use of org.codehaus.groovy.ast.FieldNode in project groovy by apache.
the class AntlrParserPlugin method fieldDef.
protected void fieldDef(AST fieldDef) {
List<AnnotationNode> annotations = new ArrayList<AnnotationNode>();
AST node = fieldDef.getFirstChild();
int modifiers = 0;
if (isType(MODIFIERS, node)) {
modifiers = modifiers(node, annotations, modifiers);
node = node.getNextSibling();
}
if (classNode.isInterface()) {
modifiers |= Opcodes.ACC_STATIC | Opcodes.ACC_FINAL;
if ((modifiers & (Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED)) == 0) {
modifiers |= Opcodes.ACC_PUBLIC;
}
}
ClassNode type = null;
if (isType(TYPE, node)) {
type = makeTypeWithArguments(node);
node = node.getNextSibling();
}
String name = identifier(node);
node = node.getNextSibling();
Expression initialValue = null;
if (node != null) {
assertNodeType(ASSIGN, node);
initialValue = expression(node.getFirstChild());
}
if (classNode.isInterface() && initialValue == null && type != null) {
initialValue = getDefaultValueForPrimitive(type);
}
FieldNode fieldNode = new FieldNode(name, modifiers, type, classNode, initialValue);
fieldNode.addAnnotations(annotations);
configureAST(fieldNode, fieldDef);
if (!hasVisibility(modifiers)) {
// let's set the modifiers on the field
int fieldModifiers = 0;
int flags = Opcodes.ACC_STATIC | Opcodes.ACC_TRANSIENT | Opcodes.ACC_VOLATILE | Opcodes.ACC_FINAL;
if (!hasVisibility(modifiers)) {
modifiers |= Opcodes.ACC_PUBLIC;
fieldModifiers |= Opcodes.ACC_PRIVATE;
}
// let's pass along any other modifiers we need
fieldModifiers |= (modifiers & flags);
fieldNode.setModifiers(fieldModifiers);
fieldNode.setSynthetic(true);
// in the case that there is already a field, we would
// like to use that field, instead of the default field
// for the property
FieldNode storedNode = classNode.getDeclaredField(fieldNode.getName());
if (storedNode != null && !classNode.hasProperty(name)) {
fieldNode = storedNode;
// we remove it here, because addProperty will add it
// again and we want to avoid it showing up multiple
// times in the fields list.
classNode.getFields().remove(storedNode);
}
PropertyNode propertyNode = new PropertyNode(fieldNode, modifiers, null, null);
configureAST(propertyNode, fieldDef);
classNode.addProperty(propertyNode);
} else {
fieldNode.setModifiers(modifiers);
// if there is a property of that name, then a field of that
// name already exists, which means this new field here should
// be used instead of the field the property originally has.
PropertyNode pn = classNode.getProperty(name);
if (pn != null && pn.getField().isSynthetic()) {
classNode.getFields().remove(pn.getField());
pn.setField(fieldNode);
}
classNode.addField(fieldNode);
}
}
use of org.codehaus.groovy.ast.FieldNode in project groovy by apache.
the class AntlrParserPlugin method enumConstantDef.
protected void enumConstantDef(AST node) {
enumConstantBeingDef = true;
assertNodeType(ENUM_CONSTANT_DEF, node);
List<AnnotationNode> annotations = new ArrayList<AnnotationNode>();
AST element = node.getFirstChild();
if (isType(ANNOTATIONS, element)) {
processAnnotations(annotations, element);
element = element.getNextSibling();
}
String identifier = identifier(element);
Expression init = null;
element = element.getNextSibling();
if (element != null) {
init = expression(element);
ClassNode innerClass;
if (element.getNextSibling() == null) {
innerClass = getAnonymousInnerClassNode(init);
if (innerClass != null) {
init = null;
}
} else {
element = element.getNextSibling();
Expression next = expression(element);
innerClass = getAnonymousInnerClassNode(next);
}
if (innerClass != null) {
// we have to handle an enum constant with a class overriding
// a method in which case we need to configure the inner class
innerClass.setSuperClass(classNode.getPlainNodeReference());
innerClass.setModifiers(classNode.getModifiers() | Opcodes.ACC_FINAL);
// we use a ClassExpression for transportation to EnumVisitor
Expression inner = new ClassExpression(innerClass);
if (init == null) {
ListExpression le = new ListExpression();
le.addExpression(inner);
init = le;
} else {
if (init instanceof ListExpression) {
((ListExpression) init).addExpression(inner);
} else {
ListExpression le = new ListExpression();
le.addExpression(init);
le.addExpression(inner);
init = le;
}
}
// and remove the final modifier from classNode to allow the sub class
classNode.setModifiers(classNode.getModifiers() & ~Opcodes.ACC_FINAL);
} else if (isType(ELIST, element)) {
if (init instanceof ListExpression && !((ListExpression) init).isWrapped()) {
ListExpression le = new ListExpression();
le.addExpression(init);
init = le;
}
}
}
FieldNode enumField = EnumHelper.addEnumConstant(classNode, identifier, init);
enumField.addAnnotations(annotations);
configureAST(enumField, node);
enumConstantBeingDef = false;
}
use of org.codehaus.groovy.ast.FieldNode 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.FieldNode in project groovy by apache.
the class ImmutableASTTransformation method adjustPropertyForImmutability.
private static void adjustPropertyForImmutability(PropertyNode pNode, List<PropertyNode> newNodes) {
final FieldNode fNode = pNode.getField();
fNode.setModifiers((pNode.getModifiers() & (~ACC_PUBLIC)) | ACC_FINAL | ACC_PRIVATE);
adjustPropertyNode(pNode, createGetterBody(fNode));
newNodes.add(pNode);
}
use of org.codehaus.groovy.ast.FieldNode in project groovy by apache.
the class ImmutableASTTransformation method createConstructorStatement.
private Statement createConstructorStatement(ClassNode cNode, PropertyNode pNode, List<String> knownImmutableClasses, List<String> knownImmutables) {
FieldNode fNode = pNode.getField();
final ClassNode fieldType = fNode.getType();
Statement statement = null;
if (fieldType.isArray() || isOrImplements(fieldType, CLONEABLE_TYPE)) {
statement = createConstructorStatementArrayOrCloneable(fNode);
} else if (isKnownImmutableClass(fieldType, knownImmutableClasses) || isKnownImmutable(pNode.getName(), knownImmutables)) {
statement = createConstructorStatementDefault(fNode);
} else if (fieldType.isDerivedFrom(DATE_TYPE)) {
statement = createConstructorStatementDate(fNode);
} else if (isOrImplements(fieldType, COLLECTION_TYPE) || fieldType.isDerivedFrom(COLLECTION_TYPE) || isOrImplements(fieldType, MAP_TYPE) || fieldType.isDerivedFrom(MAP_TYPE)) {
statement = createConstructorStatementCollection(fNode);
} else if (fieldType.isResolved()) {
addError(createErrorMessage(cNode.getName(), fNode.getName(), fieldType.getName(), "compiling"), fNode);
statement = EmptyStatement.INSTANCE;
} else {
statement = createConstructorStatementGuarded(cNode, fNode);
}
return statement;
}
Aggregations