use of org.codehaus.groovy.ast.ConstructorNode in project groovy-core by groovy.
the class InitializerStrategy method createBuilderForAnnotatedMethod.
private void createBuilderForAnnotatedMethod(BuilderASTTransformation transform, MethodNode mNode, AnnotationNode anno, boolean useSetters) {
if (transform.getMemberValue(anno, "includes") != null || transform.getMemberValue(anno, "includes") != null) {
transform.addError("Error during " + BuilderASTTransformation.MY_TYPE_NAME + " processing: includes/excludes only allowed on classes", anno);
}
if (mNode instanceof ConstructorNode) {
mNode.setModifiers(ACC_PRIVATE | ACC_SYNTHETIC);
} else {
if ((mNode.getModifiers() & ACC_STATIC) == 0) {
transform.addError("Error during " + BuilderASTTransformation.MY_TYPE_NAME + " processing: method builders only allowed on static methods", anno);
}
mNode.setModifiers(ACC_PRIVATE | ACC_SYNTHETIC | ACC_STATIC);
}
ClassNode buildee = mNode.getDeclaringClass();
Parameter[] parameters = mNode.getParameters();
ClassNode builder = createInnerHelperClass(buildee, getBuilderClassName(buildee, anno), parameters.length);
List<FieldNode> convertedFields = convertParamsToFields(builder, parameters);
buildCommon(buildee, anno, convertedFields, builder);
if (mNode instanceof ConstructorNode) {
createBuildeeConstructors(transform, buildee, builder, convertedFields, false, useSetters);
} else {
createBuildeeMethods(buildee, mNode, builder, convertedFields);
}
}
use of org.codehaus.groovy.ast.ConstructorNode in project groovy-core by groovy.
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.ConstructorNode 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.ConstructorNode in project groovy-core by groovy.
the class StaticTypeCheckingVisitor method checkGroovyStyleConstructor.
/**
* Checks that a constructor style expression is valid regarding the number of arguments and the argument types.
*
* @param node the class node for which we will try to find a matching constructor
* @param arguments the constructor arguments
*/
protected MethodNode checkGroovyStyleConstructor(final ClassNode node, final ClassNode[] arguments, final ASTNode source) {
if (node.equals(ClassHelper.OBJECT_TYPE) || node.equals(ClassHelper.DYNAMIC_TYPE)) {
// in that case, we are facing a list constructor assigned to a def or object
return null;
}
List<ConstructorNode> constructors = node.getDeclaredConstructors();
if (constructors.isEmpty() && arguments.length == 0) {
return null;
}
List<MethodNode> constructorList = findMethod(node, "<init>", arguments);
if (constructorList.isEmpty()) {
if (isBeingCompiled(node) && arguments.length == 1 && LINKEDHASHMAP_CLASSNODE.equals(arguments[0])) {
// there will be a default hash map constructor added later
ConstructorNode cn = new ConstructorNode(Opcodes.ACC_PUBLIC, new Parameter[] { new Parameter(LINKEDHASHMAP_CLASSNODE, "args") }, ClassNode.EMPTY_ARRAY, EmptyStatement.INSTANCE);
return cn;
} else {
addStaticTypeError("No matching constructor found: " + node + toMethodParametersString("<init>", arguments), source);
return null;
}
} else if (constructorList.size() > 1) {
addStaticTypeError("Ambiguous constructor call " + node + toMethodParametersString("<init>", arguments), source);
return null;
}
return constructorList.get(0);
}
use of org.codehaus.groovy.ast.ConstructorNode in project groovy-core by groovy.
the class StaticTypeCheckingVisitor method addTypeCheckingInfoAnnotation.
protected void addTypeCheckingInfoAnnotation(final MethodNode node) {
// TypeChecked$TypeCheckingInfo can not be applied on constructors
if (node instanceof ConstructorNode)
return;
// if a returned inferred type is available and no @TypeCheckingInfo is on node, then add an
// annotation to the method node
ClassNode rtype = getInferredReturnType(node);
if (rtype != null && node.getAnnotations(TYPECHECKING_INFO_NODE).isEmpty()) {
AnnotationNode anno = new AnnotationNode(TYPECHECKING_INFO_NODE);
anno.setMember("version", CURRENT_SIGNATURE_PROTOCOL);
SignatureCodec codec = SignatureCodecFactory.getCodec(CURRENT_SIGNATURE_PROTOCOL_VERSION, getTransformLoader());
String genericsSignature = codec.encode(rtype);
if (genericsSignature != null) {
ConstantExpression signature = new ConstantExpression(genericsSignature);
signature.setType(STRING_TYPE);
anno.setMember("inferredType", signature);
node.addAnnotation(anno);
}
}
}
Aggregations