package lombok.eclipse; import java.util.Map; import java.util.WeakHashMap; import lombok.eclipse.EclipseAST.Node; import lombok.eclipse.handlers.HandleGetter_ecj; import org.eclipse.jdt.internal.compiler.ast.Annotation; import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; import org.eclipse.jdt.internal.compiler.ast.TypeReference; import org.eclipse.jdt.internal.compiler.parser.Parser; /** * Entry point for the Eclipse Parser patch that lets lombok modify the Abstract Syntax Tree as generated by * eclipse's parser implementations. This class is injected into the appropriate OSGi ClassLoader and can thus * use any classes that belong to org.eclipse.jdt.(apt.)core. * * Note that, for any Method body, if Bit24 is set, the eclipse parser has been patched to never attempt to * (re)parse it. You should set Bit24 on any MethodDeclaration object you inject into the AST: * * methodDeclaration.bits |= 0x80000; * * @author rzwitserloot * @author rspilker */ public class TransformEclipseAST { private static final Map astCache = new WeakHashMap(); /** * This method is called immediately after eclipse finishes building a CompilationUnitDeclaration, which is * the top-level AST node when eclipse parses a source file. The signature is 'magic' - you should not * change it! * * Eclipse's parsers often operate in diet mode, which means many parts of the AST have been left blank. * Be ready to deal with just about anything being null, such as the Statement[] arrays of the Method AST nodes. * * @param parser The eclipse parser object that generated the AST. * @param ast The AST node belonging to the compilation unit (java speak for a single source file). */ public static void transform(Parser parser, CompilationUnitDeclaration ast) { EclipseAST existing = astCache.get(ast); if ( existing == null ) { existing = new EclipseAST(ast); astCache.put(ast, existing); } else existing.reparse(); existing.traverse(new AnnotationVisitor()); } private static class AnnotationVisitor extends EclipseASTAdapter { @Override public void visitField(Node node, FieldDeclaration field) { if ( field.annotations == null ) return; for ( Annotation annotation : field.annotations ) { TypeReference type = annotation.type; if ( type != null && new String(type.getLastToken()).equals("Getter") ) { new HandleGetter_ecj().apply(annotation, node, field); } } } } }