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;
}
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;
}
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);
}
}
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));
}
}
}
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;
}
Aggregations