use of org.codehaus.groovy.ast.expr.MethodCallExpression in project groovy-core by groovy.
the class ClassCompletionVerifier method visitMethodCallExpression.
public void visitMethodCallExpression(MethodCallExpression mce) {
super.visitMethodCallExpression(mce);
Expression aexp = mce.getArguments();
if (aexp instanceof TupleExpression) {
TupleExpression arguments = (TupleExpression) aexp;
for (Expression e : arguments.getExpressions()) {
checkForInvalidDeclaration(e);
}
} else {
checkForInvalidDeclaration(aexp);
}
}
use of org.codehaus.groovy.ast.expr.MethodCallExpression in project groovy-core by groovy.
the class MarkupBuilderCodeTransformer method transformBinaryExpression.
private Expression transformBinaryExpression(final BinaryExpression bin) {
Expression left = bin.getLeftExpression();
Expression right = bin.getRightExpression();
boolean assignment = bin.getOperation().getType() == Types.ASSIGN;
if (assignment && left instanceof VariableExpression) {
VariableExpression var = (VariableExpression) left;
if (var.getAccessedVariable() instanceof DynamicVariable) {
String varName = var.getName();
if (!"modelTypes".equals(varName)) {
MethodCallExpression callGetModel = new MethodCallExpression(new VariableExpression("this"), "getModel", ArgumentListExpression.EMPTY_ARGUMENTS);
callGetModel.setImplicitThis(true);
callGetModel.setSourcePosition(left);
MethodCallExpression mce = new MethodCallExpression(callGetModel, "put", new ArgumentListExpression(new ConstantExpression(varName), right));
mce.setSourcePosition(left);
mce.setImplicitThis(false);
return transform(mce);
}
}
}
if (assignment && left instanceof VariableExpression && right instanceof ClosureExpression) {
VariableExpression var = (VariableExpression) left;
if ("modelTypes".equals(var.getName())) {
// template declaring its expected types from model directly
// modelTypes = {
// List<String> items
// ...
// }
Map<String, ClassNode> modelTypes = extractModelTypesFromClosureExpression((ClosureExpression) right);
Expression result = new EmptyExpression();
result.setSourcePosition(bin);
classNode.putNodeMetaData(MarkupTemplateEngine.MODELTYPES_ASTKEY, modelTypes);
return result;
}
}
return super.transform(bin);
}
use of org.codehaus.groovy.ast.expr.MethodCallExpression in project groovy-core by groovy.
the class BinaryExpressionTransformer method transformBinaryExpression.
Expression transformBinaryExpression(final BinaryExpression bin) {
if (bin instanceof DeclarationExpression) {
Expression optimized = transformDeclarationExpression(bin);
if (optimized != null) {
return optimized;
}
}
Object[] list = bin.getNodeMetaData(BINARY_EXP_TARGET);
Token operation = bin.getOperation();
int operationType = operation.getType();
Expression rightExpression = bin.getRightExpression();
Expression leftExpression = bin.getLeftExpression();
if (bin instanceof DeclarationExpression && leftExpression instanceof VariableExpression) {
ClassNode declarationType = ((VariableExpression) leftExpression).getOriginType();
if (rightExpression instanceof ConstantExpression) {
ClassNode unwrapper = ClassHelper.getUnwrapper(declarationType);
ClassNode wrapper = ClassHelper.getWrapper(declarationType);
if (!rightExpression.getType().equals(declarationType) && wrapper.isDerivedFrom(ClassHelper.Number_TYPE) && WideningCategories.isDoubleCategory(unwrapper)) {
ConstantExpression constant = (ConstantExpression) rightExpression;
if (constant.getValue() != null) {
return optimizeConstantInitialization(bin, operation, constant, leftExpression, declarationType);
}
}
}
}
if (operationType == Types.EQUAL && leftExpression instanceof PropertyExpression) {
MethodNode directMCT = leftExpression.getNodeMetaData(StaticTypesMarker.DIRECT_METHOD_CALL_TARGET);
if (directMCT != null) {
return transformPropertyAssignmentToSetterCall((PropertyExpression) leftExpression, rightExpression, directMCT);
}
}
if (operationType == Types.COMPARE_EQUAL || operationType == Types.COMPARE_NOT_EQUAL) {
// let's check if one of the operands is the null constant
CompareToNullExpression compareToNullExpression = null;
if (isNullConstant(leftExpression)) {
compareToNullExpression = new CompareToNullExpression(staticCompilationTransformer.transform(rightExpression), operationType == Types.COMPARE_EQUAL);
} else if (isNullConstant(rightExpression)) {
compareToNullExpression = new CompareToNullExpression(staticCompilationTransformer.transform(leftExpression), operationType == Types.COMPARE_EQUAL);
}
if (compareToNullExpression != null) {
compareToNullExpression.setSourcePosition(bin);
return compareToNullExpression;
}
} else if (operationType == Types.KEYWORD_IN) {
return convertInOperatorToTernary(bin, rightExpression, leftExpression);
}
if (list != null) {
if (operationType == Types.COMPARE_TO) {
StaticTypesTypeChooser typeChooser = staticCompilationTransformer.getTypeChooser();
ClassNode classNode = staticCompilationTransformer.getClassNode();
ClassNode leftType = typeChooser.resolveType(leftExpression, classNode);
if (leftType.implementsInterface(ClassHelper.COMPARABLE_TYPE)) {
ClassNode rightType = typeChooser.resolveType(rightExpression, classNode);
if (rightType.implementsInterface(ClassHelper.COMPARABLE_TYPE)) {
Expression left = staticCompilationTransformer.transform(leftExpression);
Expression right = staticCompilationTransformer.transform(rightExpression);
MethodCallExpression call = new MethodCallExpression(left, "compareTo", new ArgumentListExpression(right));
call.setImplicitThis(false);
call.setMethodTarget(COMPARE_TO_METHOD);
CompareIdentityExpression compareIdentity = new CompareIdentityExpression(left, right);
compareIdentity.putNodeMetaData(StaticTypesMarker.INFERRED_RETURN_TYPE, ClassHelper.boolean_TYPE);
TernaryExpression result = new TernaryExpression(// a==b
new BooleanExpression(compareIdentity), CONSTANT_ZERO, new TernaryExpression(// a==null
new BooleanExpression(new CompareToNullExpression(left, true)), CONSTANT_MINUS_ONE, new TernaryExpression(// b==null
new BooleanExpression(new CompareToNullExpression(right, true)), CONSTANT_ONE, call)));
compareIdentity.putNodeMetaData(StaticTypesMarker.INFERRED_RETURN_TYPE, ClassHelper.int_TYPE);
result.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, ClassHelper.int_TYPE);
TernaryExpression expr = (TernaryExpression) result.getFalseExpression();
expr.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, ClassHelper.int_TYPE);
expr.getFalseExpression().putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, ClassHelper.int_TYPE);
return result;
}
}
}
boolean isAssignment = StaticTypeCheckingSupport.isAssignment(operationType);
MethodCallExpression call;
MethodNode node = (MethodNode) list[0];
String name = (String) list[1];
Expression left = staticCompilationTransformer.transform(leftExpression);
Expression right = staticCompilationTransformer.transform(rightExpression);
BinaryExpression optimized = tryOptimizeCharComparison(left, right, bin);
if (optimized != null) {
optimized.removeNodeMetaData(BINARY_EXP_TARGET);
return transformBinaryExpression(optimized);
}
call = new MethodCallExpression(left, name, new ArgumentListExpression(right));
call.setImplicitThis(false);
call.setMethodTarget(node);
MethodNode adapter = StaticCompilationTransformer.BYTECODE_BINARY_ADAPTERS.get(operationType);
if (adapter != null) {
ClassExpression sba = new ClassExpression(StaticCompilationTransformer.BYTECODE_ADAPTER_CLASS);
// replace with compareEquals
call = new MethodCallExpression(sba, "compareEquals", new ArgumentListExpression(left, right));
call.setMethodTarget(adapter);
call.setImplicitThis(false);
}
if (!isAssignment)
return call;
// the method represents the operation type only, and we must add an assignment
return new BinaryExpression(left, Token.newSymbol("=", operation.getStartLine(), operation.getStartColumn()), call);
}
if (bin.getOperation().getType() == Types.EQUAL && leftExpression instanceof TupleExpression && rightExpression instanceof ListExpression) {
// multiple assignment
ListOfExpressionsExpression cle = new ListOfExpressionsExpression();
boolean isDeclaration = bin instanceof DeclarationExpression;
List<Expression> leftExpressions = ((TupleExpression) leftExpression).getExpressions();
List<Expression> rightExpressions = ((ListExpression) rightExpression).getExpressions();
Iterator<Expression> leftIt = leftExpressions.iterator();
Iterator<Expression> rightIt = rightExpressions.iterator();
if (isDeclaration) {
while (leftIt.hasNext()) {
Expression left = leftIt.next();
if (rightIt.hasNext()) {
Expression right = rightIt.next();
BinaryExpression bexp = new DeclarationExpression(left, bin.getOperation(), right);
bexp.setSourcePosition(right);
cle.addExpression(bexp);
}
}
} else {
// (next, result) = [ result, next+result ]
// -->
// def tmp1 = result
// def tmp2 = next+result
// next = tmp1
// result = tmp2
int size = rightExpressions.size();
List<Expression> tmpAssignments = new ArrayList<Expression>(size);
List<Expression> finalAssignments = new ArrayList<Expression>(size);
for (int i = 0; i < Math.min(size, leftExpressions.size()); i++) {
Expression left = leftIt.next();
Expression right = rightIt.next();
VariableExpression tmpVar = new VariableExpression("$tmpVar$" + tmpVarCounter++);
BinaryExpression bexp = new DeclarationExpression(tmpVar, bin.getOperation(), right);
bexp.setSourcePosition(right);
tmpAssignments.add(bexp);
bexp = new BinaryExpression(left, bin.getOperation(), new VariableExpression(tmpVar));
bexp.setSourcePosition(left);
finalAssignments.add(bexp);
}
for (Expression tmpAssignment : tmpAssignments) {
cle.addExpression(tmpAssignment);
}
for (Expression finalAssignment : finalAssignments) {
cle.addExpression(finalAssignment);
}
}
return staticCompilationTransformer.transform(cle);
}
return staticCompilationTransformer.superTransform(bin);
}
use of org.codehaus.groovy.ast.expr.MethodCallExpression in project groovy-core by groovy.
the class DelegateASTTransformation method addDelegateMethod.
private void addDelegateMethod(AnnotationNode node, FieldNode fieldNode, ClassNode owner, List<MethodNode> ownMethods, MethodNode candidate, boolean includeDeprecated, List<String> includes, List<String> excludes, List<ClassNode> includeTypes, List<ClassNode> excludeTypes) {
if (!candidate.isPublic() || candidate.isStatic() || 0 != (candidate.getModifiers() & ACC_SYNTHETIC))
return;
if (!candidate.getAnnotations(DEPRECATED_TYPE).isEmpty() && !includeDeprecated)
return;
if (shouldSkip(candidate.getName(), excludes, includes))
return;
Map<String, ClassNode> genericsSpec = createGenericsSpec(fieldNode.getDeclaringClass());
genericsSpec = addMethodGenerics(candidate, genericsSpec);
extractSuperClassGenerics(fieldNode.getType(), candidate.getDeclaringClass(), genericsSpec);
if (!excludeTypes.isEmpty() || !includeTypes.isEmpty()) {
MethodNode correctedMethodNode = correctToGenericsSpec(genericsSpec, candidate);
boolean checkReturn = fieldNode.getType().getMethods().contains(candidate);
if (shouldSkipOnDescriptor(checkReturn, genericsSpec, correctedMethodNode, excludeTypes, includeTypes))
return;
}
// ignore methods from GroovyObject
for (MethodNode mn : GROOVYOBJECT_TYPE.getMethods()) {
if (mn.getTypeDescriptor().equals(candidate.getTypeDescriptor())) {
return;
}
}
// ignore methods already in owner
for (MethodNode mn : owner.getMethods()) {
if (mn.getTypeDescriptor().equals(candidate.getTypeDescriptor())) {
return;
}
}
// give precedence to methods of self (but not abstract or static superclass methods)
// also allows abstract or static self methods to be selected for overriding but they are ignored later
MethodNode existingNode = null;
for (MethodNode mn : ownMethods) {
if (mn.getTypeDescriptor().equals(candidate.getTypeDescriptor()) && !mn.isAbstract() && !mn.isStatic()) {
existingNode = mn;
break;
}
}
if (existingNode == null || existingNode.getCode() == null) {
final ArgumentListExpression args = new ArgumentListExpression();
final Parameter[] params = candidate.getParameters();
final Parameter[] newParams = new Parameter[params.length];
List<String> currentMethodGenPlaceholders = genericPlaceholderNames(candidate);
for (int i = 0; i < newParams.length; i++) {
ClassNode newParamType = correctToGenericsSpecRecurse(genericsSpec, params[i].getType(), currentMethodGenPlaceholders);
Parameter newParam = new Parameter(newParamType, getParamName(params, i, fieldNode.getName()));
newParam.setInitialExpression(params[i].getInitialExpression());
if (memberHasValue(node, MEMBER_PARAMETER_ANNOTATIONS, true)) {
newParam.addAnnotations(copyAnnotatedNodeAnnotations(params[i], MY_TYPE_NAME));
}
newParams[i] = newParam;
args.addExpression(varX(newParam));
}
boolean alsoLazy = !fieldNode.getAnnotations(LAZY_TYPE).isEmpty();
// addMethod will ignore attempts to override abstract or static methods with same signature on self
MethodCallExpression mce = callX(alsoLazy ? propX(varX("this"), fieldNode.getName().substring(1)) : varX(fieldNode.getName(), correctToGenericsSpecRecurse(genericsSpec, fieldNode.getType())), candidate.getName(), args);
mce.setSourcePosition(fieldNode);
ClassNode returnType = correctToGenericsSpecRecurse(genericsSpec, candidate.getReturnType(), currentMethodGenPlaceholders);
MethodNode newMethod = owner.addMethod(candidate.getName(), candidate.getModifiers() & (~ACC_ABSTRACT) & (~ACC_NATIVE), returnType, newParams, candidate.getExceptions(), stmt(mce));
newMethod.setGenericsTypes(candidate.getGenericsTypes());
if (memberHasValue(node, MEMBER_METHOD_ANNOTATIONS, true)) {
newMethod.addAnnotations(copyAnnotatedNodeAnnotations(candidate, MY_TYPE_NAME));
}
}
}
use of org.codehaus.groovy.ast.expr.MethodCallExpression in project groovy-core by groovy.
the class LazyASTTransformation method createSoftGetter.
private static void createSoftGetter(FieldNode fieldNode, Expression initExpr, ClassNode type) {
final BlockStatement body = new BlockStatement();
final Expression fieldExpr = varX(fieldNode);
final Expression resExpr = varX("res", type);
final MethodCallExpression callExpression = callX(fieldExpr, "get");
callExpression.setSafe(true);
body.addStatement(declS(resExpr, callExpression));
final Statement mainIf = ifElseS(notNullX(resExpr), stmt(resExpr), block(assignS(resExpr, initExpr), assignS(fieldExpr, ctorX(SOFT_REF, resExpr)), stmt(resExpr)));
if (fieldNode.isVolatile()) {
body.addStatement(ifElseS(notNullX(resExpr), stmt(resExpr), new SynchronizedStatement(syncTarget(fieldNode), block(assignS(resExpr, callExpression), mainIf))));
} else {
body.addStatement(mainIf);
}
addMethod(fieldNode, body, type);
}
Aggregations