org.chromattic.groovy.ChromatticASTTransformationVisitor Maven / Gradle / Ivy
/*
* Copyright (C) 2003-2009 eXo Platform SAS.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.chromattic.groovy;
import org.chromattic.groovy.annotations.ChromatticDelegation;
import org.chromattic.groovy.exceptions.*;
import org.codehaus.groovy.ast.*;
import org.codehaus.groovy.control.CompilePhase;
import org.codehaus.groovy.control.SourceUnit;
import org.codehaus.groovy.transform.ASTTransformation;
import org.codehaus.groovy.transform.GroovyASTTransformation;
import java.util.*;
/**
* @author Alain Defrance
* @version $Revision$
*/
@GroovyASTTransformation(phase= CompilePhase.INSTRUCTION_SELECTION)
public class ChromatticASTTransformationVisitor implements ASTTransformation
{
private final ChromatticAnnotationMover annotationMover = new ChromatticAnnotationMover();
private final ChromatticFieldChecker fieldChecker = new ChromatticFieldChecker();
private final ChromatticDelegate delegate = new ChromatticDelegate();
private final ChromatticConstructor constructor = new ChromatticConstructor();
private final ChromatticImplementor implementor = new ChromatticImplementor();
public void visit(ASTNode[] nodes, SourceUnit sourceUnit) throws ChromatticASTTransformationException {
for (ClassNode classNode : (List) sourceUnit.getAST().getClasses()) {
if (!classNode.isScript() && !classNode.isInterface() && isInChromatticHierarchy(classNode)) {
visitClass(classNode);
}
}
}
private void visitClass(ClassNode classNode) throws ChromatticASTTransformationException {
try {
constructor.setProtectedDefaultConstructor(classNode);
} catch (NoSuchDefaultConstructor e) {
constructor.generateProtectedDefaultConstructor(classNode);
}
constructor.generatePublicHandlerConstructor(classNode);
annotationMover.applyGroovyInstrumentor(classNode);
// Browse children to adapt groovy structure
for (FieldNode fieldNode : classNode.getFields()) {
if (
GroovyUtils.isChromatticAnnoted(fieldNode)
) {
//
try {
annotationMover.addSetterDelegationAnnotation(classNode, fieldNode);
} catch (NoSuchSetterException e) {
annotationMover.generateSetter(classNode, fieldNode);
}
for (AnnotationNode annotationNode : (List) fieldNode.getAnnotations()) {
if (annotationNode.getClassNode().getName().startsWith(GroovyUtils.ANNOTATIONS_PACKAGE)) {
fieldChecker.checkChromaticFieldType(fieldNode);
//
try {
annotationMover.addFieldAnnotationToMethod(classNode, fieldNode, annotationNode);
} catch (NoSuchGetterException e) {
annotationMover.generateGetter(classNode, fieldNode, annotationNode);
}
}
}
} else if (GroovyUtils.isChromatticAnnotedInHierarchy(null, fieldNode)) {
annotationMover.generateGetter(classNode, fieldNode, new AnnotationNode(new ClassNode(ChromatticDelegation.class)));
annotationMover.generateSetter(classNode, fieldNode);
}
annotationMover.removeChromatticAnnotation(fieldNode);
}
// Transform GroovyObject to ChromatticObject
delegate.setGroovyInterceptable(classNode);
delegate.addInvokerField(classNode);
try {
delegate.plugGetProperty(classNode);
} catch (NoSuchMethodException e) {
delegate.generateGetProperty(classNode);
}
try {
delegate.plugSetProperty(classNode);
} catch (NoSuchMethodException e) {
delegate.generateSetProperty(classNode);
}
try {
delegate.plugInvokeMethod(classNode);
} catch (NoSuchMethodException e) {
delegate.generateInvokeMethod(classNode);
}
delegate.removeChromatticField(classNode);
for (MethodNode methodNode : classNode.getMethods()) {
if (methodNode.isAbstract()) {
implementor.implement(methodNode);
}
}
}
private boolean isInChromatticHierarchy(ClassNode classNode) {
if (classNode != null) {
Set annotationNodeSet = new HashSet();
annotationNodeSet.addAll(classNode.getAnnotations());
for (FieldNode fieldNode : classNode.getFields()) annotationNodeSet.addAll(fieldNode.getAnnotations());
for (MethodNode methodNode : classNode.getMethods()) annotationNodeSet.addAll(methodNode.getAnnotations());
for (AnnotationNode annotationNode : annotationNodeSet) {
if (annotationNode.getClassNode().getName().startsWith(GroovyUtils.ANNOTATIONS_PACKAGE)) {
return true;
}
}
return isInChromatticHierarchy(classNode.getSuperClass());
} else {
return false;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy