/** * 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]; if (nodes[1] instanceof ClassNode) { addListenerToClass(source, (ClassNode) nodes[1]); } else { if ((((FieldNode)nodes[1]).getModifiers() & Opcodes.ACC_FINAL) != 0) { source.getErrorCollector().addErrorAndContinue(new SyntaxErrorMessage( new SyntaxException("@groovy.beans.Vetoable cannot annotate a final property.", node.getLineNumber(), node.getColumnNumber(), node.getLastLineNumber(), node.getLastColumnNumber()), source)); } addListenerToProperty(source, node, (AnnotatedNode) nodes[1]); } }
private static ClassNode getTargetClass(SourceUnit source, AnnotationNode annotation) { Expression value = annotation.getMember("value"); if (!(value instanceof ClassExpression)) { //noinspection ThrowableInstanceNeverThrown source.getErrorCollector().addErrorAndContinue(new SyntaxErrorMessage( new SyntaxException("@groovy.lang.Category must define 'value' which is the class to apply this category to", annotation.getLineNumber(), annotation.getColumnNumber(), annotation.getLastLineNumber(), annotation.getLastColumnNumber()), source)); return null; } else { ClassExpression ce = (ClassExpression) value; return ce.getType(); } } }
private void addListenerToProperty(SourceUnit source, AnnotationNode node, ClassNode declaringClass, FieldNode field) { String fieldName = field.getName(); for (PropertyNode propertyNode : declaringClass.getProperties()) { if (propertyNode.getName().equals(fieldName)) { if (field.isStatic()) { //noinspection ThrowableInstanceNeverThrown source.getErrorCollector().addErrorAndContinue(new SyntaxErrorMessage( new SyntaxException("@groovy.beans.Bindable cannot annotate a static property.", node.getLineNumber(), node.getColumnNumber(), node.getLastLineNumber(), node.getLastColumnNumber()), source)); } else { if (needsPropertyChangeSupport(declaringClass, source)) { addPropertyChangeSupport(declaringClass); } createListenerSetter(declaringClass, propertyNode); } return; } } //noinspection ThrowableInstanceNeverThrown source.getErrorCollector().addErrorAndContinue(new SyntaxErrorMessage( new SyntaxException("@groovy.beans.Bindable 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)); }
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)); }
source.getErrorCollector().addErrorAndContinue(new SyntaxErrorMessage( new SyntaxException("@groovy.beans.Bindable cannot annotate a final property.", node.getLineNumber(), node.getColumnNumber(), node.getLastLineNumber(), node.getLastColumnNumber()), source));
protected void addError(String msg) { this.errorCollector.addErrorAndContinue( new SyntaxErrorMessage(new SyntaxException(msg + " in @" + this.annotationClass.getName() + '\n', this.annotation.getLineNumber(), this.annotation.getColumnNumber()), this.source) ); }
/** * gets the first non annotation line number of a node, taking into account annotations. */ public static int findFirstNonAnnotationLine(ASTNode node, SourceCode sourceCode) { if (node instanceof AnnotatedNode && !((AnnotatedNode) node).getAnnotations().isEmpty()) { // HACK: Groovy line numbers are broken when annotations have a parameter :( // so we must look at the lineNumber, not the lastLineNumber AnnotationNode lastAnnotation = null; for (AnnotationNode annotation : ((AnnotatedNode) node).getAnnotations()) { if (lastAnnotation == null) lastAnnotation = annotation; else if (lastAnnotation.getLineNumber() < annotation.getLineNumber()) lastAnnotation = annotation; } String rawLine = getRawLine(sourceCode, lastAnnotation.getLastLineNumber()-1); if(rawLine == null) { return node.getLineNumber(); } // is the annotation the last thing on the line? if (rawLine.length() > lastAnnotation.getLastColumnNumber()) { // no it is not return lastAnnotation.getLastLineNumber(); } // yes it is the last thing, return the next thing return lastAnnotation.getLastLineNumber() + 1; } return node.getLineNumber(); }
/** * Generates a SyntaxErrorMessage based on the current SourceUnit, AnnotationNode, and a specified * error message. * * @param sourceUnit The SourceUnit * @param node The node that was annotated * @param msg The error message to display */ private void generateSyntaxErrorMessage(SourceUnit sourceUnit, AnnotationNode node, String msg) { SyntaxException error = new SyntaxException(msg, node.getLineNumber(), node.getColumnNumber()); sourceUnit.getErrorCollector().addErrorAndContinue(new SyntaxErrorMessage(error, sourceUnit)); }
/** * Generates a SyntaxErrorMessage based on the current SourceUnit, AnnotationNode, and a specified * error message. * * @param sourceUnit The SourceUnit * @param node The node that was annotated * @param msg The error message to display */ private void generateSyntaxErrorMessage(SourceUnit sourceUnit, AnnotationNode node, String msg) { SyntaxException error = new SyntaxException(msg, node.getLineNumber(), node.getColumnNumber()); sourceUnit.getErrorCollector().addErrorAndContinue(new SyntaxErrorMessage(error, sourceUnit)); }
private static OffsetRange getAnnotationRange(AnnotationNode annotation, BaseDocument doc, int cursorOffset) { final int offset = ASTUtils.getOffset(doc, annotation.getLineNumber(), annotation.getColumnNumber()); final OffsetRange range = ASTUtils.getNextIdentifierByName(doc, annotation.getClassNode().getNameWithoutPackage(), offset); if (range.containsInclusive(cursorOffset)) { return range; } return OffsetRange.NONE; }
private ClassNode getTargetClass(SourceUnit source, AnnotationNode annotation) { final Expression value = annotation.getMember("value"); if (value == null || !(value instanceof ClassExpression)) { //noinspection ThrowableInstanceNeverThrown source.getErrorCollector().addErrorAndContinue( new SyntaxErrorMessage(new SyntaxException( "@groovy.lang.Category must define 'value' which is the class to apply this category to", annotation.getLineNumber(), annotation.getColumnNumber()), source)); } return value != null ? value.getType() : null; } }
private ClassNode getTargetClass(SourceUnit source, AnnotationNode annotation) { final Expression value = annotation.getMember("value"); if (value == null || !(value instanceof ClassExpression)) { //noinspection ThrowableInstanceNeverThrown source.getErrorCollector().addErrorAndContinue( new SyntaxErrorMessage(new SyntaxException( "@groovy.lang.Category must define 'value' which is class to apply this category", annotation.getLineNumber(), annotation.getColumnNumber()), source)); } ClassNode targetClass = ((ClassExpression)value).getType(); return targetClass; } }
/** * 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]; if (nodes[1] instanceof ClassNode) { addListenerToClass(source, node, (ClassNode) nodes[1]); } else { if ((((FieldNode)nodes[1]).getModifiers() & Opcodes.ACC_FINAL) != 0) { source.getErrorCollector().addErrorAndContinue( new SyntaxErrorMessage(new SyntaxException( "@groovy.beans.Vetoable cannot annotate a final property.", node.getLineNumber(), node.getColumnNumber()), source)); } addListenerToProperty(source, node, (AnnotatedNode) nodes[1]); } }
private void addAnnotationOccurrences(AnnotationNode annotation, ClassNode findingNode) { ClassNode classNode = annotation.getClassNode(); classNode.setLineNumber(annotation.getLineNumber()); classNode.setColumnNumber(annotation.getColumnNumber()); classNode.setLastLineNumber(annotation.getLastLineNumber()); classNode.setLastColumnNumber(annotation.getLastColumnNumber()); addOccurrences(classNode, findingNode); }
private ClassNode getTargetClass(SourceUnit source, AnnotationNode annotation) { Expression value = annotation.getMember("value"); if (value == null || !(value instanceof ClassExpression)) { //noinspection ThrowableInstanceNeverThrown source.getErrorCollector().addErrorAndContinue( new SyntaxErrorMessage(new SyntaxException( "@groovy.lang.Category must define 'value' which is the class to apply this category to", annotation.getLineNumber(), annotation.getColumnNumber()), source)); return null; } else { ClassExpression ce = (ClassExpression) value; return ce.getType(); } } }
/** * 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]; if (nodes[1] instanceof ClassNode) { addVetoableIfNeeded(source, (ClassNode) nodes[1]); } else { if ((((FieldNode) nodes[1]).getModifiers() & Modifier.FINAL) != 0) { source.getErrorCollector().addErrorAndContinue(new SyntaxErrorMessage( new SyntaxException("@griffon.transform.Vetoable cannot annotate a final property.", node.getLineNumber(), node.getColumnNumber(), node.getLastLineNumber(), node.getLastColumnNumber()), source)); } addVetoableIfNeeded(source, node, (AnnotatedNode) nodes[1]); } }
private void addListenerToProperty(SourceUnit source, AnnotationNode node, ClassNode declaringClass, FieldNode field) { String fieldName = field.getName(); for (PropertyNode propertyNode : (Collection<PropertyNode>) declaringClass.getProperties()) { if (propertyNode.getName().equals(fieldName)) { if (field.isStatic()) { //noinspection ThrowableInstanceNeverThrown source.getErrorCollector().addErrorAndContinue( new SyntaxErrorMessage(new SyntaxException( "@groovy.beans.Bindable cannot annotate a static property.", node.getLineNumber(), node.getColumnNumber()), source)); } else { if (needsPropertyChangeSupport(declaringClass, source)) { addPropertyChangeSupport(declaringClass); } createListenerSetter(source, node, declaringClass, propertyNode); } return; } } //noinspection ThrowableInstanceNeverThrown source.getErrorCollector().addErrorAndContinue( new SyntaxErrorMessage(new SyntaxException( "@groovy.beans.Bindable must be on a property, not a field. Try removing the private, protected, or public modifier.", node.getLineNumber(), node.getColumnNumber()), source)); }
public static void addObservableIfNeeded(SourceUnit source, AnnotationNode annotationNode, ClassNode classNode, FieldNode field) { String fieldName = field.getName(); for (PropertyNode propertyNode : classNode.getProperties()) { if (propertyNode.getName().equals(fieldName)) { if (field.isStatic()) { //noinspection ThrowableInstanceNeverThrown source.getErrorCollector().addErrorAndContinue(new SyntaxErrorMessage( new SyntaxException("@griffon.transform.Observable cannot annotate a static property.", annotationNode.getLineNumber(), annotationNode.getColumnNumber(), annotationNode.getLastLineNumber(), annotationNode.getLastColumnNumber()), source)); } else { if (needsObservableSupport(classNode, source)) { LOG.debug("Injecting {} into {}", OBSERVABLE_TYPE, classNode.getName()); apply(classNode); } createListenerSetter(classNode, propertyNode); } return; } } //noinspection ThrowableInstanceNeverThrown source.getErrorCollector().addErrorAndContinue(new SyntaxErrorMessage( new SyntaxException("@griffon.transform.Observable must be on a property, not a field. Try removing the private, protected, or public modifier.", annotationNode.getLineNumber(), annotationNode.getColumnNumber(), annotationNode.getLastLineNumber(), annotationNode.getLastColumnNumber()), source)); }
private void addListenerToProperty(SourceUnit source, AnnotationNode node, AnnotatedNode parent) { ClassNode declaringClass = parent.getDeclaringClass(); FieldNode field = ((FieldNode) parent); String fieldName = field.getName(); for (PropertyNode propertyNode : (Collection<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()), source)); } else { createListenerSetter(source, node, 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()), source)); }
private void addVetoableIfNeeded(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 = hasObservableAnnotation(parent) || hasObservableAnnotation(parent.getDeclaringClass()); if (propertyNode.getName().equals(fieldName)) { if (field.isStatic()) { source.getErrorCollector().addErrorAndContinue(new SyntaxErrorMessage( new SyntaxException("@griffon.transform.Vetoable cannot annotate a static property.", node.getLineNumber(), node.getColumnNumber(), node.getLastLineNumber(), node.getLastColumnNumber()), source)); } else { createListenerSetter(source, bindable, declaringClass, propertyNode); } return; } } source.getErrorCollector().addErrorAndContinue(new SyntaxErrorMessage( new SyntaxException("@griffon.transform.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)); }