use of org.codehaus.groovy.ast.FieldNode in project groovy-core by groovy.
the class ExternalizeVerifierASTTransformation method visit.
public void visit(ASTNode[] nodes, SourceUnit source) {
init(nodes, source);
AnnotatedNode parent = (AnnotatedNode) nodes[1];
AnnotationNode anno = (AnnotationNode) nodes[0];
if (!MY_TYPE.equals(anno.getClassNode()))
return;
if (parent instanceof ClassNode) {
ClassNode cNode = (ClassNode) parent;
if (!hasNoargConstructor(cNode)) {
addError(MY_TYPE_NAME + ": An Externalizable class requires a no-arg constructor but none found", cNode);
}
if (!implementsExternalizable(cNode)) {
addError(MY_TYPE_NAME + ": An Externalizable class must implement the Externalizable interface", cNode);
}
boolean includeFields = memberHasValue(anno, "includeFields", true);
boolean checkPropertyTypes = memberHasValue(anno, "checkPropertyTypes", true);
List<String> excludes = getMemberList(anno, "excludes");
List<FieldNode> list = getInstancePropertyFields(cNode);
if (includeFields) {
list.addAll(getInstanceNonPropertyFields(cNode));
}
checkProps(list, excludes, checkPropertyTypes);
}
}
use of org.codehaus.groovy.ast.FieldNode in project groovy-core by groovy.
the class FieldASTTransformation method visit.
public void visit(ASTNode[] nodes, SourceUnit source) {
sourceUnit = source;
if (nodes.length != 2 || !(nodes[0] instanceof AnnotationNode) || !(nodes[1] instanceof AnnotatedNode)) {
throw new GroovyBugError("Internal error: expecting [AnnotationNode, AnnotatedNode] but got: " + Arrays.asList(nodes));
}
AnnotatedNode parent = (AnnotatedNode) nodes[1];
AnnotationNode node = (AnnotationNode) nodes[0];
if (!MY_TYPE.equals(node.getClassNode()))
return;
if (parent instanceof DeclarationExpression) {
DeclarationExpression de = (DeclarationExpression) parent;
ClassNode cNode = de.getDeclaringClass();
if (!cNode.isScript()) {
addError("Annotation " + MY_TYPE_NAME + " can only be used within a Script.", parent);
return;
}
candidate = de;
// GROOVY-4548: temp fix to stop CCE until proper support is added
if (de.isMultipleAssignmentDeclaration()) {
addError("Annotation " + MY_TYPE_NAME + " not supported with multiple assignment notation.", parent);
return;
}
VariableExpression ve = de.getVariableExpression();
variableName = ve.getName();
// set owner null here, it will be updated by addField
fieldNode = new FieldNode(variableName, ve.getModifiers(), ve.getType(), null, de.getRightExpression());
fieldNode.setSourcePosition(de);
cNode.addField(fieldNode);
// GROOVY-4833 : annotations that are not Groovy transforms should be transferred to the generated field
// GROOVY-6112 : also copy acceptable Groovy transforms
final List<AnnotationNode> annotations = de.getAnnotations();
for (AnnotationNode annotation : annotations) {
// GROOVY-6337 HACK: in case newly created field is @Lazy
if (annotation.getClassNode().equals(LAZY_TYPE)) {
LazyASTTransformation.visitField(annotation, fieldNode);
}
final ClassNode annotationClassNode = annotation.getClassNode();
if (notTransform(annotationClassNode) || acceptableTransform(annotation)) {
fieldNode.addAnnotation(annotation);
}
}
super.visitClass(cNode);
// GROOVY-5207 So that Closures can see newly added fields
// (not super efficient for a very large class with many @Fields but we chose simplicity
// and understandability of this solution over more complex but efficient alternatives)
VariableScopeVisitor scopeVisitor = new VariableScopeVisitor(source);
scopeVisitor.visitClass(cNode);
}
}
use of org.codehaus.groovy.ast.FieldNode in project groovy-core by groovy.
the class ImmutableASTTransformation method addProperty.
private void addProperty(ClassNode cNode, PropertyNode pNode) {
final FieldNode fn = pNode.getField();
cNode.getFields().remove(fn);
cNode.addProperty(pNode.getName(), pNode.getModifiers() | ACC_FINAL, pNode.getType(), pNode.getInitialExpression(), pNode.getGetterBlock(), pNode.getSetterBlock());
final FieldNode newfn = cNode.getField(fn.getName());
cNode.getFields().remove(newfn);
cNode.addField(fn);
}
use of org.codehaus.groovy.ast.FieldNode in project groovy-core by groovy.
the class MemoizedASTTransformation method visit.
public void visit(ASTNode[] nodes, final SourceUnit source) {
init(nodes, source);
AnnotationNode annotationNode = (AnnotationNode) nodes[0];
AnnotatedNode annotatedNode = (AnnotatedNode) nodes[1];
if (MY_TYPE.equals(annotationNode.getClassNode()) && annotatedNode instanceof MethodNode) {
MethodNode methodNode = (MethodNode) annotatedNode;
if (methodNode.isAbstract()) {
addError("Annotation " + MY_TYPE_NAME + " cannot be used for abstract methods.", methodNode);
return;
}
if (methodNode.isVoidMethod()) {
addError("Annotation " + MY_TYPE_NAME + " cannot be used for void methods.", methodNode);
return;
}
ClassNode ownerClassNode = methodNode.getDeclaringClass();
MethodNode delegatingMethod = buildDelegatingMethod(methodNode, ownerClassNode);
ownerClassNode.addMethod(delegatingMethod);
int modifiers = FieldNode.ACC_PRIVATE | FieldNode.ACC_FINAL;
if (methodNode.isStatic()) {
modifiers = modifiers | FieldNode.ACC_STATIC;
}
int protectedCacheSize = getMemberIntValue(annotationNode, PROTECTED_CACHE_SIZE_NAME);
int maxCacheSize = getMemberIntValue(annotationNode, MAX_CACHE_SIZE_NAME);
MethodCallExpression memoizeClosureCallExpression = buildMemoizeClosureCallExpression(delegatingMethod, protectedCacheSize, maxCacheSize);
String memoizedClosureFieldName = buildUniqueName(ownerClassNode, CLOSURE_LABEL, methodNode);
FieldNode memoizedClosureField = new FieldNode(memoizedClosureFieldName, modifiers, newClass(ClassHelper.CLOSURE_TYPE), null, memoizeClosureCallExpression);
ownerClassNode.addField(memoizedClosureField);
BlockStatement newCode = new BlockStatement();
MethodCallExpression closureCallExpression = callX(fieldX(memoizedClosureField), CLOSURE_CALL_METHOD_NAME, args(methodNode.getParameters()));
closureCallExpression.setImplicitThis(false);
newCode.addStatement(returnS(closureCallExpression));
methodNode.setCode(newCode);
VariableScopeVisitor visitor = new VariableScopeVisitor(source);
visitor.visitClass(ownerClassNode);
}
}
use of org.codehaus.groovy.ast.FieldNode in project groovy-core by groovy.
the class DelegateASTTransformation method visit.
public void visit(ASTNode[] nodes, SourceUnit source) {
init(nodes, source);
AnnotatedNode parent = (AnnotatedNode) nodes[1];
AnnotationNode node = (AnnotationNode) nodes[0];
if (parent instanceof FieldNode) {
FieldNode fieldNode = (FieldNode) parent;
final ClassNode type = fieldNode.getType();
final ClassNode owner = fieldNode.getOwner();
if (type.equals(ClassHelper.OBJECT_TYPE) || type.equals(GROOVYOBJECT_TYPE)) {
addError(MY_TYPE_NAME + " field '" + fieldNode.getName() + "' has an inappropriate type: " + type.getName() + ". Please add an explicit type but not java.lang.Object or groovy.lang.GroovyObject.", parent);
return;
}
if (type.equals(owner)) {
addError(MY_TYPE_NAME + " field '" + fieldNode.getName() + "' has an inappropriate type: " + type.getName() + ". Delegation to own type not supported. Please use a different type.", parent);
return;
}
final List<MethodNode> fieldMethods = getAllMethods(type);
for (ClassNode next : type.getAllInterfaces()) {
fieldMethods.addAll(getAllMethods(next));
}
final boolean skipInterfaces = memberHasValue(node, MEMBER_INTERFACES, false);
final boolean includeDeprecated = memberHasValue(node, MEMBER_DEPRECATED, true) || (type.isInterface() && !skipInterfaces);
List<String> excludes = getMemberList(node, MEMBER_EXCLUDES);
List<String> includes = getMemberList(node, MEMBER_INCLUDES);
List<ClassNode> excludeTypes = getClassList(node, MEMBER_EXCLUDE_TYPES);
List<ClassNode> includeTypes = getClassList(node, MEMBER_INCLUDE_TYPES);
checkIncludeExclude(node, excludes, includes, excludeTypes, includeTypes, MY_TYPE_NAME);
final List<MethodNode> ownerMethods = getAllMethods(owner);
for (MethodNode mn : fieldMethods) {
addDelegateMethod(node, fieldNode, owner, ownerMethods, mn, includeDeprecated, includes, excludes, includeTypes, excludeTypes);
}
for (PropertyNode prop : getAllProperties(type)) {
if (prop.isStatic() || !prop.isPublic())
continue;
String name = prop.getName();
addGetterIfNeeded(fieldNode, owner, prop, name, includes, excludes);
addSetterIfNeeded(fieldNode, owner, prop, name, includes, excludes);
}
if (skipInterfaces)
return;
final Set<ClassNode> allInterfaces = getInterfacesAndSuperInterfaces(type);
final Set<ClassNode> ownerIfaces = owner.getAllInterfaces();
Map<String, ClassNode> genericsSpec = createGenericsSpec(fieldNode.getDeclaringClass());
genericsSpec = createGenericsSpec(fieldNode.getType(), genericsSpec);
for (ClassNode iface : allInterfaces) {
if (Modifier.isPublic(iface.getModifiers()) && !ownerIfaces.contains(iface)) {
final ClassNode[] ifaces = owner.getInterfaces();
final ClassNode[] newIfaces = new ClassNode[ifaces.length + 1];
for (int i = 0; i < ifaces.length; i++) {
newIfaces[i] = correctToGenericsSpecRecurse(genericsSpec, ifaces[i]);
}
newIfaces[ifaces.length] = correctToGenericsSpecRecurse(genericsSpec, iface);
owner.setInterfaces(newIfaces);
}
}
}
}
Aggregations