| /* |
| * Copyright 2000-2012 JetBrains s.r.o. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.jetbrains.jps.javac; |
| |
| import com.sun.source.tree.ClassTree; |
| import com.sun.source.tree.ImportTree; |
| import com.sun.source.tree.Tree; |
| import com.sun.source.util.TreeScanner; |
| import com.sun.source.util.Trees; |
| |
| import javax.annotation.processing.AbstractProcessor; |
| import javax.annotation.processing.ProcessingEnvironment; |
| import javax.annotation.processing.RoundEnvironment; |
| import javax.annotation.processing.SupportedAnnotationTypes; |
| import javax.lang.model.SourceVersion; |
| import javax.lang.model.element.Element; |
| import javax.lang.model.element.TypeElement; |
| import java.util.HashSet; |
| import java.util.Set; |
| |
| /** |
| * @author Eugene Zhuravlev |
| * Date: 2/1/12 |
| * |
| */ |
| @SupportedAnnotationTypes("*") |
| public class JavacASTAnalyser extends AbstractProcessor{ |
| private Trees myTrees; |
| private final DiagnosticOutputConsumer myOutputConsumer; |
| private final boolean mySuppressOtherProcessors; |
| |
| public JavacASTAnalyser(DiagnosticOutputConsumer outputConsumer, boolean suppressOtherProcessors) { |
| myOutputConsumer = outputConsumer; |
| mySuppressOtherProcessors = suppressOtherProcessors; |
| } |
| |
| @Override |
| public SourceVersion getSupportedSourceVersion() { |
| return SourceVersion.latest(); |
| } |
| |
| @Override |
| public void init(ProcessingEnvironment processingEnv) { |
| super.init(processingEnv); |
| myTrees = Trees.instance(processingEnv); |
| } |
| |
| @Override |
| public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { |
| final Set<? extends Element> elements = roundEnv.getRootElements(); |
| for (Element element : elements) { |
| if (!(element instanceof TypeElement)) { |
| continue; |
| } |
| final TypeElement typeElement = (TypeElement)element; |
| |
| final ImportsCollector importsCollector = new ImportsCollector(); |
| importsCollector.scan(myTrees.getPath(typeElement).getParentPath().getLeaf(), myTrees); |
| |
| final Set<String> imports = importsCollector.getImports(); |
| final Set<String> staticImports = importsCollector.getStaticImports(); |
| |
| if (!imports.isEmpty() || !staticImports.isEmpty()) { |
| final String className = typeElement.getQualifiedName().toString(); |
| myOutputConsumer.registerImports(className, imports, staticImports); |
| } |
| break; |
| } |
| return mySuppressOtherProcessors; |
| } |
| |
| private static class ImportsCollector extends TreeScanner<Object, Trees> { |
| private Set<String> myImports = new HashSet<String>(); |
| private Set<String> myStaticImports = new HashSet<String>(); |
| |
| public Set<String> getImports() { |
| return myImports; |
| } |
| |
| public Set<String> getStaticImports() { |
| return myStaticImports; |
| } |
| |
| public Object visitImport(ImportTree node, Trees trees) { |
| final Tree identifier = node.getQualifiedIdentifier(); |
| final Set<String> container = node.isStatic()? myStaticImports : myImports; |
| container.add(identifier.toString()); |
| return null; |
| } |
| |
| public Object visitClass(ClassTree node, Trees trees) { |
| return null; |
| } |
| |
| //public void registerOverriddenMethod(TypeElement classElement, ExecutableElement method) { |
| // final Elements utils = myProcessingEnvironment.getElementUtils(); |
| // final String qName = utils.getBinaryName(classElement).toString(); |
| // List<MethodDescriptor> descriptors = myOverriddenMethods.get(qName); |
| // if (descriptors == null) { |
| // descriptors = new ArrayList<MethodDescriptor>(); |
| // myOverriddenMethods.put(qName, descriptors); |
| // } |
| // final StringBuilder buf = new StringBuilder(); |
| // buf.append("("); |
| // for (VariableElement param : method.getParameters()) { |
| // buf.append(getSignature(param.asType())); |
| // } |
| // buf.append(")").append(getSignature(method.getReturnType())); |
| // descriptors.add(new MethodDescriptor(method.getSimpleName().toString(), buf.toString())); |
| //} |
| |
| //private static String getSignature(TypeMirror type) { |
| // switch (type.getKind()) { |
| // case BOOLEAN: return "Z"; |
| // case BYTE: return "B"; |
| // case CHAR: return "C"; |
| // case SHORT: return "S"; |
| // case INT: return "I"; |
| // case LONG: return "J"; |
| // case FLOAT: return "F"; |
| // case DOUBLE: return "D"; |
| // case VOID: return "V"; |
| // case ARRAY: |
| // final String signature = getSignature(((ArrayType)type).getComponentType()); |
| // return signature != null? "[" + signature : null; |
| // case DECLARED: |
| // final TypeElement typeElement = (TypeElement)((DeclaredType)type).asElement(); |
| // final String qName = typeElement.getQualifiedName().toString().replace(".", "/"); |
| // return "L" + qName + ";"; |
| // default: |
| // return null; |
| // } |
| //} |
| } |
| |
| //private static class IdentifiersCollector extends TreeScanner<Object, Trees> { |
| // private Set<Name> myIdentifiers = new HashSet<Name>(); |
| // private Set<String> myImports = new HashSet<String>(); |
| // private Set<String> myStaticImports = new HashSet<String>(); |
| // |
| // public Set<String> getIdentifiers() { |
| // final HashSet<String> result = new HashSet<String>(); |
| // for (Name name : myIdentifiers) { |
| // result.add(name.toString()); |
| // } |
| // return result; |
| // } |
| // |
| // @Override |
| // public Object visitImport(ImportTree node, Trees trees) { |
| // final Tree identifier = node.getQualifiedIdentifier(); |
| // final Set<String> container = node.isStatic()? myStaticImports : myImports; |
| // container.add(identifier.toString()); |
| // return null; |
| // } |
| // |
| // @Override |
| // public Object visitAnnotation(AnnotationTree node, Trees trees) { |
| // return scan(node.getArguments(), trees); |
| // } |
| // |
| // @Override |
| // public Object visitIdentifier(IdentifierTree node, Trees trees) { |
| // myIdentifiers.add(node.getName()); |
| // return super.visitIdentifier(node, trees); |
| // } |
| // |
| // @Override |
| // public Object visitMemberSelect(MemberSelectTree node, Trees trees) { |
| // myIdentifiers.add(node.getIdentifier()); |
| // return scan(node.getExpression(), trees); |
| // } |
| // |
| // @Override |
| // public Object visitClass(ClassTree node, Trees trees) { |
| // return scan(node.getMembers(), trees); |
| // } |
| // |
| // @Override |
| // public Object visitVariable(VariableTree node, Trees trees) { |
| // return scan(node.getInitializer(), trees); |
| // } |
| // |
| // @Override |
| // public Object visitMethod(MethodTree node, Trees trees) { |
| // return scan(node.getBody(), trees); |
| // } |
| // |
| // @Override |
| // public Object visitMethodInvocation(MethodInvocationTree node, Trees trees) { |
| // return scan(node.getArguments(), trees); |
| // } |
| // |
| // @Override |
| // public Object visitTypeCast(TypeCastTree node, Trees trees) { |
| // return scan(node.getExpression(), trees); |
| // } |
| // |
| // @Override |
| // public Object visitInstanceOf(InstanceOfTree node, Trees trees) { |
| // return scan(node.getExpression(), trees); |
| // } |
| //} |
| } |