use of org.codehaus.groovy.ast.ClassNode in project groovy by apache.
the class TupleConstructorASTTransformation method createConstructor.
public static void createConstructor(AbstractASTTransformation xform, ClassNode cNode, boolean includeFields, boolean includeProperties, boolean includeSuperFields, boolean includeSuperProperties, boolean callSuper, boolean force, List<String> excludes, final List<String> includes, boolean useSetters, boolean defaults, boolean allNames, SourceUnit sourceUnit, ClosureExpression pre, ClosureExpression post) {
// no processing if existing constructors found
if (!cNode.getDeclaredConstructors().isEmpty() && !force)
return;
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 preBody = new BlockStatement();
boolean superInPre = false;
if (pre != null) {
superInPre = copyStatementsWithSuperAdjustment(pre, preBody);
if (superInPre && callSuper) {
xform.addError("Error during " + MY_TYPE_NAME + " processing, can't have a super call in 'pre' " + "closure and also 'callSuper' enabled", cNode);
}
}
final BlockStatement body = new BlockStatement();
for (FieldNode fNode : superList) {
String name = fNode.getName();
if (shouldSkipUndefinedAware(name, excludes, includes, allNames))
continue;
params.add(createParam(fNode, name, defaults, xform));
boolean hasSetter = cNode.getProperty(name) != null && !fNode.isFinal();
if (callSuper) {
superParams.add(varX(name));
} else if (!superInPre) {
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))));
}
if (!preBody.isEmpty()) {
body.addStatements(preBody.getStatements());
}
for (FieldNode fNode : list) {
String name = fNode.getName();
if (shouldSkipUndefinedAware(name, excludes, includes, allNames))
continue;
Parameter nextParam = createParam(fNode, name, defaults, xform);
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)));
}
}
if (post != null) {
body.addStatement(post.getCode());
}
if (includes != null) {
Comparator<Parameter> includeComparator = new Comparator<Parameter>() {
public int compare(Parameter p1, Parameter p2) {
return new Integer(includes.indexOf(p1.getName())).compareTo(includes.indexOf(p2.getName()));
}
};
Collections.sort(params, includeComparator);
}
cNode.addConstructor(new ConstructorNode(ACC_PUBLIC, params.toArray(new Parameter[params.size()]), ClassNode.EMPTY_ARRAY, body));
if (sourceUnit != null && !body.isEmpty()) {
VariableScopeVisitor scopeVisitor = new VariableScopeVisitor(sourceUnit);
scopeVisitor.visitClass(cNode);
}
// or if there is only one Map property (for backwards compatibility)
if (!params.isEmpty() && defaults) {
ClassNode firstParam = params.get(0).getType();
if (params.size() > 1 || firstParam.equals(ClassHelper.OBJECT_TYPE)) {
String message = "The class " + cNode.getName() + " was incorrectly initialized via the map constructor with null.";
if (firstParam.equals(ClassHelper.MAP_TYPE)) {
addMapConstructors(cNode, true, message);
} else {
ClassNode candidate = HMAP_TYPE;
while (candidate != null) {
if (candidate.equals(firstParam)) {
addMapConstructors(cNode, true, message);
break;
}
candidate = candidate.getSuperClass();
}
}
}
}
}
use of org.codehaus.groovy.ast.ClassNode in project groovy by apache.
the class TupleConstructorASTTransformation method providedOrDefaultInitialValue.
private static Expression providedOrDefaultInitialValue(FieldNode fNode) {
Expression initialExp = fNode.getInitialExpression() != null ? fNode.getInitialExpression() : ConstantExpression.NULL;
final ClassNode paramType = fNode.getType();
if (ClassHelper.isPrimitiveType(paramType) && initialExp.equals(ConstantExpression.NULL)) {
initialExp = primitivesInitialValues.get(paramType.getTypeClass());
}
return initialExp;
}
use of org.codehaus.groovy.ast.ClassNode in project groovy by apache.
the class CastExpressionOptimizer method transformCastExpression.
public Expression transformCastExpression(final CastExpression cast) {
if (cast.isCoerce()) {
Expression expression = cast.getExpression();
ClassNode exprInferredType = transformer.getTypeChooser().resolveType(expression, transformer.getClassNode());
ClassNode castType = cast.getType();
if (castType.isArray() && expression instanceof ListExpression) {
ArrayExpression arrayExpression = new ArrayExpression(castType.getComponentType(), ((ListExpression) expression).getExpressions());
arrayExpression.setSourcePosition(cast);
return transformer.transform(arrayExpression);
}
if (isOptimizable(exprInferredType, castType)) {
// coerce is not needed
CastExpression trn = new CastExpression(castType, transformer.transform(expression));
trn.setSourcePosition(cast);
trn.copyNodeMetaData(cast);
return trn;
}
} else if (ClassHelper.char_TYPE.equals(cast.getType())) {
Expression expression = cast.getExpression();
if (expression instanceof ConstantExpression) {
ConstantExpression ce = (ConstantExpression) expression;
if (ClassHelper.STRING_TYPE.equals(ce.getType())) {
String val = (String) ce.getValue();
if (val != null && val.length() == 1) {
ConstantExpression result = new ConstantExpression(val.charAt(0), true);
result.setSourcePosition(cast);
return result;
}
}
}
}
return transformer.superTransform(cast);
}
use of org.codehaus.groovy.ast.ClassNode in project groovy by apache.
the class ConstructorCallTransformer method transformConstructorCall.
Expression transformConstructorCall(final ConstructorCallExpression expr) {
ConstructorNode node = (ConstructorNode) expr.getNodeMetaData(DIRECT_METHOD_CALL_TARGET);
if (node == null)
return expr;
if (node.getParameters().length == 1 && StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf(node.getParameters()[0].getType(), ClassHelper.MAP_TYPE) && node.getCode() == StaticTypeCheckingVisitor.GENERATED_EMPTY_STATEMENT) {
Expression arguments = expr.getArguments();
if (arguments instanceof TupleExpression) {
TupleExpression tupleExpression = (TupleExpression) arguments;
List<Expression> expressions = tupleExpression.getExpressions();
if (expressions.size() == 1) {
Expression expression = expressions.get(0);
if (expression instanceof MapExpression) {
MapExpression map = (MapExpression) expression;
// check that the node doesn't belong to the list of declared constructors
ClassNode declaringClass = node.getDeclaringClass();
for (ConstructorNode constructorNode : declaringClass.getDeclaredConstructors()) {
if (constructorNode == node) {
return staticCompilationTransformer.superTransform(expr);
}
}
// replace this call with a call to <init>() + appropriate setters
// for example, foo(x:1, y:2) is replaced with:
// { def tmp = new Foo(); tmp.x = 1; tmp.y = 2; return tmp }()
MapStyleConstructorCall result = new MapStyleConstructorCall(staticCompilationTransformer, declaringClass, map, expr);
return result;
}
}
}
}
return staticCompilationTransformer.superTransform(expr);
}
use of org.codehaus.groovy.ast.ClassNode in project groovy by apache.
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);
}
Aggregations