Search in sources :

Example 1 with SimpleMessage

use of org.codehaus.groovy.control.messages.SimpleMessage in project groovy by apache.

the class BindableASTTransformation method needsPropertyChangeSupport.

/**
     * Snoops through the declaring class and all parents looking for methods
     * <code>void addPropertyChangeListener(PropertyChangeListener)</code>,
     * <code>void removePropertyChangeListener(PropertyChangeListener)</code>, and
     * <code>void firePropertyChange(String, Object, Object)</code>. If any are defined all
     * must be defined or a compilation error results.
     *
     * @param declaringClass the class to search
     * @param sourceUnit the source unit, for error reporting. {@code @NotNull}.
     * @return true if property change support should be added
     */
protected boolean needsPropertyChangeSupport(ClassNode declaringClass, SourceUnit sourceUnit) {
    boolean foundAdd = false, foundRemove = false, foundFire = false;
    ClassNode consideredClass = declaringClass;
    while (consideredClass != null) {
        for (MethodNode method : consideredClass.getMethods()) {
            // just check length, MOP will match it up
            foundAdd = foundAdd || method.getName().equals("addPropertyChangeListener") && method.getParameters().length == 1;
            foundRemove = foundRemove || method.getName().equals("removePropertyChangeListener") && method.getParameters().length == 1;
            foundFire = foundFire || method.getName().equals("firePropertyChange") && method.getParameters().length == 3;
            if (foundAdd && foundRemove && foundFire) {
                return false;
            }
        }
        consideredClass = consideredClass.getSuperClass();
    }
    // check if a super class has @Bindable annotations
    consideredClass = declaringClass.getSuperClass();
    while (consideredClass != null) {
        if (hasBindableAnnotation(consideredClass))
            return false;
        for (FieldNode field : consideredClass.getFields()) {
            if (hasBindableAnnotation(field))
                return false;
        }
        consideredClass = consideredClass.getSuperClass();
    }
    if (foundAdd || foundRemove || foundFire) {
        sourceUnit.getErrorCollector().addErrorAndContinue(new SimpleMessage("@Bindable cannot be processed on " + declaringClass.getName() + " because some but not all of addPropertyChangeListener, removePropertyChange, and firePropertyChange were declared in the current or super classes.", sourceUnit));
        return false;
    }
    return true;
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) MethodNode(org.codehaus.groovy.ast.MethodNode) FieldNode(org.codehaus.groovy.ast.FieldNode) SimpleMessage(org.codehaus.groovy.control.messages.SimpleMessage)

Example 2 with SimpleMessage

use of org.codehaus.groovy.control.messages.SimpleMessage in project groovy by apache.

the class ASTTransformationCollectorCodeVisitor method getTransformClassNames.

private List<String> getTransformClassNames(AnnotationNode annotation, Annotation transformClassAnnotation) {
    List<String> result = new ArrayList<String>();
    try {
        Method valueMethod = transformClassAnnotation.getClass().getMethod("value");
        String[] names = (String[]) valueMethod.invoke(transformClassAnnotation);
        result.addAll(Arrays.asList(names));
        Method classesMethod = transformClassAnnotation.getClass().getMethod("classes");
        Class[] classes = (Class[]) classesMethod.invoke(transformClassAnnotation);
        for (Class klass : classes) {
            result.add(klass.getName());
        }
        if (names.length > 0 && classes.length > 0) {
            source.getErrorCollector().addError(new SimpleMessage("@GroovyASTTransformationClass in " + annotation.getClassNode().getName() + " should specify transforms only by class names or by classes and not by both", source));
        }
    } catch (Exception e) {
        source.addException(e);
    }
    return result;
}
Also used : SimpleMessage(org.codehaus.groovy.control.messages.SimpleMessage) ArrayList(java.util.ArrayList) Method(java.lang.reflect.Method) SyntaxException(org.codehaus.groovy.syntax.SyntaxException)

Example 3 with SimpleMessage

use of org.codehaus.groovy.control.messages.SimpleMessage in project groovy by apache.

the class ASTTransformationVisitor method doAddGlobalTransforms.

private static void doAddGlobalTransforms(ASTTransformationsContext context, boolean isFirstScan) {
    final CompilationUnit compilationUnit = context.getCompilationUnit();
    GroovyClassLoader transformLoader = compilationUnit.getTransformLoader();
    Map<String, URL> transformNames = new LinkedHashMap<String, URL>();
    try {
        Enumeration<URL> globalServices = transformLoader.getResources("META-INF/services/org.codehaus.groovy.transform.ASTTransformation");
        while (globalServices.hasMoreElements()) {
            URL service = globalServices.nextElement();
            String className;
            BufferedReader svcIn = null;
            try {
                svcIn = new BufferedReader(new InputStreamReader(service.openStream(), "UTF-8"));
                try {
                    className = svcIn.readLine();
                } catch (IOException ioe) {
                    compilationUnit.getErrorCollector().addError(new SimpleMessage("IOException reading the service definition at " + service.toExternalForm() + " because of exception " + ioe.toString(), null));
                    continue;
                }
                Set<String> disabledGlobalTransforms = compilationUnit.getConfiguration().getDisabledGlobalASTTransformations();
                if (disabledGlobalTransforms == null)
                    disabledGlobalTransforms = Collections.emptySet();
                while (className != null) {
                    if (!className.startsWith("#") && className.length() > 0) {
                        if (!disabledGlobalTransforms.contains(className)) {
                            if (transformNames.containsKey(className)) {
                                if (!service.equals(transformNames.get(className))) {
                                    compilationUnit.getErrorCollector().addWarning(WarningMessage.POSSIBLE_ERRORS, "The global transform for class " + className + " is defined in both " + transformNames.get(className).toExternalForm() + " and " + service.toExternalForm() + " - the former definition will be used and the latter ignored.", null, null);
                                }
                            } else {
                                transformNames.put(className, service);
                            }
                        }
                    }
                    try {
                        className = svcIn.readLine();
                    } catch (IOException ioe) {
                        compilationUnit.getErrorCollector().addError(new SimpleMessage("IOException reading the service definition at " + service.toExternalForm() + " because of exception " + ioe.toString(), null));
                        //noinspection UnnecessaryContinue
                        continue;
                    }
                }
            } finally {
                if (svcIn != null)
                    svcIn.close();
            }
        }
    } catch (IOException e) {
        //FIXME the warning message will NPE with what I have :(
        compilationUnit.getErrorCollector().addError(new SimpleMessage("IO Exception attempting to load global transforms:" + e.getMessage(), null));
    }
    try {
        // test for 1.5 JVM
        Class.forName("java.lang.annotation.Annotation");
    } catch (Exception e) {
        // we failed, notify the user
        StringBuilder sb = new StringBuilder();
        sb.append("Global ASTTransformations are not enabled in retro builds of groovy.\n");
        sb.append("The following transformations will be ignored:");
        for (Map.Entry<String, URL> entry : transformNames.entrySet()) {
            sb.append('\t');
            sb.append(entry.getKey());
            sb.append('\n');
        }
        compilationUnit.getErrorCollector().addWarning(new WarningMessage(WarningMessage.POSSIBLE_ERRORS, sb.toString(), null, null));
        return;
    }
    // can be added for only for new transforms that have come in 
    if (isFirstScan) {
        for (Map.Entry<String, URL> entry : transformNames.entrySet()) {
            context.getGlobalTransformNames().add(entry.getKey());
        }
        addPhaseOperationsForGlobalTransforms(context.getCompilationUnit(), transformNames, isFirstScan);
    } else {
        Iterator<Map.Entry<String, URL>> it = transformNames.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, URL> entry = it.next();
            if (!context.getGlobalTransformNames().add(entry.getKey())) {
                // phase operations for this transform class have already been added before, so remove from current scan cycle
                it.remove();
            }
        }
        addPhaseOperationsForGlobalTransforms(context.getCompilationUnit(), transformNames, isFirstScan);
    }
}
Also used : WarningMessage(org.codehaus.groovy.control.messages.WarningMessage) InputStreamReader(java.io.InputStreamReader) SimpleMessage(org.codehaus.groovy.control.messages.SimpleMessage) IOException(java.io.IOException) URL(java.net.URL) IOException(java.io.IOException) GroovyClassLoader(groovy.lang.GroovyClassLoader) BufferedReader(java.io.BufferedReader)

Example 4 with SimpleMessage

use of org.codehaus.groovy.control.messages.SimpleMessage in project groovy by apache.

the class ASTTransformationVisitor method addPhaseOperationsForGlobalTransforms.

private static void addPhaseOperationsForGlobalTransforms(CompilationUnit compilationUnit, Map<String, URL> transformNames, boolean isFirstScan) {
    GroovyClassLoader transformLoader = compilationUnit.getTransformLoader();
    for (Map.Entry<String, URL> entry : transformNames.entrySet()) {
        try {
            Class gTransClass = transformLoader.loadClass(entry.getKey(), false, true, false);
            //no inspection unchecked
            GroovyASTTransformation transformAnnotation = (GroovyASTTransformation) gTransClass.getAnnotation(GroovyASTTransformation.class);
            if (transformAnnotation == null) {
                compilationUnit.getErrorCollector().addWarning(new WarningMessage(WarningMessage.POSSIBLE_ERRORS, "Transform Class " + entry.getKey() + " is specified as a global transform in " + entry.getValue().toExternalForm() + " but it is not annotated by " + GroovyASTTransformation.class.getName() + " the global transform associated with it may fail and cause the compilation to fail.", null, null));
                continue;
            }
            if (ASTTransformation.class.isAssignableFrom(gTransClass)) {
                final ASTTransformation instance = (ASTTransformation) gTransClass.newInstance();
                if (instance instanceof CompilationUnitAware) {
                    ((CompilationUnitAware) instance).setCompilationUnit(compilationUnit);
                }
                CompilationUnit.SourceUnitOperation suOp = new CompilationUnit.SourceUnitOperation() {

                    public void call(SourceUnit source) throws CompilationFailedException {
                        instance.visit(new ASTNode[] { source.getAST() }, source);
                    }
                };
                if (isFirstScan) {
                    compilationUnit.addPhaseOperation(suOp, transformAnnotation.phase().getPhaseNumber());
                } else {
                    compilationUnit.addNewPhaseOperation(suOp, transformAnnotation.phase().getPhaseNumber());
                }
            } else {
                compilationUnit.getErrorCollector().addError(new SimpleMessage("Transform Class " + entry.getKey() + " specified at " + entry.getValue().toExternalForm() + " is not an ASTTransformation.", null));
            }
        } catch (Exception e) {
            compilationUnit.getErrorCollector().addError(new SimpleMessage("Could not instantiate global transform class " + entry.getKey() + " specified at " + entry.getValue().toExternalForm() + "  because of exception " + e.toString(), null));
        }
    }
}
Also used : WarningMessage(org.codehaus.groovy.control.messages.WarningMessage) CompilationUnitAware(groovy.transform.CompilationUnitAware) SimpleMessage(org.codehaus.groovy.control.messages.SimpleMessage) URL(java.net.URL) IOException(java.io.IOException) GroovyClassLoader(groovy.lang.GroovyClassLoader)

Example 5 with SimpleMessage

use of org.codehaus.groovy.control.messages.SimpleMessage in project groovy-core by groovy.

the class VetoableASTTransformation method needsVetoableChangeSupport.

/**
 * Snoops through the declaring class and all parents looking for a field
 * of type VetoableChangeSupport.  Remembers the field and returns false
 * if found otherwise returns true to indicate that such support should
 * be added.
 *
 * @param declaringClass the class to search
 * @return true if vetoable change support should be added
 */
protected boolean needsVetoableChangeSupport(ClassNode declaringClass, SourceUnit sourceUnit) {
    boolean foundAdd = false, foundRemove = false, foundFire = false;
    ClassNode consideredClass = declaringClass;
    while (consideredClass != null) {
        for (MethodNode method : consideredClass.getMethods()) {
            // just check length, MOP will match it up
            foundAdd = foundAdd || method.getName().equals("addVetoableChangeListener") && method.getParameters().length == 1;
            foundRemove = foundRemove || method.getName().equals("removeVetoableChangeListener") && method.getParameters().length == 1;
            foundFire = foundFire || method.getName().equals("fireVetoableChange") && method.getParameters().length == 3;
            if (foundAdd && foundRemove && foundFire) {
                return false;
            }
        }
        consideredClass = consideredClass.getSuperClass();
    }
    // check if a super class has @Vetoable annotations
    consideredClass = declaringClass.getSuperClass();
    while (consideredClass != null) {
        if (hasVetoableAnnotation(consideredClass))
            return false;
        for (FieldNode field : consideredClass.getFields()) {
            if (hasVetoableAnnotation(field))
                return false;
        }
        consideredClass = consideredClass.getSuperClass();
    }
    if (foundAdd || foundRemove || foundFire) {
        sourceUnit.getErrorCollector().addErrorAndContinue(new SimpleMessage("@Vetoable cannot be processed on " + declaringClass.getName() + " because some but not all of addVetoableChangeListener, removeVetoableChange, and fireVetoableChange were declared in the current or super classes.", sourceUnit));
        return false;
    }
    return true;
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) MethodNode(org.codehaus.groovy.ast.MethodNode) FieldNode(org.codehaus.groovy.ast.FieldNode) SimpleMessage(org.codehaus.groovy.control.messages.SimpleMessage)

Aggregations

SimpleMessage (org.codehaus.groovy.control.messages.SimpleMessage)15 GroovyClassLoader (groovy.lang.GroovyClassLoader)7 IOException (java.io.IOException)6 InputStreamReader (java.io.InputStreamReader)4 URL (java.net.URL)4 GroovyBugError (org.codehaus.groovy.GroovyBugError)4 ClassNode (org.codehaus.groovy.ast.ClassNode)4 FieldNode (org.codehaus.groovy.ast.FieldNode)4 MethodNode (org.codehaus.groovy.ast.MethodNode)4 WarningMessage (org.codehaus.groovy.control.messages.WarningMessage)4 CompilerConfiguration (org.codehaus.groovy.control.CompilerConfiguration)3 Binding (groovy.lang.Binding)2 Closure (groovy.lang.Closure)2 GroovyShell (groovy.lang.GroovyShell)2 CompilationUnitAware (groovy.transform.CompilationUnitAware)2 BufferedReader (java.io.BufferedReader)2 InputStream (java.io.InputStream)2 Reader (java.io.Reader)2 UnsupportedEncodingException (java.io.UnsupportedEncodingException)2 Constructor (java.lang.reflect.Constructor)2