use of org.codehaus.groovy.ast.FieldNode in project groovy by apache.
the class BindableASTTransformation method visit.
/**
* Handles the bulk of the processing, mostly delegating to other methods.
*
* @param nodes the ast nodes
* @param source the source unit for the nodes
*/
public void visit(ASTNode[] nodes, SourceUnit source) {
if (!(nodes[0] instanceof AnnotationNode) || !(nodes[1] instanceof AnnotatedNode)) {
throw new RuntimeException("Internal error: wrong types: $node.class / $parent.class");
}
AnnotationNode node = (AnnotationNode) nodes[0];
AnnotatedNode parent = (AnnotatedNode) nodes[1];
if (VetoableASTTransformation.hasVetoableAnnotation(parent)) {
// VetoableASTTransformation will handle both @Bindable and @Vetoable
return;
}
ClassNode declaringClass = parent.getDeclaringClass();
if (parent instanceof FieldNode) {
if ((((FieldNode) parent).getModifiers() & Opcodes.ACC_FINAL) != 0) {
source.getErrorCollector().addErrorAndContinue(new SyntaxErrorMessage(new SyntaxException("@groovy.beans.Bindable cannot annotate a final property.", node.getLineNumber(), node.getColumnNumber(), node.getLastLineNumber(), node.getLastColumnNumber()), source));
}
if (VetoableASTTransformation.hasVetoableAnnotation(parent.getDeclaringClass())) {
// VetoableASTTransformation will handle both @Bindable and @Vetoable
return;
}
addListenerToProperty(source, node, declaringClass, (FieldNode) parent);
} else if (parent instanceof ClassNode) {
addListenerToClass(source, (ClassNode) parent);
}
}
use of org.codehaus.groovy.ast.FieldNode in project groovy by apache.
the class VetoableASTTransformation method addListenerToProperty.
private void addListenerToProperty(SourceUnit source, AnnotationNode node, AnnotatedNode parent) {
ClassNode declaringClass = parent.getDeclaringClass();
FieldNode field = ((FieldNode) parent);
String fieldName = field.getName();
for (PropertyNode propertyNode : declaringClass.getProperties()) {
boolean bindable = BindableASTTransformation.hasBindableAnnotation(parent) || BindableASTTransformation.hasBindableAnnotation(parent.getDeclaringClass());
if (propertyNode.getName().equals(fieldName)) {
if (field.isStatic()) {
//noinspection ThrowableInstanceNeverThrown
source.getErrorCollector().addErrorAndContinue(new SyntaxErrorMessage(new SyntaxException("@groovy.beans.Vetoable cannot annotate a static property.", node.getLineNumber(), node.getColumnNumber(), node.getLastLineNumber(), node.getLastColumnNumber()), source));
} else {
createListenerSetter(source, bindable, declaringClass, propertyNode);
}
return;
}
}
//noinspection ThrowableInstanceNeverThrown
source.getErrorCollector().addErrorAndContinue(new SyntaxErrorMessage(new SyntaxException("@groovy.beans.Vetoable must be on a property, not a field. Try removing the private, protected, or public modifier.", node.getLineNumber(), node.getColumnNumber(), node.getLastLineNumber(), node.getLastColumnNumber()), source));
}
use of org.codehaus.groovy.ast.FieldNode in project groovy by apache.
the class AbstractASTTransformation method checkPropertyList.
protected boolean checkPropertyList(ClassNode cNode, List<String> propertyNameList, String listName, AnnotationNode anno, String typeName, boolean includeFields, boolean includeSuperProperties, boolean allProperties, boolean includeSuperFields) {
if (propertyNameList == null || propertyNameList.isEmpty()) {
return true;
}
final List<String> pNames = new ArrayList<String>();
for (PropertyNode pNode : BeanUtils.getAllProperties(cNode, includeSuperProperties, false, allProperties)) {
pNames.add(pNode.getField().getName());
}
boolean result = true;
if (includeFields || includeSuperFields) {
final List<String> fNames = new ArrayList<String>();
if (includeFields) {
fNames.addAll(getInstanceNonPropertyFieldNames(cNode));
}
if (includeSuperFields) {
List<FieldNode> superNonPropertyFields = getSuperNonPropertyFields(cNode.getSuperClass());
for (FieldNode fn : superNonPropertyFields) {
fNames.add(fn.getName());
}
}
for (String pName : propertyNameList) {
if (!pNames.contains(pName) && !fNames.contains(pName)) {
addError("Error during " + typeName + " processing: '" + listName + "' property or field '" + pName + "' does not exist.", anno);
result = false;
}
}
} else {
for (String pName : propertyNameList) {
if (!pNames.contains(pName)) {
addError("Error during " + typeName + " processing: '" + listName + "' property '" + pName + "' does not exist.", anno);
result = false;
}
}
}
return result;
}
use of org.codehaus.groovy.ast.FieldNode in project groovy by apache.
the class AbstractInterruptibleASTTransformation method visit.
public void visit(ASTNode[] nodes, SourceUnit source) {
if (nodes.length != 2 || !(nodes[0] instanceof AnnotationNode) || !(nodes[1] instanceof AnnotatedNode)) {
internalError("Expecting [AnnotationNode, AnnotatedNode] but got: " + Arrays.asList(nodes));
}
this.source = source;
AnnotationNode node = (AnnotationNode) nodes[0];
AnnotatedNode annotatedNode = (AnnotatedNode) nodes[1];
if (!type().equals(node.getClassNode())) {
internalError("Transformation called from wrong annotation: " + node.getClassNode().getName());
}
setupTransform(node);
// should be limited to the current SourceUnit or propagated to the whole CompilationUnit
final ModuleNode tree = source.getAST();
if (applyToAllClasses) {
// guard every class and method defined in this script
if (tree != null) {
final List<ClassNode> classes = tree.getClasses();
for (ClassNode classNode : classes) {
visitClass(classNode);
}
}
} else if (annotatedNode instanceof ClassNode) {
// only guard this particular class
this.visitClass((ClassNode) annotatedNode);
} else if (!applyToAllMembers && annotatedNode instanceof MethodNode) {
this.visitMethod((MethodNode) annotatedNode);
this.visitClass(annotatedNode.getDeclaringClass());
} else if (!applyToAllMembers && annotatedNode instanceof FieldNode) {
this.visitField((FieldNode) annotatedNode);
this.visitClass(annotatedNode.getDeclaringClass());
} else if (!applyToAllMembers && annotatedNode instanceof DeclarationExpression) {
this.visitDeclarationExpression((DeclarationExpression) annotatedNode);
this.visitClass(annotatedNode.getDeclaringClass());
} else {
// only guard the script class
if (tree != null) {
final List<ClassNode> classes = tree.getClasses();
for (ClassNode classNode : classes) {
if (classNode.isScript()) {
visitClass(classNode);
}
}
}
}
}
use of org.codehaus.groovy.ast.FieldNode in project groovy by apache.
the class AutoCloneASTTransformation method createCloneCopyConstructor.
private static void createCloneCopyConstructor(ClassNode cNode, List<FieldNode> list, List<String> excludes) {
if (cNode.getDeclaredConstructors().isEmpty()) {
// add no-arg constructor
BlockStatement noArgBody = new BlockStatement();
noArgBody.addStatement(EmptyStatement.INSTANCE);
cNode.addConstructor(ACC_PUBLIC, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, noArgBody);
}
boolean hasThisCons = false;
for (ConstructorNode consNode : cNode.getDeclaredConstructors()) {
Parameter[] parameters = consNode.getParameters();
if (parameters.length == 1 && parameters[0].getType().equals(cNode)) {
hasThisCons = true;
}
}
if (!hasThisCons) {
BlockStatement initBody = new BlockStatement();
Parameter initParam = param(GenericsUtils.nonGeneric(cNode), "other");
final Expression other = varX(initParam);
boolean hasParent = cNode.getSuperClass() != ClassHelper.OBJECT_TYPE;
if (hasParent) {
initBody.addStatement(stmt(ctorX(ClassNode.SUPER, other)));
}
for (FieldNode fieldNode : list) {
String name = fieldNode.getName();
if (excludes != null && excludes.contains(name))
continue;
ClassNode fieldType = fieldNode.getType();
Expression direct = propX(other, name);
Expression to = propX(varX("this"), name);
Statement assignDirect = assignS(to, direct);
Statement assignCloned = assignS(to, castX(fieldType, callCloneDirectX(direct)));
Statement assignClonedDynamic = assignS(to, castX(fieldType, callCloneDynamicX(direct)));
if (isCloneableType(fieldType)) {
initBody.addStatement(assignCloned);
} else if (!possiblyCloneable(fieldType)) {
initBody.addStatement(assignDirect);
} else {
initBody.addStatement(ifElseS(isInstanceOfX(direct, CLONEABLE_TYPE), assignClonedDynamic, assignDirect));
}
}
cNode.addConstructor(ACC_PROTECTED, params(initParam), ClassNode.EMPTY_ARRAY, initBody);
}
ClassNode[] exceptions = { make(CloneNotSupportedException.class) };
cNode.addMethod("clone", ACC_PUBLIC, GenericsUtils.nonGeneric(cNode), Parameter.EMPTY_ARRAY, exceptions, block(stmt(ctorX(cNode, args(varX("this"))))));
}
Aggregations