JavacTrees.java revision 3255:7a0c34355149
1139749Simp/* 235388Smjacob * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. 335388Smjacob * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4154704Smjacob * 5154704Smjacob * This code is free software; you can redistribute it and/or modify it 635388Smjacob * under the terms of the GNU General Public License version 2 only, as 735388Smjacob * published by the Free Software Foundation. Oracle designates this 835388Smjacob * particular file as subject to the "Classpath" exception as provided 935388Smjacob * by Oracle in the LICENSE file that accompanied this code. 1035388Smjacob * 1135388Smjacob * This code is distributed in the hope that it will be useful, but WITHOUT 1235388Smjacob * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1366189Smjacob * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1466189Smjacob * version 2 for more details (a copy is included in the LICENSE file that 1535388Smjacob * accompanied this code). 1635388Smjacob * 1735388Smjacob * You should have received a copy of the GNU General Public License version 1835388Smjacob * 2 along with this work; if not, write to the Free Software Foundation, 1935388Smjacob * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2035388Smjacob * 2135388Smjacob * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2235388Smjacob * or visit www.oracle.com if you need additional information or have any 2335388Smjacob * questions. 2435388Smjacob */ 2535388Smjacob 2635388Smjacobpackage com.sun.tools.javac.api; 2735388Smjacob 28119418Sobrienimport java.io.FileNotFoundException; 29119418Sobrienimport java.io.IOException; 30119418Sobrienimport java.text.BreakIterator; 31119418Sobrienimport java.util.HashMap; 3235388Smjacobimport java.util.HashSet; 3377365Smjacobimport java.util.Map; 3477365Smjacobimport java.util.Set; 3564176Smjacobimport java.util.regex.Matcher; 3677365Smjacobimport java.util.regex.Pattern; 37100679Smjacob 3877365Smjacobimport javax.annotation.processing.ProcessingEnvironment; 3977365Smjacobimport javax.lang.model.element.AnnotationMirror; 4035388Smjacobimport javax.lang.model.element.AnnotationValue; 4175200Smjacobimport javax.lang.model.element.Element; 42100679Smjacobimport javax.lang.model.element.ElementKind; 43120088Smarkmimport javax.lang.model.element.ExecutableElement; 4499756Smjacobimport javax.lang.model.element.Modifier; 4599756Smjacobimport javax.lang.model.element.NestingKind; 4699756Smjacobimport javax.lang.model.element.PackageElement; 4777365Smjacobimport javax.lang.model.element.TypeElement; 4862498Smjacobimport javax.lang.model.type.DeclaredType; 49155704Smjacobimport javax.lang.model.type.TypeKind; 5049915Smjacobimport javax.lang.model.type.TypeMirror; 5162173Smjacobimport javax.tools.Diagnostic; 5277365Smjacobimport javax.tools.FileObject; 5349915Smjacobimport javax.tools.ForwardingFileObject; 5439235Sgibbsimport javax.tools.JavaCompiler; 5560220Smjacobimport javax.tools.JavaFileManager; 5677365Smjacobimport javax.tools.JavaFileObject; 57126080Sphkimport javax.tools.JavaFileObject.Kind; 58126080Sphkimport javax.tools.StandardLocation; 59111815Sphk 60111815Sphkimport com.sun.source.doctree.DocCommentTree; 6177365Smjacobimport com.sun.source.doctree.DocTree; 6277365Smjacobimport com.sun.source.tree.CatchTree; 6355371Smjacobimport com.sun.source.tree.CompilationUnitTree; 6449915Smjacobimport com.sun.source.tree.Scope; 6539235Sgibbsimport com.sun.source.tree.Tree; 6642131Smjacobimport com.sun.source.util.DocSourcePositions; 6739235Sgibbsimport com.sun.source.util.DocTreePath; 6846972Smjacobimport com.sun.source.util.DocTreeScanner; 6939235Sgibbsimport com.sun.source.util.DocTrees; 7039235Sgibbsimport com.sun.source.util.JavacTask; 7146972Smjacobimport com.sun.source.util.TreePath; 7246972Smjacobimport com.sun.tools.javac.code.Flags; 7339235Sgibbsimport com.sun.tools.javac.code.Scope.NamedImportScope; 7439235Sgibbsimport com.sun.tools.javac.code.Scope.StarImportScope; 7546972Smjacobimport com.sun.tools.javac.code.Scope.WriteableScope; 7639235Sgibbsimport com.sun.tools.javac.code.Symbol; 7746972Smjacobimport com.sun.tools.javac.code.Symbol.ClassSymbol; 7846972Smjacobimport com.sun.tools.javac.code.Symbol.MethodSymbol; 7946972Smjacobimport com.sun.tools.javac.code.Symbol.PackageSymbol; 8046972Smjacobimport com.sun.tools.javac.code.Symbol.TypeSymbol; 8146972Smjacobimport com.sun.tools.javac.code.Symbol.VarSymbol; 8246972Smjacobimport com.sun.tools.javac.code.Symtab; 8346972Smjacobimport com.sun.tools.javac.code.Type; 8452349Smjacobimport com.sun.tools.javac.code.Type.ArrayType; 8539235Sgibbsimport com.sun.tools.javac.code.Type.ClassType; 8639235Sgibbsimport com.sun.tools.javac.code.Type.ErrorType; 8739235Sgibbsimport com.sun.tools.javac.code.Type.UnionClassType; 8839235Sgibbsimport com.sun.tools.javac.code.Types; 8939235Sgibbsimport com.sun.tools.javac.code.Types.TypeRelation; 9046972Smjacobimport com.sun.tools.javac.comp.Attr; 9139235Sgibbsimport com.sun.tools.javac.comp.AttrContext; 9279336Smjacobimport com.sun.tools.javac.comp.Enter; 9346972Smjacobimport com.sun.tools.javac.comp.Env; 9473245Smjacobimport com.sun.tools.javac.comp.MemberEnter; 9546972Smjacobimport com.sun.tools.javac.comp.Resolve; 9639235Sgibbsimport com.sun.tools.javac.file.BaseFileManager; 9779336Smjacobimport com.sun.tools.javac.model.JavacElements; 9839235Sgibbsimport com.sun.tools.javac.parser.DocCommentParser; 9939235Sgibbsimport com.sun.tools.javac.parser.ParserFactory; 10079336Smjacobimport com.sun.tools.javac.parser.Tokens.Comment; 10162498Smjacobimport com.sun.tools.javac.parser.Tokens.Comment.CommentStyle; 10262498Smjacobimport com.sun.tools.javac.processing.JavacProcessingEnvironment; 10362498Smjacobimport com.sun.tools.javac.tree.DCTree; 10479336Smjacobimport com.sun.tools.javac.tree.DCTree.DCBlockTag; 10562498Smjacobimport com.sun.tools.javac.tree.DCTree.DCDocComment; 10679336Smjacobimport com.sun.tools.javac.tree.DCTree.DCEndPosTree; 10779336Smjacobimport com.sun.tools.javac.tree.DCTree.DCErroneous; 10869597Smjacobimport com.sun.tools.javac.tree.DCTree.DCIdentifier; 10969597Smjacobimport com.sun.tools.javac.tree.DCTree.DCParam; 11062498Smjacobimport com.sun.tools.javac.tree.DCTree.DCReference; 11162498Smjacobimport com.sun.tools.javac.tree.DCTree.DCText; 11262498Smjacobimport com.sun.tools.javac.tree.DocCommentTable; 11346972Smjacobimport com.sun.tools.javac.tree.DocTreeMaker; 11446972Smjacobimport com.sun.tools.javac.tree.EndPosTable; 11579336Smjacobimport com.sun.tools.javac.tree.JCTree; 11639235Sgibbsimport com.sun.tools.javac.tree.JCTree.JCBlock; 11739235Sgibbsimport com.sun.tools.javac.tree.JCTree.JCCatch; 11839235Sgibbsimport com.sun.tools.javac.tree.JCTree.JCClassDecl; 11946972Smjacobimport com.sun.tools.javac.tree.JCTree.JCCompilationUnit; 12039235Sgibbsimport com.sun.tools.javac.tree.JCTree.JCExpression; 12146972Smjacobimport com.sun.tools.javac.tree.JCTree.JCIdent; 12246972Smjacobimport com.sun.tools.javac.tree.JCTree.JCMethodDecl; 12377365Smjacobimport com.sun.tools.javac.tree.JCTree.JCVariableDecl; 12479336Smjacobimport com.sun.tools.javac.tree.TreeCopier; 12539235Sgibbsimport com.sun.tools.javac.tree.TreeInfo; 12639235Sgibbsimport com.sun.tools.javac.tree.TreeMaker; 12739235Sgibbsimport com.sun.tools.javac.util.Abort; 12846972Smjacobimport com.sun.tools.javac.util.Assert; 12939235Sgibbsimport com.sun.tools.javac.util.Context; 13039235Sgibbsimport com.sun.tools.javac.util.DefinedBy; 13143420Smjacobimport com.sun.tools.javac.util.DefinedBy.Api; 13246972Smjacobimport com.sun.tools.javac.util.DiagnosticSource; 13339235Sgibbsimport com.sun.tools.javac.util.JCDiagnostic; 13479336Smjacobimport com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag; 13546972Smjacobimport com.sun.tools.javac.util.List; 13646972Smjacobimport com.sun.tools.javac.util.ListBuffer; 13777365Smjacobimport com.sun.tools.javac.util.Log; 13877365Smjacobimport com.sun.tools.javac.util.Name; 13977365Smjacobimport com.sun.tools.javac.util.Names; 14077365Smjacobimport com.sun.tools.javac.util.Pair; 14177365Smjacobimport com.sun.tools.javac.util.Position; 14279336Smjacob 14379336Smjacobimport static com.sun.tools.javac.code.Kinds.Kind.*; 14477365Smjacobimport static com.sun.tools.javac.code.TypeTag.*; 14577365Smjacob 146104354Sscottl/** 14777365Smjacob * Provides an implementation of Trees. 14877365Smjacob * 14977365Smjacob * <p><b>This is NOT part of any supported API. 15077365Smjacob * If you write code that depends on this, you do so at your own 15179336Smjacob * risk. This code and its internal interfaces are subject to change 15279336Smjacob * or deletion without notice.</b></p> 15377365Smjacob * 15477365Smjacob * @author Peter von der Ahé 15579338Smjacob */ 15677365Smjacobpublic class JavacTrees extends DocTrees { 15739235Sgibbs 15877365Smjacob // in a world of a single context per compilation, these would all be final 15946972Smjacob private Resolve resolve; 16046972Smjacob private Enter enter; 16146972Smjacob private Log log; 16254671Smjacob private MemberEnter memberEnter; 16379336Smjacob private Attr attr; 16446972Smjacob private TreeMaker treeMaker; 16573245Smjacob private JavacElements elements; 16646972Smjacob private JavacTaskImpl javacTaskImpl; 16746972Smjacob private Names names; 16846972Smjacob private Types types; 16946972Smjacob private DocTreeMaker docTreeMaker; 17077365Smjacob private BreakIterator breakIterator; 17146972Smjacob private JavaFileManager fileManager; 17246972Smjacob private ParserFactory parser; 17346972Smjacob private Symtab syms; 17446972Smjacob private Map<JavaFileObject, PackageSymbol> javaFileObjectToPackageMap; 17546972Smjacob 17646972Smjacob // called reflectively from Trees.instance(CompilationTask task) 17777365Smjacob public static JavacTrees instance(JavaCompiler.CompilationTask task) { 17879336Smjacob if (!(task instanceof BasicJavacTask)) 17946972Smjacob throw new IllegalArgumentException(); 18046972Smjacob return instance(((BasicJavacTask)task).getContext()); 18146972Smjacob } 18246972Smjacob 18346972Smjacob // called reflectively from Trees.instance(ProcessingEnvironment env) 18446972Smjacob public static JavacTrees instance(ProcessingEnvironment env) { 18546972Smjacob if (!(env instanceof JavacProcessingEnvironment)) 18646972Smjacob throw new IllegalArgumentException(); 18746972Smjacob return instance(((JavacProcessingEnvironment)env).getContext()); 18877365Smjacob } 18979336Smjacob 19046972Smjacob public static JavacTrees instance(Context context) { 19146972Smjacob JavacTrees instance = context.get(JavacTrees.class); 19246972Smjacob if (instance == null) 19346972Smjacob instance = new JavacTrees(context); 19446972Smjacob return instance; 19546972Smjacob } 19646972Smjacob 19746972Smjacob protected JavacTrees(Context context) { 19846972Smjacob javaFileObjectToPackageMap = new HashMap<>(); 19979336Smjacob this.breakIterator = null; 20046972Smjacob context.put(JavacTrees.class, this); 20146972Smjacob init(context); 20246972Smjacob } 20377365Smjacob 20477365Smjacob public void updateContext(Context context) { 20577365Smjacob init(context); 20677365Smjacob } 20777365Smjacob 20877365Smjacob private void init(Context context) { 20977365Smjacob attr = Attr.instance(context); 21072347Smjacob enter = Enter.instance(context); 21172347Smjacob elements = JavacElements.instance(context); 21272347Smjacob log = Log.instance(context); 21372347Smjacob resolve = Resolve.instance(context); 21455371Smjacob treeMaker = TreeMaker.instance(context); 21555371Smjacob memberEnter = MemberEnter.instance(context); 21655371Smjacob names = Names.instance(context); 21755371Smjacob types = Types.instance(context); 21855371Smjacob docTreeMaker = DocTreeMaker.instance(context); 21955371Smjacob parser = ParserFactory.instance(context); 22055371Smjacob syms = Symtab.instance(context); 22155371Smjacob fileManager = context.get(JavaFileManager.class); 22249915Smjacob JavacTask t = context.get(JavacTask.class); 22377365Smjacob if (t instanceof JavacTaskImpl) 22439235Sgibbs javacTaskImpl = (JavacTaskImpl) t; 22539235Sgibbs } 226155228Smjacob 22799598Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 22899598Smjacob public BreakIterator getBreakIterator() { 22999598Smjacob return breakIterator; 23099598Smjacob } 23199598Smjacob 23299598Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 23399598Smjacob public DocSourcePositions getSourcePositions() { 23499598Smjacob return new DocSourcePositions() { 23599598Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 23699598Smjacob public long getStartPosition(CompilationUnitTree file, Tree tree) { 23799598Smjacob return TreeInfo.getStartPos((JCTree) tree); 23899598Smjacob } 23999598Smjacob 24099598Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 24177365Smjacob public long getEndPosition(CompilationUnitTree file, Tree tree) { 242130585Sphk EndPosTable endPosTable = ((JCCompilationUnit) file).endPositions; 24377365Smjacob return TreeInfo.getEndPos((JCTree) tree, endPosTable); 24477365Smjacob } 245125549Smjacob 24677365Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 24777365Smjacob public long getStartPosition(CompilationUnitTree file, DocCommentTree comment, DocTree tree) { 24877365Smjacob return ((DCTree) tree).getSourcePosition((DCDocComment) comment); 24977365Smjacob } 25077365Smjacob @Override @DefinedBy(Api.COMPILER_TREE) @SuppressWarnings("fallthrough") 25177365Smjacob public long getEndPosition(CompilationUnitTree file, DocCommentTree comment, DocTree tree) { 25277365Smjacob DCDocComment dcComment = (DCDocComment) comment; 25377365Smjacob if (tree instanceof DCEndPosTree) { 25477365Smjacob int endPos = ((DCEndPosTree) tree).getEndPos(dcComment); 25577365Smjacob 25677365Smjacob if (endPos != Position.NOPOS) { 25777365Smjacob return endPos; 25890813Smjacob } 25990813Smjacob } 26090813Smjacob int correction = 0; 261155704Smjacob switch (tree.getKind()) { 26290813Smjacob case TEXT: 26390813Smjacob DCText text = (DCText) tree; 26490813Smjacob 26590813Smjacob return dcComment.comment.getSourcePos(text.pos + text.text.length()); 26690813Smjacob case ERRONEOUS: 26790813Smjacob DCErroneous err = (DCErroneous) tree; 26890813Smjacob 26990813Smjacob return dcComment.comment.getSourcePos(err.pos + err.body.length()); 27090813Smjacob case IDENTIFIER: 27190813Smjacob DCIdentifier ident = (DCIdentifier) tree; 27290813Smjacob 27390813Smjacob return dcComment.comment.getSourcePos(ident.pos + (ident.name != names.error ? ident.name.length() : 0)); 27490813Smjacob case PARAM: 27590813Smjacob DCParam param = (DCParam) tree; 27690813Smjacob 27790813Smjacob if (param.isTypeParameter && param.getDescription().isEmpty()) { 27890813Smjacob correction = 1; 27990813Smjacob } 28090813Smjacob case AUTHOR: case DEPRECATED: case RETURN: case SEE: 28190813Smjacob case SERIAL: case SERIAL_DATA: case SERIAL_FIELD: case SINCE: 28290813Smjacob case THROWS: case UNKNOWN_BLOCK_TAG: case VERSION: { 28390813Smjacob DocTree last = getLastChild(tree); 28490813Smjacob 28590813Smjacob if (last != null) { 28699598Smjacob return getEndPosition(file, comment, last) + correction; 28790813Smjacob } 28890813Smjacob 28990813Smjacob DCBlockTag block = (DCBlockTag) tree; 29090813Smjacob 29190813Smjacob return dcComment.comment.getSourcePos(block.pos + block.getTagName().length() + 1); 29290813Smjacob } 29377365Smjacob default: 29477365Smjacob DocTree last = getLastChild(tree); 29577365Smjacob 29677365Smjacob if (last != null) { 29777365Smjacob return getEndPosition(file, comment, last); 29877365Smjacob } 29977365Smjacob break; 30077365Smjacob } 301125549Smjacob 302125549Smjacob return Position.NOPOS; 303125549Smjacob } 304125549Smjacob }; 305125549Smjacob } 306125549Smjacob 307125549Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 308125549Smjacob public DocTreeMaker getDocTreeFactory() { 309125549Smjacob return docTreeMaker; 310125549Smjacob } 311125549Smjacob 312125549Smjacob private DocTree getLastChild(DocTree tree) { 313125549Smjacob final DocTree[] last = new DocTree[] {null}; 31477365Smjacob 31577365Smjacob tree.accept(new DocTreeScanner<Void, Void>() { 31677365Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 31777365Smjacob public Void scan(DocTree node, Void p) { 31877365Smjacob if (node != null) last[0] = node; 31977365Smjacob return null; 32091036Smjacob } 32177365Smjacob }, null); 32277365Smjacob 32377365Smjacob return last[0]; 32477365Smjacob } 32577365Smjacob 32677365Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 32777365Smjacob public JCClassDecl getTree(TypeElement element) { 32877365Smjacob return (JCClassDecl) getTree((Element) element); 32977365Smjacob } 33077365Smjacob 33177365Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 33277365Smjacob public JCMethodDecl getTree(ExecutableElement method) { 33377365Smjacob return (JCMethodDecl) getTree((Element) method); 33477365Smjacob } 33577365Smjacob 33677365Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 33777365Smjacob public JCTree getTree(Element element) { 33877365Smjacob return getTree(element, null); 33977365Smjacob } 34077365Smjacob 34177365Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 34277365Smjacob public JCTree getTree(Element e, AnnotationMirror a) { 34377365Smjacob return getTree(e, a, null); 34477365Smjacob } 34577365Smjacob 34677365Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 34777365Smjacob public JCTree getTree(Element e, AnnotationMirror a, AnnotationValue v) { 34877365Smjacob Pair<JCTree, JCCompilationUnit> treeTopLevel = elements.getTreeAndTopLevel(e, a, v); 34977365Smjacob if (treeTopLevel == null) 35077365Smjacob return null; 35177365Smjacob return treeTopLevel.fst; 35277365Smjacob } 35377365Smjacob 354156040Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 35577365Smjacob public TreePath getPath(CompilationUnitTree unit, Tree node) { 35677365Smjacob return TreePath.getPath(unit, node); 35777365Smjacob } 35877365Smjacob 35977365Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 36077365Smjacob public TreePath getPath(Element e) { 36177365Smjacob return getPath(e, null, null); 36277365Smjacob } 36377365Smjacob 36477365Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 36577365Smjacob public TreePath getPath(Element e, AnnotationMirror a) { 36688855Smjacob return getPath(e, a, null); 36788855Smjacob } 36888855Smjacob 36988855Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 37088855Smjacob public TreePath getPath(Element e, AnnotationMirror a, AnnotationValue v) { 37188855Smjacob final Pair<JCTree, JCCompilationUnit> treeTopLevel = elements.getTreeAndTopLevel(e, a, v); 37288855Smjacob if (treeTopLevel == null) 37388855Smjacob return null; 37488855Smjacob return TreePath.getPath(treeTopLevel.snd, treeTopLevel.fst); 37588855Smjacob } 37688855Smjacob 37788855Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 37888855Smjacob public Symbol getElement(TreePath path) { 37988855Smjacob JCTree tree = (JCTree) path.getLeaf(); 38088855Smjacob Symbol sym = TreeInfo.symbolFor(tree); 38188855Smjacob if (sym == null) { 38288855Smjacob if (TreeInfo.isDeclaration(tree)) { 38388855Smjacob for (TreePath p = path; p != null; p = p.getParentPath()) { 38488855Smjacob JCTree t = (JCTree) p.getLeaf(); 38588855Smjacob if (t.hasTag(JCTree.Tag.CLASSDEF)) { 38688855Smjacob JCClassDecl ct = (JCClassDecl) t; 38788855Smjacob if (ct.sym != null) { 38888855Smjacob if ((ct.sym.flags_field & Flags.UNATTRIBUTED) != 0) { 38988855Smjacob attr.attribClass(ct.pos(), ct.sym); 39088855Smjacob sym = TreeInfo.symbolFor(tree); 39188855Smjacob } 39288855Smjacob break; 39388855Smjacob } 39488855Smjacob } 39588855Smjacob } 39688855Smjacob } 39788855Smjacob } 39888855Smjacob return sym; 39988855Smjacob } 40098289Smjacob 40198289Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 40298289Smjacob public Element getElement(DocTreePath path) { 40398289Smjacob DocTree forTree = path.getLeaf(); 40498289Smjacob if (forTree instanceof DCReference) 405124892Smjacob return attributeDocReference(path.getTreePath(), ((DCReference) forTree)); 406124892Smjacob if (forTree instanceof DCIdentifier) { 407124892Smjacob if (path.getParentPath().getLeaf() instanceof DCParam) { 40898289Smjacob return attributeParamIdentifier(path.getTreePath(), (DCParam) path.getParentPath().getLeaf()); 40998289Smjacob } 41098289Smjacob } 41198289Smjacob return null; 412120013Smjacob } 413120013Smjacob 414120013Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 415120013Smjacob public java.util.List<DocTree> getFirstSentence(java.util.List<? extends DocTree> list) { 41698289Smjacob return docTreeMaker.getFirstSentence(list); 41798289Smjacob } 41898289Smjacob 41998289Smjacob private Symbol attributeDocReference(TreePath path, DCReference ref) { 42099598Smjacob Env<AttrContext> env = getAttrContext(path); 42199598Smjacob 42299598Smjacob Log.DeferredDiagnosticHandler deferredDiagnosticHandler = 42399598Smjacob new Log.DeferredDiagnosticHandler(log); 42499598Smjacob try { 42599598Smjacob final TypeSymbol tsym; 42699598Smjacob final Name memberName; 42799598Smjacob if (ref.qualifierExpression == null) { 42899598Smjacob tsym = env.enclClass.sym; 42999598Smjacob memberName = (Name) ref.memberName; 43099598Smjacob } else { 43199598Smjacob // newSeeTree if the qualifierExpression is a type or package name. 43299598Smjacob // javac does not provide the exact method required, so 43399598Smjacob // we first check if qualifierExpression identifies a type, 43499598Smjacob // and if not, then we check to see if it identifies a package. 43599598Smjacob Type t = attr.attribType(ref.qualifierExpression, env); 43699598Smjacob if (t.isErroneous()) { 43799598Smjacob if (ref.memberName == null) { 43899598Smjacob // Attr/Resolve assume packages exist and create symbols as needed 43999598Smjacob // so use getPackageElement to restrict search to existing packages 44099598Smjacob PackageSymbol pck = elements.getPackageElement(ref.qualifierExpression.toString()); 44199598Smjacob if (pck != null) { 44299598Smjacob return pck; 44399598Smjacob } else if (ref.qualifierExpression.hasTag(JCTree.Tag.IDENT)) { 44499598Smjacob // fixup: allow "identifier" instead of "#identifier" 44599598Smjacob // for compatibility with javadoc 44699598Smjacob tsym = env.enclClass.sym; 44799598Smjacob memberName = ((JCIdent) ref.qualifierExpression).name; 44899598Smjacob } else 44999598Smjacob return null; 45099598Smjacob } else { 45199598Smjacob return null; 45299598Smjacob } 45399598Smjacob } else { 45499598Smjacob tsym = t.tsym; 45599598Smjacob memberName = (Name) ref.memberName; 456155704Smjacob } 45799598Smjacob } 45899598Smjacob 45999598Smjacob if (memberName == null) 46099598Smjacob return tsym; 46199598Smjacob 46299598Smjacob final List<Type> paramTypes; 46399598Smjacob if (ref.paramTypes == null) 46499598Smjacob paramTypes = null; 46599598Smjacob else { 46699598Smjacob ListBuffer<Type> lb = new ListBuffer<>(); 46799598Smjacob for (List<JCTree> l = (List<JCTree>) ref.paramTypes; l.nonEmpty(); l = l.tail) { 46899598Smjacob JCTree tree = l.head; 46999598Smjacob Type t = attr.attribType(tree, env); 47099598Smjacob lb.add(t); 47199598Smjacob } 47299598Smjacob paramTypes = lb.toList(); 47399598Smjacob } 47499598Smjacob 47599598Smjacob ClassSymbol sym = (ClassSymbol) types.cvarUpperBound(tsym.type).tsym; 47699598Smjacob 47799598Smjacob Symbol msym = (memberName == sym.name) 47899598Smjacob ? findConstructor(sym, paramTypes) 47999598Smjacob : findMethod(sym, memberName, paramTypes); 48099598Smjacob if (paramTypes != null) { 48199598Smjacob // explicit (possibly empty) arg list given, so cannot be a field 48299598Smjacob return msym; 48399598Smjacob } 48499598Smjacob 48599598Smjacob VarSymbol vsym = (ref.paramTypes != null) ? null : findField(sym, memberName); 48699598Smjacob // prefer a field over a method with no parameters 48799598Smjacob if (vsym != null && 48899598Smjacob (msym == null || 48999598Smjacob types.isSubtypeUnchecked(vsym.enclClass().asType(), msym.enclClass().asType()))) { 49099598Smjacob return vsym; 49199598Smjacob } else { 49299598Smjacob return msym; 49399598Smjacob } 49499598Smjacob } catch (Abort e) { // may be thrown by Check.completionError in case of bad class file 49599598Smjacob return null; 49699598Smjacob } finally { 49799598Smjacob log.popDiagnosticHandler(deferredDiagnosticHandler); 49899598Smjacob } 49999598Smjacob } 50099598Smjacob 50199598Smjacob private Symbol attributeParamIdentifier(TreePath path, DCParam ptag) { 50299598Smjacob Symbol javadocSymbol = getElement(path); 50399598Smjacob if (javadocSymbol == null) 50499598Smjacob return null; 50599598Smjacob ElementKind kind = javadocSymbol.getKind(); 50699598Smjacob List<? extends Symbol> params = List.nil(); 50799598Smjacob if (kind == ElementKind.METHOD || kind == ElementKind.CONSTRUCTOR) { 508151834Smjacob MethodSymbol ee = (MethodSymbol) javadocSymbol; 509151834Smjacob params = ptag.isTypeParameter() 510151834Smjacob ? ee.getTypeParameters() 511151834Smjacob : ee.getParameters(); 512155704Smjacob } else if (kind.isClass() || kind.isInterface()) { 513151834Smjacob ClassSymbol te = (ClassSymbol) javadocSymbol; 514151834Smjacob params = te.getTypeParameters(); 515151834Smjacob } 516151834Smjacob 517151834Smjacob for (Symbol param : params) { 518151834Smjacob if (param.getSimpleName() == ptag.getName().getName()) { 519151834Smjacob return param; 520151834Smjacob } 521151834Smjacob } 522154704Smjacob return null; 523154704Smjacob } 524154704Smjacob 525154704Smjacob /** @see com.sun.tools.javadoc.ClassDocImpl#findField */ 526151834Smjacob private VarSymbol findField(ClassSymbol tsym, Name fieldName) { 527151834Smjacob return searchField(tsym, fieldName, new HashSet<>()); 528151834Smjacob } 529154704Smjacob 530151834Smjacob /** @see com.sun.tools.javadoc.ClassDocImpl#searchField */ 531151834Smjacob private VarSymbol searchField(ClassSymbol tsym, Name fieldName, Set<ClassSymbol> searched) { 532151834Smjacob if (searched.contains(tsym)) { 533151834Smjacob return null; 534154704Smjacob } 535151834Smjacob searched.add(tsym); 536151834Smjacob 537151834Smjacob for (Symbol sym : tsym.members().getSymbolsByName(fieldName)) { 538151834Smjacob if (sym.kind == VAR) { 539154704Smjacob return (VarSymbol)sym; 540151834Smjacob } 541151834Smjacob } 542151834Smjacob 543151834Smjacob //### If we found a VarSymbol above, but which did not pass 544151834Smjacob //### the modifier filter, we should return failure here! 545154704Smjacob 546151834Smjacob ClassSymbol encl = tsym.owner.enclClass(); 547151834Smjacob if (encl != null) { 548151834Smjacob VarSymbol vsym = searchField(encl, fieldName, searched); 549151834Smjacob if (vsym != null) { 550151834Smjacob return vsym; 551154704Smjacob } 552151834Smjacob } 553151834Smjacob 554151834Smjacob // search superclass 555151834Smjacob Type superclass = tsym.getSuperclass(); 556151834Smjacob if (superclass.tsym != null) { 557151834Smjacob VarSymbol vsym = searchField((ClassSymbol) superclass.tsym, fieldName, searched); 558151834Smjacob if (vsym != null) { 559151834Smjacob return vsym; 560151834Smjacob } 561151834Smjacob } 562151834Smjacob 563151834Smjacob // search interfaces 564151834Smjacob List<Type> intfs = tsym.getInterfaces(); 565151834Smjacob for (List<Type> l = intfs; l.nonEmpty(); l = l.tail) { 566151834Smjacob Type intf = l.head; 567151834Smjacob if (intf.isErroneous()) continue; 568151834Smjacob VarSymbol vsym = searchField((ClassSymbol) intf.tsym, fieldName, searched); 569151834Smjacob if (vsym != null) { 570151834Smjacob return vsym; 57177365Smjacob } 57277365Smjacob } 57377365Smjacob 57477365Smjacob return null; 57577365Smjacob } 57677365Smjacob 57762498Smjacob /** @see com.sun.tools.javadoc.ClassDocImpl#findConstructor */ 57862498Smjacob MethodSymbol findConstructor(ClassSymbol tsym, List<Type> paramTypes) { 57962498Smjacob for (Symbol sym : tsym.members().getSymbolsByName(names.init)) { 58062498Smjacob if (sym.kind == MTH) { 58172347Smjacob if (hasParameterTypes((MethodSymbol) sym, paramTypes)) { 58272347Smjacob return (MethodSymbol) sym; 583134224Smjacob } 58472347Smjacob } 585134224Smjacob } 58672347Smjacob return null; 58762498Smjacob } 58862498Smjacob 58962498Smjacob /** @see com.sun.tools.javadoc.ClassDocImpl#findMethod */ 59055371Smjacob private MethodSymbol findMethod(ClassSymbol tsym, Name methodName, List<Type> paramTypes) { 59155371Smjacob return searchMethod(tsym, methodName, paramTypes, new HashSet<>()); 59255371Smjacob } 59355371Smjacob 59455371Smjacob /** @see com.sun.tools.javadoc.ClassDocImpl#searchMethod */ 59555371Smjacob private MethodSymbol searchMethod(ClassSymbol tsym, Name methodName, 59655371Smjacob List<Type> paramTypes, Set<ClassSymbol> searched) { 597155228Smjacob //### Note that this search is not necessarily what the compiler would do! 598155228Smjacob 599155228Smjacob // do not match constructors 600155228Smjacob if (methodName == names.init) 601155228Smjacob return null; 60255371Smjacob 60375200Smjacob if (searched.contains(tsym)) 60455371Smjacob return null; 605125597Smjacob searched.add(tsym); 606125597Smjacob 60755371Smjacob // search current class 60875200Smjacob 60975200Smjacob //### Using modifier filter here isn't really correct, 61075200Smjacob //### but emulates the old behavior. Instead, we should 61155371Smjacob //### apply the normal rules of visibility and inheritance. 61255371Smjacob 61355371Smjacob if (paramTypes == null) { 61455371Smjacob // If no parameters specified, we are allowed to return 61598289Smjacob // any method with a matching name. In practice, the old 61698289Smjacob // code returned the first method, which is now the last! 61755371Smjacob // In order to provide textually identical results, we 618155228Smjacob // attempt to emulate the old behavior. 61975200Smjacob MethodSymbol lastFound = null; 62055371Smjacob for (Symbol sym : tsym.members().getSymbolsByName(methodName)) { 62155371Smjacob if (sym.kind == MTH) { 62275200Smjacob if (sym.name == methodName) { 62375200Smjacob lastFound = (MethodSymbol)sym; 62455371Smjacob } 62555371Smjacob } 62655371Smjacob } 62775200Smjacob if (lastFound != null) { 62855371Smjacob return lastFound; 62955371Smjacob } 63055371Smjacob } else { 63155371Smjacob for (Symbol sym : tsym.members().getSymbolsByName(methodName)) { 63255371Smjacob if (sym != null && 63355371Smjacob sym.kind == MTH) { 634155228Smjacob if (hasParameterTypes((MethodSymbol) sym, paramTypes)) { 63575200Smjacob return (MethodSymbol) sym; 63655371Smjacob } 63775200Smjacob } 63875200Smjacob } 63975200Smjacob } 64075200Smjacob 64175200Smjacob //### If we found a MethodSymbol above, but which did not pass 64275200Smjacob //### the modifier filter, we should return failure here! 64375200Smjacob 64475200Smjacob // search superclass 64575200Smjacob Type superclass = tsym.getSuperclass(); 64675200Smjacob if (superclass.tsym != null) { 64755371Smjacob MethodSymbol msym = searchMethod((ClassSymbol) superclass.tsym, methodName, paramTypes, searched); 64855371Smjacob if (msym != null) { 64955371Smjacob return msym; 65055371Smjacob } 65155371Smjacob } 65255371Smjacob 653155228Smjacob // search interfaces 65475200Smjacob List<Type> intfs = tsym.getInterfaces(); 65555371Smjacob for (List<Type> l = intfs; l.nonEmpty(); l = l.tail) { 65683028Smjacob Type intf = l.head; 65755371Smjacob if (intf.isErroneous()) continue; 65855371Smjacob MethodSymbol msym = searchMethod((ClassSymbol) intf.tsym, methodName, paramTypes, searched); 65983028Smjacob if (msym != null) { 66082689Smjacob return msym; 66182689Smjacob } 66282689Smjacob } 66382689Smjacob 664125597Smjacob // search enclosing class 66555371Smjacob ClassSymbol encl = tsym.owner.enclClass(); 66675200Smjacob if (encl != null) { 66783028Smjacob MethodSymbol msym = searchMethod(encl, methodName, paramTypes, searched); 66883028Smjacob if (msym != null) { 66983028Smjacob return msym; 67055371Smjacob } 67155371Smjacob } 67255371Smjacob 67375200Smjacob return null; 67455371Smjacob } 67555371Smjacob 67655371Smjacob /** @see com.sun.tools.javadoc.ClassDocImpl */ 67755371Smjacob private boolean hasParameterTypes(MethodSymbol method, List<Type> paramTypes) { 67855371Smjacob if (paramTypes == null) 67955371Smjacob return true; 68055371Smjacob 681155228Smjacob if (method.params().size() != paramTypes.size()) 68255371Smjacob return false; 68355371Smjacob 68455371Smjacob List<Type> methodParamTypes = types.erasureRecursive(method.asType()).getParameterTypes(); 68555371Smjacob 68655371Smjacob return (Type.isErroneous(paramTypes)) 68755371Smjacob ? fuzzyMatch(paramTypes, methodParamTypes) 688155228Smjacob : types.isSameTypes(paramTypes, methodParamTypes); 68984242Smjacob } 69084242Smjacob 69184242Smjacob boolean fuzzyMatch(List<Type> paramTypes, List<Type> methodParamTypes) { 69284242Smjacob List<Type> l1 = paramTypes; 69384242Smjacob List<Type> l2 = methodParamTypes; 69484242Smjacob while (l1.nonEmpty()) { 69584242Smjacob if (!fuzzyMatch(l1.head, l2.head)) 69684242Smjacob return false; 69784242Smjacob l1 = l1.tail; 69884242Smjacob l2 = l2.tail; 69984242Smjacob } 70055371Smjacob return true; 70175200Smjacob } 70275200Smjacob 70355371Smjacob boolean fuzzyMatch(Type paramType, Type methodParamType) { 70455371Smjacob Boolean b = fuzzyMatcher.visit(paramType, methodParamType); 70555371Smjacob return (b == Boolean.TRUE); 70675200Smjacob } 70755371Smjacob 70855371Smjacob TypeRelation fuzzyMatcher = new TypeRelation() { 70955371Smjacob @Override 71055371Smjacob public Boolean visitType(Type t, Type s) { 71155371Smjacob if (t == s) 71255371Smjacob return true; 71375200Smjacob 71455371Smjacob if (s.isPartial()) 71555371Smjacob return visit(s, t); 71669557Sdwmalone 71755371Smjacob switch (t.getTag()) { 71855371Smjacob case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT: 71955371Smjacob case DOUBLE: case BOOLEAN: case VOID: case BOT: case NONE: 72055371Smjacob return t.hasTag(s.getTag()); 72155371Smjacob default: 72255371Smjacob throw new AssertionError("fuzzyMatcher " + t.getTag()); 72355371Smjacob } 72455371Smjacob } 72555371Smjacob 72655371Smjacob @Override 72775200Smjacob public Boolean visitArrayType(ArrayType t, Type s) { 72855371Smjacob if (t == s) 72955371Smjacob return true; 73055371Smjacob 73155371Smjacob if (s.isPartial()) 73255371Smjacob return visit(s, t); 73375200Smjacob 73475200Smjacob return s.hasTag(ARRAY) 73575200Smjacob && visit(t.elemtype, types.elemtype(s)); 73675200Smjacob } 73755371Smjacob 73855371Smjacob @Override 73955371Smjacob public Boolean visitClassType(ClassType t, Type s) { 74055371Smjacob if (t == s) 74155371Smjacob return true; 74255371Smjacob 74355371Smjacob if (s.isPartial()) 74455371Smjacob return visit(s, t); 74555371Smjacob 746155228Smjacob return t.tsym == s.tsym; 74755371Smjacob } 74855371Smjacob 74975200Smjacob @Override 75055371Smjacob public Boolean visitErrorType(ErrorType t, Type s) { 75155371Smjacob return s.hasTag(CLASS) 75255371Smjacob && t.tsym.name == ((ClassType) s).tsym.name; 75355371Smjacob } 75455371Smjacob }; 755125597Smjacob 75675200Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 75755371Smjacob public TypeMirror getTypeMirror(TreePath path) { 75855371Smjacob Tree t = path.getLeaf(); 75975200Smjacob Type ty = ((JCTree)t).type; 76075200Smjacob return ty == null ? null : ty.stripMetadataIfNeeded(); 76155371Smjacob } 76255371Smjacob 76355371Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 76455371Smjacob public JavacScope getScope(TreePath path) { 76575200Smjacob return JavacScope.create(getAttrContext(path)); 76655371Smjacob } 76755371Smjacob 76855371Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 76955371Smjacob public String getDocComment(TreePath path) { 77055371Smjacob CompilationUnitTree t = path.getCompilationUnit(); 77155371Smjacob Tree leaf = path.getLeaf(); 77255371Smjacob if (t instanceof JCTree.JCCompilationUnit && leaf instanceof JCTree) { 77355371Smjacob JCCompilationUnit cu = (JCCompilationUnit) t; 77455371Smjacob if (cu.docComments != null) { 77555371Smjacob return cu.docComments.getCommentText((JCTree) leaf); 77655371Smjacob } 77755371Smjacob } 77855371Smjacob return null; 77977365Smjacob } 780125597Smjacob 78177365Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 782125597Smjacob public DocCommentTree getDocCommentTree(TreePath path) { 78355371Smjacob CompilationUnitTree t = path.getCompilationUnit(); 78455371Smjacob Tree leaf = path.getLeaf(); 78555371Smjacob if (t instanceof JCTree.JCCompilationUnit && leaf instanceof JCTree) { 78655371Smjacob JCCompilationUnit cu = (JCCompilationUnit) t; 787155704Smjacob if (cu.docComments != null) { 788125549Smjacob return cu.docComments.getCommentTree((JCTree) leaf); 78955371Smjacob } 79055371Smjacob } 79155371Smjacob return null; 792125597Smjacob } 793125597Smjacob 794125597Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 795125597Smjacob public DocCommentTree getDocCommentTree(Element e) { 796125597Smjacob TreePath path = getPath(e); 797125597Smjacob if (path == null) { 798125597Smjacob return null; 79955371Smjacob } 80055371Smjacob return getDocCommentTree(path); 80155371Smjacob } 802125597Smjacob 803125597Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 804125597Smjacob public DocCommentTree getDocCommentTree(Element e, String relativeFileName) throws IOException { 80565140Smjacob PackageElement pkg = elements.getPackageOf(e); 806125597Smjacob FileObject fileForInput = fileManager.getFileForInput(StandardLocation.SOURCE_PATH, 80772347Smjacob pkg.getQualifiedName().toString(), relativeFileName); 80872347Smjacob 80965140Smjacob if (fileForInput == null) { 810125597Smjacob throw new FileNotFoundException(relativeFileName); 81165140Smjacob } 81283028Smjacob return getDocCommentTree(fileForInput); 81365140Smjacob } 81475200Smjacob 81575200Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 81665140Smjacob public boolean isAccessible(Scope scope, TypeElement type) { 81775200Smjacob if (scope instanceof JavacScope && type instanceof ClassSymbol) { 81865140Smjacob Env<AttrContext> env = ((JavacScope) scope).env; 819125597Smjacob return resolve.isAccessible(env, (ClassSymbol)type, true); 82065140Smjacob } else 82165140Smjacob return false; 822125549Smjacob } 823125549Smjacob 824125549Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 825125549Smjacob public boolean isAccessible(Scope scope, Element member, DeclaredType type) { 826125549Smjacob if (scope instanceof JavacScope 82765140Smjacob && member instanceof Symbol 82872347Smjacob && type instanceof com.sun.tools.javac.code.Type) { 82965140Smjacob Env<AttrContext> env = ((JavacScope) scope).env; 830125597Smjacob return resolve.isAccessible(env, (com.sun.tools.javac.code.Type)type, (Symbol)member, true); 83165140Smjacob } else 832125549Smjacob return false; 83383028Smjacob } 83483028Smjacob 83583028Smjacob private Env<AttrContext> getAttrContext(TreePath path) { 83683028Smjacob if (!(path.getLeaf() instanceof JCTree)) // implicit null-check 83783028Smjacob throw new IllegalArgumentException(); 83883028Smjacob 83983028Smjacob // if we're being invoked from a Tree API client via parse/enter/analyze, 840125597Smjacob // we need to make sure all the classes have been entered; 84172347Smjacob // if we're being invoked from JSR 199 or JSR 269, then the classes 84283028Smjacob // will already have been entered. 84383028Smjacob if (javacTaskImpl != null) { 84483028Smjacob javacTaskImpl.enter(null); 84583028Smjacob } 84683028Smjacob 84783028Smjacob JCCompilationUnit unit = (JCCompilationUnit) path.getCompilationUnit(); 84883028Smjacob Copier copier = createCopier(treeMaker.forToplevel(unit)); 849125549Smjacob 850125597Smjacob Env<AttrContext> env = null; 85165140Smjacob JCMethodDecl method = null; 85265140Smjacob JCVariableDecl field = null; 85365140Smjacob 85483028Smjacob List<Tree> l = List.nil(); 85583028Smjacob TreePath p = path; 85683028Smjacob while (p != null) { 85783028Smjacob l = l.prepend(p.getLeaf()); 85883028Smjacob p = p.getParentPath(); 859125597Smjacob } 86055371Smjacob 86182689Smjacob for ( ; l.nonEmpty(); l = l.tail) { 86282689Smjacob Tree tree = l.head; 86382689Smjacob switch (tree.getKind()) { 86455371Smjacob case COMPILATION_UNIT: 865125549Smjacob// System.err.println("COMP: " + ((JCCompilationUnit)tree).sourcefile); 866125549Smjacob env = enter.getTopLevelEnv((JCCompilationUnit)tree); 86755371Smjacob break; 86855371Smjacob case ANNOTATION_TYPE: 86983028Smjacob case CLASS: 87083028Smjacob case ENUM: 87183028Smjacob case INTERFACE: 87283028Smjacob// System.err.println("CLASS: " + ((JCClassDecl)tree).sym.getSimpleName()); 87355371Smjacob env = enter.getClassEnv(((JCClassDecl)tree).sym); 87482689Smjacob break; 87582689Smjacob case METHOD: 87675200Smjacob// System.err.println("METHOD: " + ((JCMethodDecl)tree).sym.getSimpleName()); 87755371Smjacob method = (JCMethodDecl)tree; 878125597Smjacob env = memberEnter.getMethodEnv(method, env); 87955371Smjacob break; 880125597Smjacob case VARIABLE: 88155371Smjacob// System.err.println("FIELD: " + ((JCVariableDecl)tree).sym.getSimpleName()); 88255371Smjacob field = (JCVariableDecl)tree; 88355371Smjacob break; 88455371Smjacob case BLOCK: { 88555371Smjacob// System.err.println("BLOCK: "); 88655371Smjacob if (method != null) { 88755371Smjacob try { 888125597Smjacob Assert.check(method.body == tree); 88955371Smjacob method.body = copier.copy((JCBlock)tree, (JCTree) path.getLeaf()); 89055371Smjacob env = attribStatToTree(method.body, env, copier.leafCopy); 89155371Smjacob } finally { 89283028Smjacob method.body = (JCBlock) tree; 89355371Smjacob } 894125597Smjacob } else { 89582689Smjacob JCBlock body = copier.copy((JCBlock)tree, (JCTree) path.getLeaf()); 896125597Smjacob env = attribStatToTree(body, env, copier.leafCopy); 89755371Smjacob } 89882689Smjacob return env; 89955371Smjacob } 900125597Smjacob default: 90155371Smjacob// System.err.println("DEFAULT: " + tree.getKind()); 90282689Smjacob if (field != null && field.getInitializer() == tree) { 90383028Smjacob env = memberEnter.getInitEnv(field, env); 90482689Smjacob JCExpression expr = copier.copy((JCExpression)tree, (JCTree) path.getLeaf()); 90582689Smjacob env = attribExprToTree(expr, env, copier.leafCopy); 90682689Smjacob return env; 90782689Smjacob } 90882689Smjacob } 90982689Smjacob } 91082689Smjacob return (field != null) ? memberEnter.getInitEnv(field, env) : env; 91182689Smjacob } 912125549Smjacob 91382689Smjacob private Env<AttrContext> attribStatToTree(JCTree stat, Env<AttrContext>env, JCTree tree) { 91482689Smjacob JavaFileObject prev = log.useSource(env.toplevel.sourcefile); 91582689Smjacob try { 91682689Smjacob return attr.attribStatToTree(stat, env, tree); 91782689Smjacob } finally { 91883028Smjacob log.useSource(prev); 91983028Smjacob } 92082689Smjacob } 92155371Smjacob 922125597Smjacob private Env<AttrContext> attribExprToTree(JCExpression expr, Env<AttrContext>env, JCTree tree) { 92355371Smjacob JavaFileObject prev = log.useSource(env.toplevel.sourcefile); 92483028Smjacob try { 92582689Smjacob return attr.attribExprToTree(expr, env, tree); 92682689Smjacob } finally { 927125549Smjacob log.useSource(prev); 92882689Smjacob } 92982689Smjacob } 930125597Smjacob 93182689Smjacob static JavaFileObject asJavaFileObject(FileObject fileObject) { 93282689Smjacob JavaFileObject jfo = null; 93382689Smjacob 93482689Smjacob if (fileObject instanceof JavaFileObject) { 935125597Smjacob jfo = (JavaFileObject) fileObject; 93682689Smjacob checkHtmlKind(fileObject, Kind.HTML); 93783028Smjacob return jfo; 93882689Smjacob } 93982689Smjacob 94082689Smjacob checkHtmlKind(fileObject); 94182689Smjacob jfo = new HtmlFileObject(fileObject); 94282689Smjacob return jfo; 94383028Smjacob } 944125597Smjacob 94555371Smjacob private static void checkHtmlKind(FileObject fileObject) { 94655371Smjacob checkHtmlKind(fileObject, BaseFileManager.getKind(fileObject.getName())); 947125597Smjacob } 948125597Smjacob 949125597Smjacob private static void checkHtmlKind(FileObject fileObject, JavaFileObject.Kind kind) { 950125597Smjacob if (kind != JavaFileObject.Kind.HTML) { 951125597Smjacob throw new IllegalArgumentException("HTML file expected:" + fileObject.getName()); 952125597Smjacob } 953125597Smjacob } 954125597Smjacob 955125597Smjacob private static class HtmlFileObject extends ForwardingFileObject<FileObject> 956125597Smjacob implements JavaFileObject { 957125597Smjacob 958125597Smjacob public HtmlFileObject(FileObject fileObject) { 959125597Smjacob super(fileObject); 960125597Smjacob } 961125597Smjacob 96255371Smjacob @Override @DefinedBy(Api.COMPILER) 96355371Smjacob public Kind getKind() { 96475200Smjacob return BaseFileManager.getKind(fileObject.getName()); 96555371Smjacob } 966125597Smjacob 967125597Smjacob @Override @DefinedBy(Api.COMPILER) 96855371Smjacob public boolean isNameCompatible(String simpleName, Kind kind) { 96955371Smjacob return false; 97075200Smjacob } 97155371Smjacob 97255371Smjacob @Override @DefinedBy(Api.COMPILER) 973125597Smjacob public NestingKind getNestingKind() { 97455371Smjacob return null; 97555371Smjacob } 97655371Smjacob 97755371Smjacob @Override @DefinedBy(Api.COMPILER) 97877365Smjacob public Modifier getAccessLevel() { 97977365Smjacob return null; 98077365Smjacob } 98177365Smjacob } 98277365Smjacob 98377365Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 98477365Smjacob public DocCommentTree getDocCommentTree(FileObject fileObject) { 98577365Smjacob JavaFileObject jfo = asJavaFileObject(fileObject); 98677365Smjacob DiagnosticSource diagSource = new DiagnosticSource(jfo, log); 98777365Smjacob 98877365Smjacob final Comment comment = new Comment() { 98977365Smjacob int offset = 0; 99077365Smjacob @Override 99177365Smjacob public String getText() { 992125597Smjacob try { 993125597Smjacob CharSequence rawDoc = fileObject.getCharContent(true); 994125597Smjacob Pattern bodyPat = 995125597Smjacob Pattern.compile("(?is).*?<body\\b[^>]*>(.*)</body\\b.*"); 99655371Smjacob Matcher m = bodyPat.matcher(rawDoc); 99755371Smjacob if (m.matches()) { 99877365Smjacob offset = m.end(1); 99955371Smjacob return m.group(1); 100077365Smjacob } else { 100177365Smjacob // Assume doclint will do the right thing. 100277365Smjacob return ""; 100377365Smjacob } 100477365Smjacob } catch (IOException ignore) { 100577365Smjacob // do nothing 100677365Smjacob } 100777365Smjacob return ""; 100877365Smjacob } 100977365Smjacob 101077365Smjacob @Override 1011125597Smjacob public int getSourcePos(int index) { 1012125597Smjacob return offset + index; 1013125597Smjacob } 1014125597Smjacob 101555371Smjacob @Override 1016125597Smjacob public CommentStyle getStyle() { 1017125597Smjacob throw new UnsupportedOperationException(); 1018125597Smjacob } 1019125597Smjacob 1020125597Smjacob @Override 1021125597Smjacob public boolean isDeprecated() { 1022125597Smjacob throw new UnsupportedOperationException(); 1023125597Smjacob } 102477365Smjacob }; 1025125597Smjacob 1026125597Smjacob return new DocCommentParser(parser, diagSource, comment).parse(); 1027125597Smjacob } 1028125597Smjacob 1029125597Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 1030155704Smjacob public DocTreePath getDocTreePath(FileObject fileObject) { 1031125597Smjacob JavaFileObject jfo = asJavaFileObject(fileObject); 1032125597Smjacob DocCommentTree docCommentTree = getDocCommentTree(jfo); 1033125597Smjacob return new DocTreePath(makeTreePath(jfo, docCommentTree), docCommentTree); 103455371Smjacob } 1035125597Smjacob 1036125597Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 1037125597Smjacob public void setBreakIterator(BreakIterator breakiterator) { 1038125597Smjacob this.breakIterator = breakiterator; 1039125597Smjacob } 104055371Smjacob 1041125597Smjacob /** 1042125597Smjacob * Makes a copy of a tree, noting the value resulting from copying a particular leaf. 1043125597Smjacob **/ 1044125597Smjacob protected static class Copier extends TreeCopier<JCTree> { 1045125597Smjacob JCTree leafCopy = null; 1046125597Smjacob 1047125597Smjacob protected Copier(TreeMaker M) { 1048125597Smjacob super(M); 1049125597Smjacob } 1050125597Smjacob 1051125597Smjacob @Override 1052125597Smjacob public <T extends JCTree> T copy(T t, JCTree leaf) { 1053125597Smjacob T t2 = super.copy(t, leaf); 1054125597Smjacob if (t == leaf) 105582689Smjacob leafCopy = t2; 1056125597Smjacob return t2; 105755371Smjacob } 1058125597Smjacob } 1059125597Smjacob 106055371Smjacob protected Copier createCopier(TreeMaker maker) { 1061125597Smjacob return new Copier(maker); 106255371Smjacob } 1063125597Smjacob 1064125597Smjacob /** 1065125597Smjacob * Returns the original type from the ErrorType object. 1066125597Smjacob * @param errorType The errorType for which we want to get the original type. 1067125597Smjacob * @return TypeMirror corresponding to the original type, replaced by the ErrorType. 106855371Smjacob * noType (type.tag == NONE) is returned if there is no original type. 1069125597Smjacob */ 1070125597Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 1071125597Smjacob public TypeMirror getOriginalType(javax.lang.model.type.ErrorType errorType) { 1072125597Smjacob if (errorType instanceof com.sun.tools.javac.code.Type.ErrorType) { 1073125597Smjacob return ((com.sun.tools.javac.code.Type.ErrorType)errorType).getOriginalType(); 1074125597Smjacob } 1075125597Smjacob 1076125597Smjacob return com.sun.tools.javac.code.Type.noType; 1077125597Smjacob } 107855371Smjacob 1079125597Smjacob /** 1080125597Smjacob * Prints a message of the specified kind at the location of the 1081125597Smjacob * tree within the provided compilation unit 1082125597Smjacob * 1083125597Smjacob * @param kind the kind of message 1084125597Smjacob * @param msg the message, or an empty string if none 1085125597Smjacob * @param t the tree to use as a position hint 1086125597Smjacob * @param root the compilation unit that contains tree 1087125597Smjacob */ 1088125597Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 1089125597Smjacob public void printMessage(Diagnostic.Kind kind, CharSequence msg, 1090125597Smjacob com.sun.source.tree.Tree t, 1091125597Smjacob com.sun.source.tree.CompilationUnitTree root) { 109255371Smjacob printMessage(kind, msg, ((JCTree) t).pos(), root); 1093125597Smjacob } 1094125597Smjacob 109555371Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 1096125597Smjacob public void printMessage(Diagnostic.Kind kind, CharSequence msg, 1097125597Smjacob com.sun.source.doctree.DocTree t, 1098125597Smjacob com.sun.source.doctree.DocCommentTree c, 1099125597Smjacob com.sun.source.tree.CompilationUnitTree root) { 1100125597Smjacob printMessage(kind, msg, ((DCTree) t).pos((DCDocComment) c), root); 1101125597Smjacob } 1102125597Smjacob 1103125597Smjacob private void printMessage(Diagnostic.Kind kind, CharSequence msg, 1104125597Smjacob JCDiagnostic.DiagnosticPosition pos, 1105125597Smjacob com.sun.source.tree.CompilationUnitTree root) { 1106125597Smjacob JavaFileObject oldSource = null; 1107125597Smjacob JavaFileObject newSource = null; 1108125597Smjacob 1109125597Smjacob newSource = root.getSourceFile(); 1110125597Smjacob if (newSource == null) { 1111125597Smjacob pos = null; 1112125597Smjacob } else { 1113125597Smjacob oldSource = log.useSource(newSource); 1114125597Smjacob } 1115125597Smjacob 1116125597Smjacob try { 1117125597Smjacob switch (kind) { 111855371Smjacob case ERROR: 111955371Smjacob log.error(DiagnosticFlag.MULTIPLE, pos, "proc.messager", msg.toString()); 1120125597Smjacob break; 112155371Smjacob 112255371Smjacob case WARNING: 112355371Smjacob log.warning(pos, "proc.messager", msg.toString()); 112455371Smjacob break; 112555371Smjacob 112655371Smjacob case MANDATORY_WARNING: 1127125549Smjacob log.mandatoryWarning(pos, "proc.messager", msg.toString()); 112855371Smjacob break; 112955371Smjacob 1130125549Smjacob default: 113155371Smjacob log.note(pos, "proc.messager", msg.toString()); 1132125549Smjacob } 113355371Smjacob } finally { 113455371Smjacob if (oldSource != null) 1135125549Smjacob log.useSource(oldSource); 113655371Smjacob } 113755371Smjacob } 1138125549Smjacob 1139125549Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 1140125549Smjacob public TypeMirror getLub(CatchTree tree) { 1141125549Smjacob JCCatch ct = (JCCatch) tree; 1142125549Smjacob JCVariableDecl v = ct.param; 1143125549Smjacob if (v.type != null && v.type.getKind() == TypeKind.UNION) { 1144125549Smjacob UnionClassType ut = (UnionClassType) v.type; 1145125549Smjacob return ut.getLub(); 1146125549Smjacob } else { 114755371Smjacob return v.type; 1148125549Smjacob } 114955371Smjacob } 115055371Smjacob 115175200Smjacob /** 115255371Smjacob * Register a file object, such as for a package.html, that provides 1153125549Smjacob * doc comments for a package. 1154125549Smjacob * @param psym the PackageSymbol representing the package. 115555371Smjacob * @param jfo the JavaFileObject for the given package. 115655371Smjacob */ 115755371Smjacob public void putJavaFileObject(PackageSymbol psym, JavaFileObject jfo) { 115855371Smjacob javaFileObjectToPackageMap.putIfAbsent(jfo, psym); 1159125549Smjacob } 116055371Smjacob 116155371Smjacob private TreePath makeTreePath(final JavaFileObject jfo, DocCommentTree dcTree) { 1162125549Smjacob JCCompilationUnit jcCompilationUnit = new JCCompilationUnit(List.nil()) { 116355371Smjacob public int getPos() { 116455371Smjacob return Position.FIRSTPOS; 1165125549Smjacob } 1166125549Smjacob 116755371Smjacob public JavaFileObject getSourcefile() { 116855371Smjacob return jfo; 116955371Smjacob } 117055371Smjacob 117155371Smjacob @Override @DefinedBy(Api.COMPILER_TREE) 117255371Smjacob public Position.LineMap getLineMap() { 117355371Smjacob try { 117455371Smjacob CharSequence content = jfo.getCharContent(true); 117555371Smjacob String s = content.toString(); 117655371Smjacob return Position.makeLineMap(s.toCharArray(), s.length(), true); 117755371Smjacob } catch (IOException ignore) {} 117855371Smjacob return null; 117955371Smjacob } 118055371Smjacob }; 118155371Smjacob 118255371Smjacob PackageSymbol psym = javaFileObjectToPackageMap.getOrDefault(jfo, syms.unnamedPackage); 118355371Smjacob 118455371Smjacob jcCompilationUnit.docComments = new DocCommentTable() { 118555371Smjacob @Override 118655371Smjacob public boolean hasComment(JCTree tree) { 118755371Smjacob return false; 118855371Smjacob } 118955371Smjacob 1190125549Smjacob @Override 119155371Smjacob public Comment getComment(JCTree tree) { 1192125549Smjacob throw new UnsupportedOperationException(); 119355371Smjacob } 119455371Smjacob 1195125549Smjacob @Override 1196125549Smjacob public String getCommentText(JCTree tree) { 1197125549Smjacob throw new UnsupportedOperationException(); 119855371Smjacob } 119955371Smjacob 120055371Smjacob @Override 120155371Smjacob public DCDocComment getCommentTree(JCTree tree) { 120255371Smjacob return (DCDocComment)dcTree; 120355371Smjacob } 120456007Smjacob 1205155704Smjacob @Override 1206155704Smjacob public void putComment(JCTree tree, Comment c) { 1207155704Smjacob throw new UnsupportedOperationException(); 120855371Smjacob } 120963385Smjacob 121087635Smjacob }; 121155387Smjacob jcCompilationUnit.lineMap = jcCompilationUnit.getLineMap(); 121255387Smjacob jcCompilationUnit.namedImportScope = new NamedImportScope(psym, jcCompilationUnit.toplevelScope); 121355371Smjacob jcCompilationUnit.packge = psym; 121455371Smjacob jcCompilationUnit.starImportScope = null; 121587635Smjacob jcCompilationUnit.sourcefile = jfo; 121655371Smjacob jcCompilationUnit.starImportScope = new StarImportScope(psym); 121755371Smjacob jcCompilationUnit.toplevelScope = WriteableScope.create(psym); 121855371Smjacob 121955371Smjacob return new TreePath(jcCompilationUnit); 122055371Smjacob } 122155371Smjacob} 122284242Smjacob