Skip to content

Instantly share code, notes, and snippets.

@DarkSeraphim
Created November 6, 2017 21:14
Show Gist options
  • Save DarkSeraphim/6751268521a43aba0078ffa23435ce19 to your computer and use it in GitHub Desktop.
Save DarkSeraphim/6751268521a43aba0078ffa23435ce19 to your computer and use it in GitHub Desktop.
Fixed processor! (with member enter for actual methods)
package me.bramhaag.annotationtest.api.util;
import com.sun.source.tree.Tree;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.util.Context;
import me.bramhaag.annotationtest.api.ISpec;
import me.bramhaag.annotationtest.api.MethodSpec;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class SpecUtil {
public static void addToClass(Tree tree, Context context, ISpec... specs) {
if(!(tree instanceof JCTree.JCClassDecl)) {
throw new IllegalArgumentException("tree is not an instance of JCTree.JCClassDecl");
}
JCTree.JCClassDecl classDecl = (JCTree.JCClassDecl) tree;
List<JCTree> trees = new ArrayList<>(classDecl.defs);
Arrays.stream(specs)
.map(s -> s.createTree(context, classDecl))
.peek(methodTree -> {
if (methodTree instanceof JCTree.JCMethodDecl) {
((JCTree.JCClassDecl) classDecl).sym.members_field.enter(((JCTree.JCMethodDecl) methodTree).sym);
}
})
//.map(t -> getTree(t, classDecl))
.forEach(trees::add);
classDecl.defs = com.sun.tools.javac.util.List.from(trees.toArray(new JCTree[0]));
}
private static JCTree getTree(JCTree tree, JCTree.JCClassDecl classDecl) {
if(tree instanceof JCTree.JCMethodDecl) {
JCTree.JCMethodDecl methodDecl = (JCTree.JCMethodDecl) tree;
methodDecl.sym = new Symbol.MethodSymbol(methodDecl.mods.flags, methodDecl.name, methodDecl.type, classDecl.sym);
methodDecl.params.forEach(p -> {
p.sym = new Symbol.VarSymbol(Flags.PARAMETER, p.name, p.type, methodDecl.sym);
p.sym.adr = 0;
p.sym.name = p.name;
});
classDecl.sym.members_field.enter(methodDecl.sym);
}
return tree;
}
}
package me.bramhaag.annotationtest.processor;
import com.google.auto.service.AutoService;
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.util.JavacTask;
import com.sun.source.util.TaskEvent;
import com.sun.source.util.TaskListener;
import com.sun.source.util.Trees;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symtab;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.model.JavacElements;
import com.sun.tools.javac.processing.JavacProcessingEnvironment;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.Name;
import me.bramhaag.annotationtest.annotations.TestAnnotation;
import me.bramhaag.annotationtest.api.MethodSpec;
import me.bramhaag.annotationtest.api.util.Modifier;
import me.bramhaag.annotationtest.api.util.SpecUtil;
import me.bramhaag.annotationtest.printer.TreePrinter;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
import java.util.HashSet;
import java.util.Set;
@SupportedSourceVersion(SourceVersion.RELEASE_8)
@SupportedAnnotationTypes("me.bramhaag.annotationtest.annotations.TestAnnotation")
@AutoService(Processor.class)
public class TestProcessor extends AbstractProcessor {
private JavacProcessingEnvironment env;
private Messager messager;
@Override
public void init(ProcessingEnvironment env) {
this.env = (JavacProcessingEnvironment) env;
this.messager = env.getMessager();
JavacTask.instance(env).addTaskListener(new TaskListener() {
@Override
public void started(TaskEvent taskEvent) {
System.out.println("KIND " + taskEvent.getKind().name());
if (taskEvent.getKind() == TaskEvent.Kind.ANALYZE) {
handleAnnotations(taskEvent.getCompilationUnit());
}
}
@Override
public void finished(TaskEvent taskEvent) {
}
});
messager.printMessage(Diagnostic.Kind.NOTE, "Starting...");
super.init(env);
}
private void handleAnnotations(CompilationUnitTree compilationUnitTree) {
Trees trees = Trees.instance(env);
for (Element element : elements) {
System.out.println(element);
System.out.println(trees.getPath(element));
new TreePrinter().visit(compilationUnitTree, null);
new TestTreeTranslator(env.getContext()).translate(((JCTree.JCCompilationUnit) compilationUnitTree));
JCTree.JCClassDecl cls = (JCTree.JCClassDecl) compilationUnitTree.getTypeDecls().get(0);
JCTree.JCMethodDecl method = cls.defs.stream().filter(def -> def instanceof JCTree.JCMethodDecl)
.map(def -> ((JCTree.JCMethodDecl) def))
.filter(def -> "test".equals(def.name.toString()))
.findFirst().get();
JCTree.JCVariableDecl var = method.params.get(0);
System.out.println("Found test method, parameter is at " + var.sym.adr);
}
}
Set<Element> elements = new HashSet<>();
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
Trees trees = Trees.instance(env);
for(Element e : roundEnv.getElementsAnnotatedWith(TestAnnotation.class)) {
messager.printMessage(Diagnostic.Kind.NOTE, "Found element: " + e.getSimpleName());
if(e.getKind() != ElementKind.CLASS) {
messager.printMessage(Diagnostic.Kind.ERROR, "Cannot use annotation on anything other than a class!");
return false;
}
elements.add(e);
/* CompilationUnitTree tre = trees.getPath(e).getCompilationUnit();
new TreePrinter().visit(trees.getPath(e).getCompilationUnit(), null);
new TestTreeTranslator(env.getContext()).translate((JCTree) trees.getPath(e).getCompilationUnit());
JCTree.JCClassDecl cls = (JCTree.JCClassDecl) tre.getTypeDecls().get(0);
JCTree.JCMethodDecl method = cls.defs.stream().filter(def -> def instanceof JCTree.JCMethodDecl)
.map(def -> ((JCTree.JCMethodDecl) def))
.filter(def -> "test".equals(def.name.toString()))
.findFirst().get();
JCTree.JCVariableDecl var = method.params.get(0);
cls.sym.members_field.enter(method.sym);
System.out.println("Found test method, parameter is at " + var.sym.adr);*/
}
return false;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment