aboutsummaryrefslogtreecommitdiff
path: root/src/lombok/eclipse/TransformEclipseAST.java
blob: d0685d1d41e4e83a9403e6698545cdb5bfa42f3b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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:
 * 
 * <code>methodDeclaration.bits |= 0x80000;</code>
 * 
 * @author rzwitserloot
 * @author rspilker
 */
public class TransformEclipseAST {
	private static final Map<CompilationUnitDeclaration, EclipseAST> astCache =
		new WeakHashMap<CompilationUnitDeclaration, EclipseAST>();
	
	/**
	 * 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);
				}
			}
		}
		
	}
}