use of org.codehaus.groovy.ast.expr.Expression in project groovy-core by groovy.
the class MethodCallExpressionTransformer method transformMethodCallExpression.
Expression transformMethodCallExpression(final MethodCallExpression expr) {
Expression trn = tryTransformIsToCompareIdentity(expr);
if (trn != null) {
return trn;
}
ClassNode superCallReceiver = expr.getNodeMetaData(StaticTypesMarker.SUPER_MOP_METHOD_REQUIRED);
if (superCallReceiver != null) {
return transformMethodCallExpression(transformToMopSuperCall(superCallReceiver, expr));
}
Expression objectExpression = expr.getObjectExpression();
ClassNode type = staticCompilationTransformer.getTypeChooser().resolveType(objectExpression, staticCompilationTransformer.getClassNode());
if (isCallOnClosure(expr)) {
FieldNode field = staticCompilationTransformer.getClassNode().getField(expr.getMethodAsString());
if (field != null) {
VariableExpression vexp = new VariableExpression(field);
MethodCallExpression result = new MethodCallExpression(vexp, "call", staticCompilationTransformer.transform(expr.getArguments()));
result.setImplicitThis(false);
result.setSourcePosition(expr);
result.setSafe(expr.isSafe());
result.setSpreadSafe(expr.isSpreadSafe());
result.setMethodTarget(StaticTypeCheckingVisitor.CLOSURE_CALL_VARGS);
return result;
}
}
if (type != null && type.isArray()) {
String method = expr.getMethodAsString();
ClassNode componentType = type.getComponentType();
if ("getAt".equals(method)) {
Expression arguments = expr.getArguments();
if (arguments instanceof TupleExpression) {
List<Expression> argList = ((TupleExpression) arguments).getExpressions();
if (argList.size() == 1) {
Expression indexExpr = argList.get(0);
ClassNode argType = staticCompilationTransformer.getTypeChooser().resolveType(indexExpr, staticCompilationTransformer.getClassNode());
ClassNode indexType = ClassHelper.getWrapper(argType);
if (componentType.isEnum() && ClassHelper.Number_TYPE == indexType) {
// workaround for generated code in enums which use .next() returning a Number
indexType = ClassHelper.Integer_TYPE;
}
if (argType != null && ClassHelper.Integer_TYPE == indexType) {
BinaryExpression binaryExpression = new BinaryExpression(objectExpression, Token.newSymbol("[", indexExpr.getLineNumber(), indexExpr.getColumnNumber()), indexExpr);
binaryExpression.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, componentType);
return staticCompilationTransformer.transform(binaryExpression);
}
}
}
} else if ("putAt".equals(method)) {
Expression arguments = expr.getArguments();
if (arguments instanceof TupleExpression) {
List<Expression> argList = ((TupleExpression) arguments).getExpressions();
if (argList.size() == 2) {
Expression indexExpr = argList.get(0);
Expression objExpr = argList.get(1);
ClassNode argType = staticCompilationTransformer.getTypeChooser().resolveType(indexExpr, staticCompilationTransformer.getClassNode());
if (argType != null && ClassHelper.Integer_TYPE == ClassHelper.getWrapper(argType)) {
BinaryExpression arrayGet = new BinaryExpression(objectExpression, Token.newSymbol("[", indexExpr.getLineNumber(), indexExpr.getColumnNumber()), indexExpr);
arrayGet.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, componentType);
BinaryExpression assignment = new BinaryExpression(arrayGet, Token.newSymbol("=", objExpr.getLineNumber(), objExpr.getColumnNumber()), objExpr);
return staticCompilationTransformer.transform(assignment);
}
}
}
}
}
return staticCompilationTransformer.superTransform(expr);
}
use of org.codehaus.groovy.ast.expr.Expression in project groovy-core by groovy.
the class MethodCallExpressionTransformer method tryTransformIsToCompareIdentity.
/**
* Identifies a method call expression on {@link DefaultGroovyMethods#is(Object, Object)} and if recognized, transforms it into a {@link CompareIdentityExpression}.
* @param call a method call to be transformed
* @return null if the method call is not DGM#is, or {@link CompareIdentityExpression}
*/
private static Expression tryTransformIsToCompareIdentity(MethodCallExpression call) {
MethodNode methodTarget = call.getMethodTarget();
if (methodTarget instanceof ExtensionMethodNode && "is".equals(methodTarget.getName()) && methodTarget.getParameters().length == 1) {
methodTarget = ((ExtensionMethodNode) methodTarget).getExtensionMethodNode();
ClassNode owner = methodTarget.getDeclaringClass();
if (DGM_CLASSNODE.equals(owner)) {
Expression args = call.getArguments();
if (args instanceof ArgumentListExpression) {
ArgumentListExpression arguments = (ArgumentListExpression) args;
List<Expression> exprs = arguments.getExpressions();
if (exprs.size() == 1) {
CompareIdentityExpression cid = new CompareIdentityExpression(call.getObjectExpression(), exprs.get(0));
cid.setSourcePosition(call);
return cid;
}
}
}
}
return null;
}
use of org.codehaus.groovy.ast.expr.Expression in project groovy-core by groovy.
the class TupleConstructorASTTransformation method createConstructor.
public static void createConstructor(ClassNode cNode, boolean includeFields, boolean includeProperties, boolean includeSuperFields, boolean includeSuperProperties, boolean callSuper, boolean force, List<String> excludes, List<String> includes, boolean useSetters) {
// no processing if existing constructors found
List<ConstructorNode> constructors = cNode.getDeclaredConstructors();
if (constructors.size() > 1 && !force)
return;
boolean foundEmpty = constructors.size() == 1 && constructors.get(0).getFirstStatement() == null;
if (constructors.size() == 1 && !foundEmpty && !force)
return;
// HACK: JavaStubGenerator could have snuck in a constructor we don't want
if (foundEmpty)
constructors.remove(0);
List<FieldNode> superList = new ArrayList<FieldNode>();
if (includeSuperProperties) {
superList.addAll(getSuperPropertyFields(cNode.getSuperClass()));
}
if (includeSuperFields) {
superList.addAll(getSuperNonPropertyFields(cNode.getSuperClass()));
}
List<FieldNode> list = new ArrayList<FieldNode>();
if (includeProperties) {
list.addAll(getInstancePropertyFields(cNode));
}
if (includeFields) {
list.addAll(getInstanceNonPropertyFields(cNode));
}
final List<Parameter> params = new ArrayList<Parameter>();
final List<Expression> superParams = new ArrayList<Expression>();
final BlockStatement body = new BlockStatement();
for (FieldNode fNode : superList) {
String name = fNode.getName();
if (shouldSkip(name, excludes, includes))
continue;
params.add(createParam(fNode, name));
boolean hasSetter = cNode.getProperty(name) != null && !fNode.isFinal();
if (callSuper) {
superParams.add(varX(name));
} else {
if (useSetters && hasSetter) {
body.addStatement(stmt(callThisX(getSetterName(name), varX(name))));
} else {
body.addStatement(assignS(propX(varX("this"), name), varX(name)));
}
}
}
if (callSuper) {
body.addStatement(stmt(ctorX(ClassNode.SUPER, args(superParams))));
}
for (FieldNode fNode : list) {
String name = fNode.getName();
if (shouldSkip(name, excludes, includes))
continue;
Parameter nextParam = createParam(fNode, name);
params.add(nextParam);
boolean hasSetter = cNode.getProperty(name) != null && !fNode.isFinal();
if (useSetters && hasSetter) {
body.addStatement(stmt(callThisX(getSetterName(name), varX(nextParam))));
} else {
body.addStatement(assignS(propX(varX("this"), name), varX(nextParam)));
}
}
cNode.addConstructor(new ConstructorNode(ACC_PUBLIC, params.toArray(new Parameter[params.size()]), ClassNode.EMPTY_ARRAY, body));
// or if there is only one Map property (for backwards compatibility)
if (params.size() > 0) {
ClassNode firstParam = params.get(0).getType();
if (params.size() > 1 || firstParam.equals(ClassHelper.OBJECT_TYPE)) {
if (firstParam.equals(ClassHelper.MAP_TYPE)) {
addMapConstructors(cNode, true, "The class " + cNode.getName() + " was incorrectly initialized via the map constructor with null.");
} else {
ClassNode candidate = HMAP_TYPE;
while (candidate != null) {
if (candidate.equals(firstParam)) {
addMapConstructors(cNode, true, "The class " + cNode.getName() + " was incorrectly initialized via the map constructor with null.");
break;
}
candidate = candidate.getSuperClass();
}
}
}
}
}
use of org.codehaus.groovy.ast.expr.Expression in project groovy-core by groovy.
the class JavaStubGenerator method printField.
private void printField(PrintWriter out, FieldNode fieldNode, boolean isInterface) {
if ((fieldNode.getModifiers() & Opcodes.ACC_PRIVATE) != 0)
return;
printAnnotations(out, fieldNode);
if (!isInterface) {
printModifiers(out, fieldNode.getModifiers());
}
ClassNode type = fieldNode.getType();
printType(out, type);
out.print(" ");
out.print(fieldNode.getName());
if (isInterface || (fieldNode.getModifiers() & Opcodes.ACC_FINAL) != 0) {
out.print(" = ");
Expression valueExpr = fieldNode.getInitialValueExpression();
if (valueExpr instanceof ConstantExpression) {
valueExpr = Verifier.transformToPrimitiveConstantIfPossible((ConstantExpression) valueExpr);
}
if (valueExpr instanceof ConstantExpression && fieldNode.isStatic() && fieldNode.isFinal() && ClassHelper.isStaticConstantInitializerType(valueExpr.getType()) && valueExpr.getType().equals(fieldNode.getType())) {
// GROOVY-5150 : Initialize value with a dummy constant so that Java cross compiles correctly
if (ClassHelper.STRING_TYPE.equals(valueExpr.getType())) {
out.print(formatString(valueExpr.getText()));
} else if (ClassHelper.char_TYPE.equals(valueExpr.getType())) {
out.print("'" + valueExpr.getText() + "'");
} else {
ClassNode constantType = valueExpr.getType();
out.print('(');
printType(out, type);
out.print(") ");
out.print(valueExpr.getText());
if (ClassHelper.Long_TYPE.equals(ClassHelper.getWrapper(constantType)))
out.print('L');
}
} else if (ClassHelper.isPrimitiveType(type)) {
String val = type == ClassHelper.boolean_TYPE ? "false" : "0";
out.print("new " + ClassHelper.getWrapper(type) + "((" + type + ")" + val + ")");
} else {
out.print("null");
}
}
out.println(";");
}
use of org.codehaus.groovy.ast.expr.Expression in project groovy-core by groovy.
the class JavaStubGenerator method printClassContents.
private void printClassContents(PrintWriter out, ClassNode classNode) throws FileNotFoundException {
if (classNode instanceof InnerClassNode && ((InnerClassNode) classNode).isAnonymous()) {
// if it is an anonymous inner class, don't generate the stub code for it.
return;
}
try {
Verifier verifier = new Verifier() {
@Override
public void visitClass(final ClassNode node) {
List<Statement> savedStatements = new ArrayList<Statement>(node.getObjectInitializerStatements());
super.visitClass(node);
node.getObjectInitializerStatements().addAll(savedStatements);
}
@Override
protected FinalVariableAnalyzer.VariableNotFinalCallback getFinalVariablesCallback() {
return null;
}
public void addCovariantMethods(ClassNode cn) {
}
protected void addTimeStamp(ClassNode node) {
}
protected void addInitialization(ClassNode node) {
}
protected void addPropertyMethod(MethodNode method) {
doAddMethod(method);
}
protected void addReturnIfNeeded(MethodNode node) {
}
protected void addMethod(ClassNode node, boolean shouldBeSynthetic, String name, int modifiers, ClassNode returnType, Parameter[] parameters, ClassNode[] exceptions, Statement code) {
doAddMethod(new MethodNode(name, modifiers, returnType, parameters, exceptions, code));
}
protected void addConstructor(Parameter[] newParams, ConstructorNode ctor, Statement code, ClassNode node) {
if (code instanceof ExpressionStatement) {
//GROOVY-4508
Statement temp = code;
code = new BlockStatement();
((BlockStatement) code).addStatement(temp);
}
ConstructorNode ctrNode = new ConstructorNode(ctor.getModifiers(), newParams, ctor.getExceptions(), code);
ctrNode.setDeclaringClass(node);
constructors.add(ctrNode);
}
protected void addDefaultParameters(DefaultArgsAction action, MethodNode method) {
final Parameter[] parameters = method.getParameters();
final Expression[] saved = new Expression[parameters.length];
for (int i = 0; i < parameters.length; i++) {
if (parameters[i].hasInitialExpression())
saved[i] = parameters[i].getInitialExpression();
}
super.addDefaultParameters(action, method);
for (int i = 0; i < parameters.length; i++) {
if (saved[i] != null)
parameters[i].setInitialExpression(saved[i]);
}
}
private void doAddMethod(MethodNode method) {
String sig = method.getTypeDescriptor();
if (propertyMethodsWithSigs.containsKey(sig))
return;
propertyMethods.add(method);
propertyMethodsWithSigs.put(sig, method);
}
@Override
protected void addDefaultConstructor(ClassNode node) {
// not required for stub generation
}
};
verifier.visitClass(classNode);
currentModule = classNode.getModule();
boolean isInterface = isInterfaceOrTrait(classNode);
boolean isEnum = (classNode.getModifiers() & Opcodes.ACC_ENUM) != 0;
boolean isAnnotationDefinition = classNode.isAnnotationDefinition();
printAnnotations(out, classNode);
printModifiers(out, classNode.getModifiers() & ~(isInterface ? Opcodes.ACC_ABSTRACT : 0) & ~(isEnum ? Opcodes.ACC_FINAL : 0));
if (isInterface) {
if (isAnnotationDefinition) {
out.print("@");
}
out.print("interface ");
} else if (isEnum) {
out.print("enum ");
} else {
out.print("class ");
}
String className = classNode.getNameWithoutPackage();
if (classNode instanceof InnerClassNode)
className = className.substring(className.lastIndexOf("$") + 1);
out.println(className);
printGenericsBounds(out, classNode, true);
ClassNode superClass = classNode.getUnresolvedSuperClass(false);
if (!isInterface && !isEnum) {
out.print(" extends ");
printType(out, superClass);
}
ClassNode[] interfaces = classNode.getInterfaces();
if (interfaces != null && interfaces.length > 0 && !isAnnotationDefinition) {
if (isInterface) {
out.println(" extends");
} else {
out.println(" implements");
}
for (int i = 0; i < interfaces.length - 1; ++i) {
out.print(" ");
printType(out, interfaces[i]);
out.print(",");
}
out.print(" ");
printType(out, interfaces[interfaces.length - 1]);
}
out.println(" {");
printFields(out, classNode);
printMethods(out, classNode, isEnum);
for (Iterator<InnerClassNode> inner = classNode.getInnerClasses(); inner.hasNext(); ) {
// GROOVY-4004: Clear the methods from the outer class so that they don't get duplicated in inner ones
propertyMethods.clear();
propertyMethodsWithSigs.clear();
constructors.clear();
printClassContents(out, inner.next());
}
out.println("}");
} finally {
propertyMethods.clear();
propertyMethodsWithSigs.clear();
constructors.clear();
currentModule = null;
}
}
Aggregations