1 /*
   2  * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.tools.javac.api;
  27 
  28 import java.io.FileNotFoundException;
  29 import java.io.IOException;
  30 import java.text.BreakIterator;
  31 import java.util.Collections;
  32 import java.util.HashSet;
  33 import java.util.Map;
  34 import java.util.Set;
  35 import java.util.WeakHashMap;
  36 import java.util.regex.Matcher;
  37 import java.util.regex.Pattern;
  38 
  39 import javax.annotation.processing.ProcessingEnvironment;
  40 import javax.lang.model.element.AnnotationMirror;
  41 import javax.lang.model.element.AnnotationValue;
  42 import javax.lang.model.element.Element;
  43 import javax.lang.model.element.ElementKind;
  44 import javax.lang.model.element.ExecutableElement;
  45 import javax.lang.model.element.Modifier;
  46 import javax.lang.model.element.NestingKind;
  47 import javax.lang.model.element.PackageElement;
  48 import javax.lang.model.element.TypeElement;
  49 import javax.lang.model.type.DeclaredType;
  50 import javax.lang.model.type.TypeKind;
  51 import javax.lang.model.type.TypeMirror;
  52 import javax.tools.Diagnostic;
  53 import javax.tools.FileObject;
  54 import javax.tools.ForwardingFileObject;
  55 import javax.tools.JavaCompiler;
  56 import javax.tools.JavaFileManager;
  57 import javax.tools.JavaFileObject;
  58 import javax.tools.JavaFileObject.Kind;
  59 import javax.tools.StandardLocation;
  60 
  61 import com.sun.source.doctree.DocCommentTree;
  62 import com.sun.source.doctree.DocTree;
  63 import com.sun.source.doctree.EndElementTree;
  64 import com.sun.source.doctree.StartElementTree;
  65 import com.sun.source.tree.CatchTree;
  66 import com.sun.source.tree.CompilationUnitTree;
  67 import com.sun.source.tree.Scope;
  68 import com.sun.source.tree.Tree;
  69 import com.sun.source.util.DocSourcePositions;
  70 import com.sun.source.util.DocTreePath;
  71 import com.sun.source.util.DocTreeScanner;
  72 import com.sun.source.util.DocTrees;
  73 import com.sun.source.util.JavacTask;
  74 import com.sun.source.util.SimpleDocTreeVisitor;
  75 import com.sun.source.util.TreePath;
  76 import com.sun.tools.javac.code.Flags;
  77 import com.sun.tools.javac.code.Scope.NamedImportScope;
  78 import com.sun.tools.javac.code.Scope.StarImportScope;
  79 import com.sun.tools.javac.code.Scope.WriteableScope;
  80 import com.sun.tools.javac.code.Symbol;
  81 import com.sun.tools.javac.code.Symbol.ClassSymbol;
  82 import com.sun.tools.javac.code.Symbol.MethodSymbol;
  83 import com.sun.tools.javac.code.Symbol.ModuleSymbol;
  84 import com.sun.tools.javac.code.Symbol.PackageSymbol;
  85 import com.sun.tools.javac.code.Symbol.TypeSymbol;
  86 import com.sun.tools.javac.code.Symbol.VarSymbol;
  87 import com.sun.tools.javac.code.Symtab;
  88 import com.sun.tools.javac.code.Type;
  89 import com.sun.tools.javac.code.Type.ArrayType;
  90 import com.sun.tools.javac.code.Type.ClassType;
  91 import com.sun.tools.javac.code.Type.ErrorType;
  92 import com.sun.tools.javac.code.Type.UnionClassType;
  93 import com.sun.tools.javac.code.Types;
  94 import com.sun.tools.javac.code.Types.TypeRelation;
  95 import com.sun.tools.javac.comp.Attr;
  96 import com.sun.tools.javac.comp.AttrContext;
  97 import com.sun.tools.javac.comp.Enter;
  98 import com.sun.tools.javac.comp.Env;
  99 import com.sun.tools.javac.comp.MemberEnter;
 100 import com.sun.tools.javac.comp.Modules;
 101 import com.sun.tools.javac.comp.Resolve;
 102 import com.sun.tools.javac.file.BaseFileManager;
 103 import com.sun.tools.javac.model.JavacElements;
 104 import com.sun.tools.javac.parser.DocCommentParser;
 105 import com.sun.tools.javac.parser.ParserFactory;
 106 import com.sun.tools.javac.parser.Tokens.Comment;
 107 import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle;
 108 import com.sun.tools.javac.processing.JavacProcessingEnvironment;
 109 import com.sun.tools.javac.resources.CompilerProperties.Errors;
 110 import com.sun.tools.javac.resources.CompilerProperties.Notes;
 111 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
 112 import com.sun.tools.javac.tree.DCTree;
 113 import com.sun.tools.javac.tree.DCTree.DCBlockTag;
 114 import com.sun.tools.javac.tree.DCTree.DCDocComment;
 115 import com.sun.tools.javac.tree.DCTree.DCEndPosTree;
 116 import com.sun.tools.javac.tree.DCTree.DCErroneous;
 117 import com.sun.tools.javac.tree.DCTree.DCIdentifier;
 118 import com.sun.tools.javac.tree.DCTree.DCParam;
 119 import com.sun.tools.javac.tree.DCTree.DCReference;
 120 import com.sun.tools.javac.tree.DCTree.DCText;
 121 import com.sun.tools.javac.tree.DocCommentTable;
 122 import com.sun.tools.javac.tree.DocTreeMaker;
 123 import com.sun.tools.javac.tree.EndPosTable;
 124 import com.sun.tools.javac.tree.JCTree;
 125 import com.sun.tools.javac.tree.JCTree.JCBlock;
 126 import com.sun.tools.javac.tree.JCTree.JCCatch;
 127 import com.sun.tools.javac.tree.JCTree.JCClassDecl;
 128 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
 129 import com.sun.tools.javac.tree.JCTree.JCExpression;
 130 import com.sun.tools.javac.tree.JCTree.JCIdent;
 131 import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
 132 import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
 133 import com.sun.tools.javac.tree.TreeCopier;
 134 import com.sun.tools.javac.tree.TreeInfo;
 135 import com.sun.tools.javac.tree.TreeMaker;
 136 import com.sun.tools.javac.util.Abort;
 137 import com.sun.tools.javac.util.Assert;
 138 import com.sun.tools.javac.util.Context;
 139 import com.sun.tools.javac.util.DefinedBy;
 140 import com.sun.tools.javac.util.DefinedBy.Api;
 141 import com.sun.tools.javac.util.DiagnosticSource;
 142 import com.sun.tools.javac.util.JCDiagnostic;
 143 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
 144 import com.sun.tools.javac.util.List;
 145 import com.sun.tools.javac.util.ListBuffer;
 146 import com.sun.tools.javac.util.Log;
 147 import com.sun.tools.javac.util.Name;
 148 import com.sun.tools.javac.util.Names;
 149 import com.sun.tools.javac.util.Pair;
 150 import com.sun.tools.javac.util.Position;
 151 
 152 import static com.sun.tools.javac.code.Kinds.Kind.*;
 153 import static com.sun.tools.javac.code.TypeTag.*;
 154 
 155 /**
 156  * Provides an implementation of Trees.
 157  *
 158  * <p><b>This is NOT part of any supported API.
 159  * If you write code that depends on this, you do so at your own
 160  * risk.  This code and its internal interfaces are subject to change
 161  * or deletion without notice.</b></p>
 162  *
 163  * @author Peter von der Ah&eacute;
 164  */
 165 public class JavacTrees extends DocTrees {
 166 
 167     // in a world of a single context per compilation, these would all be final
 168     private Modules modules;
 169     private Resolve resolve;
 170     private Enter enter;
 171     private Log log;
 172     private MemberEnter memberEnter;
 173     private Attr attr;
 174     private TreeMaker treeMaker;
 175     private JavacElements elements;
 176     private JavacTaskImpl javacTaskImpl;
 177     private Names names;
 178     private Types types;
 179     private DocTreeMaker docTreeMaker;
 180     private BreakIterator breakIterator;
 181     private JavaFileManager fileManager;
 182     private ParserFactory parser;
 183     private Symtab syms;
 184 
 185     private final Map<Type, Type> extraType2OriginalMap = new WeakHashMap<>();
 186 
 187     // called reflectively from Trees.instance(CompilationTask task)
 188     public static JavacTrees instance(JavaCompiler.CompilationTask task) {
 189         if (!(task instanceof BasicJavacTask))
 190             throw new IllegalArgumentException();
 191         return instance(((BasicJavacTask)task).getContext());
 192     }
 193 
 194     // called reflectively from Trees.instance(ProcessingEnvironment env)
 195     public static JavacTrees instance(ProcessingEnvironment env) {
 196         if (!(env instanceof JavacProcessingEnvironment))
 197             throw new IllegalArgumentException();
 198         return instance(((JavacProcessingEnvironment)env).getContext());
 199     }
 200 
 201     public static JavacTrees instance(Context context) {
 202         JavacTrees instance = context.get(JavacTrees.class);
 203         if (instance == null)
 204             instance = new JavacTrees(context);
 205         return instance;
 206     }
 207 
 208     protected JavacTrees(Context context) {
 209         this.breakIterator = null;
 210         context.put(JavacTrees.class, this);
 211         init(context);
 212     }
 213 
 214     public void updateContext(Context context) {
 215         init(context);
 216     }
 217 
 218     private void init(Context context) {
 219         modules = Modules.instance(context);
 220         attr = Attr.instance(context);
 221         enter = Enter.instance(context);
 222         elements = JavacElements.instance(context);
 223         log = Log.instance(context);
 224         resolve = Resolve.instance(context);
 225         treeMaker = TreeMaker.instance(context);
 226         memberEnter = MemberEnter.instance(context);
 227         names = Names.instance(context);
 228         types = Types.instance(context);
 229         docTreeMaker = DocTreeMaker.instance(context);
 230         parser = ParserFactory.instance(context);
 231         syms = Symtab.instance(context);
 232         fileManager = context.get(JavaFileManager.class);
 233         JavacTask t = context.get(JavacTask.class);
 234         if (t instanceof JavacTaskImpl)
 235             javacTaskImpl = (JavacTaskImpl) t;
 236     }
 237 
 238     @Override @DefinedBy(Api.COMPILER_TREE)
 239     public BreakIterator getBreakIterator() {
 240         return breakIterator;
 241     }
 242 
 243     @Override @DefinedBy(Api.COMPILER_TREE)
 244     public DocSourcePositions getSourcePositions() {
 245         return new DocSourcePositions() {
 246                 @Override @DefinedBy(Api.COMPILER_TREE)
 247                 public long getStartPosition(CompilationUnitTree file, Tree tree) {
 248                     return TreeInfo.getStartPos((JCTree) tree);
 249                 }
 250 
 251                 @Override @DefinedBy(Api.COMPILER_TREE)
 252                 public long getEndPosition(CompilationUnitTree file, Tree tree) {
 253                     EndPosTable endPosTable = ((JCCompilationUnit) file).endPositions;
 254                     return TreeInfo.getEndPos((JCTree) tree, endPosTable);
 255                 }
 256 
 257                 @Override @DefinedBy(Api.COMPILER_TREE)
 258                 public long getStartPosition(CompilationUnitTree file, DocCommentTree comment, DocTree tree) {
 259                     return ((DCTree) tree).getSourcePosition((DCDocComment) comment);
 260                 }
 261                 @Override  @DefinedBy(Api.COMPILER_TREE) @SuppressWarnings("fallthrough")
 262                 public long getEndPosition(CompilationUnitTree file, DocCommentTree comment, DocTree tree) {
 263                     DCDocComment dcComment = (DCDocComment) comment;
 264                     if (tree instanceof DCEndPosTree) {
 265                         int endPos = ((DCEndPosTree) tree).getEndPos(dcComment);
 266 
 267                         if (endPos != Position.NOPOS) {
 268                             return endPos;
 269                         }
 270                     }
 271                     int correction = 0;
 272                     switch (tree.getKind()) {
 273                         case TEXT:
 274                             DCText text = (DCText) tree;
 275 
 276                             return dcComment.comment.getSourcePos(text.pos + text.text.length());
 277                         case ERRONEOUS:
 278                             DCErroneous err = (DCErroneous) tree;
 279 
 280                             return dcComment.comment.getSourcePos(err.pos + err.body.length());
 281                         case IDENTIFIER:
 282                             DCIdentifier ident = (DCIdentifier) tree;
 283 
 284                             return dcComment.comment.getSourcePos(ident.pos + (ident.name != names.error ? ident.name.length() : 0));
 285                         case PARAM:
 286                             DCParam param = (DCParam) tree;
 287 
 288                             if (param.isTypeParameter && param.getDescription().isEmpty()) {
 289                                 correction = 1;
 290                             }
 291                         case AUTHOR: case DEPRECATED: case RETURN: case SEE:
 292                         case SERIAL: case SERIAL_DATA: case SERIAL_FIELD: case SINCE:
 293                         case THROWS: case UNKNOWN_BLOCK_TAG: case VERSION: {
 294                             DocTree last = getLastChild(tree);
 295 
 296                             if (last != null) {
 297                                 return getEndPosition(file, comment, last) + correction;
 298                             }
 299 
 300                             DCBlockTag block = (DCBlockTag) tree;
 301 
 302                             return dcComment.comment.getSourcePos(block.pos + block.getTagName().length() + 1);
 303                         }
 304                         default:
 305                             DocTree last = getLastChild(tree);
 306 
 307                             if (last != null) {
 308                                 return getEndPosition(file, comment, last);
 309                             }
 310                             break;
 311                     }
 312 
 313                     return Position.NOPOS;
 314                 }
 315             };
 316     }
 317 
 318     @Override @DefinedBy(Api.COMPILER_TREE)
 319     public DocTreeMaker getDocTreeFactory() {
 320         return docTreeMaker;
 321     }
 322 
 323     private DocTree getLastChild(DocTree tree) {
 324         final DocTree[] last = new DocTree[] {null};
 325 
 326         tree.accept(new DocTreeScanner<Void, Void>() {
 327             @Override @DefinedBy(Api.COMPILER_TREE)
 328             public Void scan(DocTree node, Void p) {
 329                 if (node != null) last[0] = node;
 330                 return null;
 331             }
 332         }, null);
 333 
 334         return last[0];
 335     }
 336 
 337     @Override @DefinedBy(Api.COMPILER_TREE)
 338     public JCClassDecl getTree(TypeElement element) {
 339         return (JCClassDecl) getTree((Element) element);
 340     }
 341 
 342     @Override @DefinedBy(Api.COMPILER_TREE)
 343     public JCMethodDecl getTree(ExecutableElement method) {
 344         return (JCMethodDecl) getTree((Element) method);
 345     }
 346 
 347     @Override @DefinedBy(Api.COMPILER_TREE)
 348     public JCTree getTree(Element element) {
 349         return getTree(element, null);
 350     }
 351 
 352     @Override @DefinedBy(Api.COMPILER_TREE)
 353     public JCTree getTree(Element e, AnnotationMirror a) {
 354         return getTree(e, a, null);
 355     }
 356 
 357     @Override @DefinedBy(Api.COMPILER_TREE)
 358     public JCTree getTree(Element e, AnnotationMirror a, AnnotationValue v) {
 359         Pair<JCTree, JCCompilationUnit> treeTopLevel = elements.getTreeAndTopLevel(e, a, v);
 360         if (treeTopLevel == null)
 361             return null;
 362         return treeTopLevel.fst;
 363     }
 364 
 365     @Override @DefinedBy(Api.COMPILER_TREE)
 366     public TreePath getPath(CompilationUnitTree unit, Tree node) {
 367         return TreePath.getPath(unit, node);
 368     }
 369 
 370     @Override @DefinedBy(Api.COMPILER_TREE)
 371     public TreePath getPath(Element e) {
 372         return getPath(e, null, null);
 373     }
 374 
 375     @Override @DefinedBy(Api.COMPILER_TREE)
 376     public TreePath getPath(Element e, AnnotationMirror a) {
 377         return getPath(e, a, null);
 378     }
 379 
 380     @Override @DefinedBy(Api.COMPILER_TREE)
 381     public TreePath getPath(Element e, AnnotationMirror a, AnnotationValue v) {
 382         final Pair<JCTree, JCCompilationUnit> treeTopLevel = elements.getTreeAndTopLevel(e, a, v);
 383         if (treeTopLevel == null)
 384             return null;
 385         return TreePath.getPath(treeTopLevel.snd, treeTopLevel.fst);
 386     }
 387 
 388     @Override @DefinedBy(Api.COMPILER_TREE)
 389     public Symbol getElement(TreePath path) {
 390         JCTree tree = (JCTree) path.getLeaf();
 391         Symbol sym = TreeInfo.symbolFor(tree);
 392         if (sym == null) {
 393             for (TreePath p = path; p != null; p = p.getParentPath()) {
 394                 JCTree t = (JCTree) p.getLeaf();
 395                 if (t.hasTag(JCTree.Tag.CLASSDEF)) {
 396                     JCClassDecl ct = (JCClassDecl) t;
 397                     if (ct.sym != null) {
 398                         if ((ct.sym.flags_field & Flags.UNATTRIBUTED) != 0) {
 399                             attr.attribClass(ct.pos(), ct.sym);
 400                             sym = TreeInfo.symbolFor(tree);
 401                         }
 402                         break;
 403                     }
 404                 }
 405             }
 406         }
 407         return sym;
 408     }
 409 
 410     @Override @DefinedBy(Api.COMPILER_TREE)
 411     public Element getElement(DocTreePath path) {
 412         DocTree tree = path.getLeaf();
 413         if (tree instanceof DCReference)
 414             return attributeDocReference(path.getTreePath(), ((DCReference) tree));
 415         if (tree instanceof DCIdentifier) {
 416             if (path.getParentPath().getLeaf() instanceof DCParam) {
 417                 return attributeParamIdentifier(path.getTreePath(), (DCParam) path.getParentPath().getLeaf());
 418             }
 419         }
 420         return null;
 421     }
 422 
 423     @Override @DefinedBy(Api.COMPILER_TREE)
 424     public java.util.List<DocTree> getFirstSentence(java.util.List<? extends DocTree> list) {
 425         return docTreeMaker.getFirstSentence(list);
 426     }
 427 
 428     private Symbol attributeDocReference(TreePath path, DCReference ref) {
 429         Env<AttrContext> env = getAttrContext(path);
 430         if (env == null) return null;
 431 
 432         Log.DeferredDiagnosticHandler deferredDiagnosticHandler =
 433                 new Log.DeferredDiagnosticHandler(log);
 434         try {
 435             final TypeSymbol tsym;
 436             final Name memberName;
 437             if (ref.qualifierExpression == null) {
 438                 tsym = env.enclClass.sym;
 439                 memberName = (Name) ref.memberName;
 440             } else {
 441                 // newSeeTree if the qualifierExpression is a type or package name.
 442                 // javac does not provide the exact method required, so
 443                 // we first check if qualifierExpression identifies a type,
 444                 // and if not, then we check to see if it identifies a package.
 445                 Type t = attr.attribType(ref.qualifierExpression, env);
 446                 if (t.isErroneous()) {
 447                     JCCompilationUnit toplevel =
 448                         treeMaker.TopLevel(List.nil());
 449                     final ModuleSymbol msym = modules.getDefaultModule();
 450                     toplevel.modle = msym;
 451                     toplevel.packge = msym.unnamedPackage;
 452                     Symbol sym = attr.attribIdent(ref.qualifierExpression, toplevel);
 453 
 454                     if (sym == null)
 455                         return null;
 456 
 457                     sym.complete();
 458 
 459                     if ((sym.kind == PCK || sym.kind == TYP) && sym.exists()) {
 460                         tsym = (TypeSymbol) sym;
 461                         memberName = (Name) ref.memberName;
 462                         if (sym.kind == PCK && memberName != null) {
 463                             //cannot refer to a package "member"
 464                             return null;
 465                         }
 466                     } else {
 467                         if (ref.qualifierExpression.hasTag(JCTree.Tag.IDENT)) {
 468                             // fixup:  allow "identifier" instead of "#identifier"
 469                             // for compatibility with javadoc
 470                             tsym = env.enclClass.sym;
 471                             memberName = ((JCIdent) ref.qualifierExpression).name;
 472                         } else {
 473                             return null;
 474                         }
 475                     }
 476                 } else {
 477                     Type e = t;
 478                     // If this is an array type convert to element type
 479                     while (e instanceof ArrayType)
 480                         e = ((ArrayType)e).elemtype;
 481                     tsym = e.tsym;
 482                     memberName = (Name) ref.memberName;
 483                 }
 484             }
 485 
 486             if (memberName == null)
 487                 return tsym;
 488 
 489             final List<Type> paramTypes;
 490             if (ref.paramTypes == null)
 491                 paramTypes = null;
 492             else {
 493                 ListBuffer<Type> lb = new ListBuffer<>();
 494                 for (List<JCTree> l = (List<JCTree>) ref.paramTypes; l.nonEmpty(); l = l.tail) {
 495                     JCTree tree = l.head;
 496                     Type t = attr.attribType(tree, env);
 497                     lb.add(t);
 498                 }
 499                 paramTypes = lb.toList();
 500             }
 501 
 502             ClassSymbol sym = (ClassSymbol) types.skipTypeVars(tsym.type, false).tsym;
 503 
 504             Symbol msym = (memberName == sym.name)
 505                     ? findConstructor(sym, paramTypes)
 506                     : findMethod(sym, memberName, paramTypes);
 507             if (paramTypes != null) {
 508                 // explicit (possibly empty) arg list given, so cannot be a field
 509                 return msym;
 510             }
 511 
 512             VarSymbol vsym = (ref.paramTypes != null) ? null : findField(sym, memberName);
 513             // prefer a field over a method with no parameters
 514             if (vsym != null &&
 515                     (msym == null ||
 516                         types.isSubtypeUnchecked(vsym.enclClass().asType(), msym.enclClass().asType()))) {
 517                 return vsym;
 518             } else {
 519                 return msym;
 520             }
 521         } catch (Abort e) { // may be thrown by Check.completionError in case of bad class file
 522             return null;
 523         } finally {
 524             log.popDiagnosticHandler(deferredDiagnosticHandler);
 525         }
 526     }
 527 
 528     private Symbol attributeParamIdentifier(TreePath path, DCParam paramTag) {
 529         Symbol javadocSymbol = getElement(path);
 530         if (javadocSymbol == null)
 531             return null;
 532         ElementKind kind = javadocSymbol.getKind();
 533         List<? extends Symbol> params = List.nil();
 534         if (kind == ElementKind.METHOD || kind == ElementKind.CONSTRUCTOR) {
 535             MethodSymbol ee = (MethodSymbol) javadocSymbol;
 536             params = paramTag.isTypeParameter()
 537                     ? ee.getTypeParameters()
 538                     : ee.getParameters();
 539         } else if (kind.isClass() || kind.isInterface()) {
 540             ClassSymbol te = (ClassSymbol) javadocSymbol;
 541             params = paramTag.isTypeParameter()
 542                     ? te.getTypeParameters()
 543                     : te.getStateComponents();
 544         }
 545 
 546         for (Symbol param : params) {
 547             if (param.getSimpleName() == paramTag.getName().getName()) {
 548                 return param;
 549             }
 550         }
 551         return null;
 552     }
 553 
 554     private VarSymbol findField(ClassSymbol tsym, Name fieldName) {
 555         return searchField(tsym, fieldName, new HashSet<>());
 556     }
 557 
 558     private VarSymbol searchField(ClassSymbol tsym, Name fieldName, Set<ClassSymbol> searched) {
 559         if (searched.contains(tsym)) {
 560             return null;
 561         }
 562         searched.add(tsym);
 563 
 564         for (Symbol sym : tsym.members().getSymbolsByName(fieldName)) {
 565             if (sym.kind == VAR) {
 566                 return (VarSymbol)sym;
 567             }
 568         }
 569 
 570         //### If we found a VarSymbol above, but which did not pass
 571         //### the modifier filter, we should return failure here!
 572 
 573         ClassSymbol encl = tsym.owner.enclClass();
 574         if (encl != null) {
 575             VarSymbol vsym = searchField(encl, fieldName, searched);
 576             if (vsym != null) {
 577                 return vsym;
 578             }
 579         }
 580 
 581         // search superclass
 582         Type superclass = tsym.getSuperclass();
 583         if (superclass.tsym != null) {
 584             VarSymbol vsym = searchField((ClassSymbol) superclass.tsym, fieldName, searched);
 585             if (vsym != null) {
 586                 return vsym;
 587             }
 588         }
 589 
 590         // search interfaces
 591         List<Type> intfs = tsym.getInterfaces();
 592         for (List<Type> l = intfs; l.nonEmpty(); l = l.tail) {
 593             Type intf = l.head;
 594             if (intf.isErroneous()) continue;
 595             VarSymbol vsym = searchField((ClassSymbol) intf.tsym, fieldName, searched);
 596             if (vsym != null) {
 597                 return vsym;
 598             }
 599         }
 600 
 601         return null;
 602     }
 603 
 604     /** @see com.sun.tools.javadoc.ClassDocImpl#findConstructor */
 605     MethodSymbol findConstructor(ClassSymbol tsym, List<Type> paramTypes) {
 606         for (Symbol sym : tsym.members().getSymbolsByName(names.init)) {
 607             if (sym.kind == MTH) {
 608                 if (hasParameterTypes((MethodSymbol) sym, paramTypes)) {
 609                     return (MethodSymbol) sym;
 610                 }
 611             }
 612         }
 613         return null;
 614     }
 615 
 616     /** @see com.sun.tools.javadoc.ClassDocImpl#findMethod */
 617     private MethodSymbol findMethod(ClassSymbol tsym, Name methodName, List<Type> paramTypes) {
 618         return searchMethod(tsym, methodName, paramTypes, new HashSet<>());
 619     }
 620 
 621     /** @see com.sun.tools.javadoc.ClassDocImpl#searchMethod */
 622     private MethodSymbol searchMethod(ClassSymbol tsym, Name methodName,
 623                                        List<Type> paramTypes, Set<ClassSymbol> searched) {
 624         //### Note that this search is not necessarily what the compiler would do!
 625 
 626         // do not match constructors
 627         if (methodName == names.init)
 628             return null;
 629 
 630         if (searched.contains(tsym))
 631             return null;
 632         searched.add(tsym);
 633 
 634         // search current class
 635 
 636         //### Using modifier filter here isn't really correct,
 637         //### but emulates the old behavior.  Instead, we should
 638         //### apply the normal rules of visibility and inheritance.
 639 
 640         if (paramTypes == null) {
 641             // If no parameters specified, we are allowed to return
 642             // any method with a matching name.  In practice, the old
 643             // code returned the first method, which is now the last!
 644             // In order to provide textually identical results, we
 645             // attempt to emulate the old behavior.
 646             MethodSymbol lastFound = null;
 647             for (Symbol sym : tsym.members().getSymbolsByName(methodName)) {
 648                 if (sym.kind == MTH) {
 649                     if (sym.name == methodName) {
 650                         lastFound = (MethodSymbol)sym;
 651                     }
 652                 }
 653             }
 654             if (lastFound != null) {
 655                 return lastFound;
 656             }
 657         } else {
 658             for (Symbol sym : tsym.members().getSymbolsByName(methodName)) {
 659                 if (sym != null &&
 660                     sym.kind == MTH) {
 661                     if (hasParameterTypes((MethodSymbol) sym, paramTypes)) {
 662                         return (MethodSymbol) sym;
 663                     }
 664                 }
 665             }
 666         }
 667 
 668         //### If we found a MethodSymbol above, but which did not pass
 669         //### the modifier filter, we should return failure here!
 670 
 671         // search superclass
 672         Type superclass = tsym.getSuperclass();
 673         if (superclass.tsym != null) {
 674             MethodSymbol msym = searchMethod((ClassSymbol) superclass.tsym, methodName, paramTypes, searched);
 675             if (msym != null) {
 676                 return msym;
 677             }
 678         }
 679 
 680         // search interfaces
 681         List<Type> intfs = tsym.getInterfaces();
 682         for (List<Type> l = intfs; l.nonEmpty(); l = l.tail) {
 683             Type intf = l.head;
 684             if (intf.isErroneous()) continue;
 685             MethodSymbol msym = searchMethod((ClassSymbol) intf.tsym, methodName, paramTypes, searched);
 686             if (msym != null) {
 687                 return msym;
 688             }
 689         }
 690 
 691         // search enclosing class
 692         ClassSymbol encl = tsym.owner.enclClass();
 693         if (encl != null) {
 694             MethodSymbol msym = searchMethod(encl, methodName, paramTypes, searched);
 695             if (msym != null) {
 696                 return msym;
 697             }
 698         }
 699 
 700         return null;
 701     }
 702 
 703     /** @see com.sun.tools.javadoc.ClassDocImpl */
 704     private boolean hasParameterTypes(MethodSymbol method, List<Type> paramTypes) {
 705         if (paramTypes == null)
 706             return true;
 707 
 708         if (method.params().size() != paramTypes.size())
 709             return false;
 710 
 711         List<Type> methodParamTypes = types.erasureRecursive(method.asType()).getParameterTypes();
 712 
 713         return (Type.isErroneous(paramTypes))
 714             ? fuzzyMatch(paramTypes, methodParamTypes)
 715             : types.isSameTypes(paramTypes, methodParamTypes);
 716     }
 717 
 718     boolean fuzzyMatch(List<Type> paramTypes, List<Type> methodParamTypes) {
 719         List<Type> l1 = paramTypes;
 720         List<Type> l2 = methodParamTypes;
 721         while (l1.nonEmpty()) {
 722             if (!fuzzyMatch(l1.head, l2.head))
 723                 return false;
 724             l1 = l1.tail;
 725             l2 = l2.tail;
 726         }
 727         return true;
 728     }
 729 
 730     boolean fuzzyMatch(Type paramType, Type methodParamType) {
 731         Boolean b = fuzzyMatcher.visit(paramType, methodParamType);
 732         return (b == Boolean.TRUE);
 733     }
 734 
 735     TypeRelation fuzzyMatcher = new TypeRelation() {
 736         @Override
 737         public Boolean visitType(Type t, Type s) {
 738             if (t == s)
 739                 return true;
 740 
 741             if (s.isPartial())
 742                 return visit(s, t);
 743 
 744             switch (t.getTag()) {
 745             case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
 746             case DOUBLE: case BOOLEAN: case VOID: case BOT: case NONE:
 747                 return t.hasTag(s.getTag());
 748             default:
 749                 throw new AssertionError("fuzzyMatcher " + t.getTag());
 750             }
 751         }
 752 
 753         @Override
 754         public Boolean visitArrayType(ArrayType t, Type s) {
 755             if (t == s)
 756                 return true;
 757 
 758             if (s.isPartial())
 759                 return visit(s, t);
 760 
 761             return s.hasTag(ARRAY)
 762                 && visit(t.elemtype, types.elemtype(s));
 763         }
 764 
 765         @Override
 766         public Boolean visitClassType(ClassType t, Type s) {
 767             if (t == s)
 768                 return true;
 769 
 770             if (s.isPartial())
 771                 return visit(s, t);
 772 
 773             return t.tsym == s.tsym;
 774         }
 775 
 776         @Override
 777         public Boolean visitErrorType(ErrorType t, Type s) {
 778             return s.hasTag(CLASS)
 779                     && t.tsym.name == ((ClassType) s).tsym.name;
 780         }
 781     };
 782 
 783     @Override @DefinedBy(Api.COMPILER_TREE)
 784     public TypeMirror getTypeMirror(TreePath path) {
 785         Tree t = path.getLeaf();
 786         Type ty = ((JCTree)t).type;
 787         return ty == null ? null : ty.stripMetadataIfNeeded();
 788     }
 789 
 790     @Override @DefinedBy(Api.COMPILER_TREE)
 791     public JavacScope getScope(TreePath path) {
 792         return JavacScope.create(getAttrContext(path));
 793     }
 794 
 795     @Override @DefinedBy(Api.COMPILER_TREE)
 796     public String getDocComment(TreePath path) {
 797         CompilationUnitTree t = path.getCompilationUnit();
 798         Tree leaf = path.getLeaf();
 799         if (t instanceof JCTree.JCCompilationUnit && leaf instanceof JCTree) {
 800             JCCompilationUnit cu = (JCCompilationUnit) t;
 801             if (cu.docComments != null) {
 802                 return cu.docComments.getCommentText((JCTree) leaf);
 803             }
 804         }
 805         return null;
 806     }
 807 
 808     @Override @DefinedBy(Api.COMPILER_TREE)
 809     public DocCommentTree getDocCommentTree(TreePath path) {
 810         CompilationUnitTree t = path.getCompilationUnit();
 811         Tree leaf = path.getLeaf();
 812         if (t instanceof JCTree.JCCompilationUnit && leaf instanceof JCTree) {
 813             JCCompilationUnit cu = (JCCompilationUnit) t;
 814             if (cu.docComments != null) {
 815                 return cu.docComments.getCommentTree((JCTree) leaf);
 816             }
 817         }
 818         return null;
 819     }
 820 
 821     @Override @DefinedBy(Api.COMPILER_TREE)
 822     public DocCommentTree getDocCommentTree(Element e) {
 823         TreePath path = getPath(e);
 824         if (path == null) {
 825             return null;
 826         }
 827         return getDocCommentTree(path);
 828     }
 829 
 830     @Override @DefinedBy(Api.COMPILER_TREE)
 831     public DocCommentTree getDocCommentTree(Element e, String relativeFileName) throws IOException {
 832         PackageElement pkg = elements.getPackageOf(e);
 833         FileObject fileForInput = fileManager.getFileForInput(StandardLocation.SOURCE_PATH,
 834                 pkg.getQualifiedName().toString(), relativeFileName);
 835 
 836         if (fileForInput == null) {
 837             throw new FileNotFoundException(relativeFileName);
 838         }
 839         return getDocCommentTree(fileForInput);
 840     }
 841 
 842     @Override @DefinedBy(Api.COMPILER_TREE)
 843     public boolean isAccessible(Scope scope, TypeElement type) {
 844         if (scope instanceof JavacScope && type instanceof ClassSymbol) {
 845             Env<AttrContext> env = ((JavacScope) scope).env;
 846             return resolve.isAccessible(env, (ClassSymbol)type, true);
 847         } else
 848             return false;
 849     }
 850 
 851     @Override @DefinedBy(Api.COMPILER_TREE)
 852     public boolean isAccessible(Scope scope, Element member, DeclaredType type) {
 853         if (scope instanceof JavacScope
 854                 && member instanceof Symbol
 855                 && type instanceof com.sun.tools.javac.code.Type) {
 856             Env<AttrContext> env = ((JavacScope) scope).env;
 857             return resolve.isAccessible(env, (com.sun.tools.javac.code.Type)type, (Symbol)member, true);
 858         } else
 859             return false;
 860     }
 861 
 862     private Env<AttrContext> getAttrContext(TreePath path) {
 863         if (!(path.getLeaf() instanceof JCTree))  // implicit null-check
 864             throw new IllegalArgumentException();
 865 
 866         // if we're being invoked from a Tree API client via parse/enter/analyze,
 867         // we need to make sure all the classes have been entered;
 868         // if we're being invoked from JSR 199 or JSR 269, then the classes
 869         // will already have been entered.
 870         if (javacTaskImpl != null) {
 871             javacTaskImpl.enter(null);
 872         }
 873 
 874         JCCompilationUnit unit = (JCCompilationUnit) path.getCompilationUnit();
 875         Copier copier = createCopier(treeMaker.forToplevel(unit));
 876 
 877         Env<AttrContext> env = null;
 878         JCMethodDecl method = null;
 879         JCVariableDecl field = null;
 880 
 881         List<Tree> l = List.nil();
 882         TreePath p = path;
 883         while (p != null) {
 884             l = l.prepend(p.getLeaf());
 885             p = p.getParentPath();
 886         }
 887 
 888         for ( ; l.nonEmpty(); l = l.tail) {
 889             Tree tree = l.head;
 890             switch (tree.getKind()) {
 891                 case COMPILATION_UNIT:
 892 //                    System.err.println("COMP: " + ((JCCompilationUnit)tree).sourcefile);
 893                     env = enter.getTopLevelEnv((JCCompilationUnit)tree);
 894                     break;
 895                 case ANNOTATION_TYPE:
 896                 case CLASS:
 897                 case ENUM:
 898                 case INTERFACE:
 899 //                    System.err.println("CLASS: " + ((JCClassDecl)tree).sym.getSimpleName());
 900                     env = enter.getClassEnv(((JCClassDecl)tree).sym);
 901                     if (env == null) return null;
 902                     break;
 903                 case METHOD:
 904 //                    System.err.println("METHOD: " + ((JCMethodDecl)tree).sym.getSimpleName());
 905                     method = (JCMethodDecl)tree;
 906                     env = memberEnter.getMethodEnv(method, env);
 907                     break;
 908                 case VARIABLE:
 909 //                    System.err.println("FIELD: " + ((JCVariableDecl)tree).sym.getSimpleName());
 910                     field = (JCVariableDecl)tree;
 911                     break;
 912                 case BLOCK: {
 913 //                    System.err.println("BLOCK: ");
 914                     if (method != null) {
 915                         try {
 916                             Assert.check(method.body == tree);
 917                             method.body = copier.copy((JCBlock)tree, (JCTree) path.getLeaf());
 918                             env = attribStatToTree(method.body, env, copier.leafCopy);
 919                         } finally {
 920                             method.body = (JCBlock) tree;
 921                         }
 922                     } else {
 923                         JCBlock body = copier.copy((JCBlock)tree, (JCTree) path.getLeaf());
 924                         env = attribStatToTree(body, env, copier.leafCopy);
 925                     }
 926                     return env;
 927                 }
 928                 default:
 929 //                    System.err.println("DEFAULT: " + tree.getKind());
 930                     if (field != null && field.getInitializer() == tree) {
 931                         env = memberEnter.getInitEnv(field, env);
 932                         JCExpression expr = copier.copy((JCExpression)tree, (JCTree) path.getLeaf());
 933                         env = attribExprToTree(expr, env, copier.leafCopy);
 934                         return env;
 935                     }
 936             }
 937         }
 938         return (field != null) ? memberEnter.getInitEnv(field, env) : env;
 939     }
 940 
 941     private Env<AttrContext> attribStatToTree(JCTree stat, Env<AttrContext>env, JCTree tree) {
 942         JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
 943         try {
 944             return attr.attribStatToTree(stat, env, tree);
 945         } finally {
 946             log.useSource(prev);
 947         }
 948     }
 949 
 950     private Env<AttrContext> attribExprToTree(JCExpression expr, Env<AttrContext>env, JCTree tree) {
 951         JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
 952         try {
 953             return attr.attribExprToTree(expr, env, tree);
 954         } finally {
 955             log.useSource(prev);
 956         }
 957     }
 958 
 959     static JavaFileObject asJavaFileObject(FileObject fileObject) {
 960         JavaFileObject jfo = null;
 961 
 962         if (fileObject instanceof JavaFileObject) {
 963             jfo = (JavaFileObject) fileObject;
 964             checkHtmlKind(fileObject, Kind.HTML);
 965             return jfo;
 966         }
 967 
 968         checkHtmlKind(fileObject);
 969         jfo = new HtmlFileObject(fileObject);
 970         return jfo;
 971     }
 972 
 973     private static void checkHtmlKind(FileObject fileObject) {
 974         checkHtmlKind(fileObject, BaseFileManager.getKind(fileObject.getName()));
 975     }
 976 
 977     private static void checkHtmlKind(FileObject fileObject, JavaFileObject.Kind kind) {
 978         if (kind != JavaFileObject.Kind.HTML) {
 979             throw new IllegalArgumentException("HTML file expected:" + fileObject.getName());
 980         }
 981     }
 982 
 983     private static class HtmlFileObject extends ForwardingFileObject<FileObject>
 984             implements JavaFileObject {
 985 
 986         public HtmlFileObject(FileObject fileObject) {
 987             super(fileObject);
 988         }
 989 
 990         @Override @DefinedBy(Api.COMPILER)
 991         public Kind getKind() {
 992             return BaseFileManager.getKind(fileObject.getName());
 993         }
 994 
 995         @Override @DefinedBy(Api.COMPILER)
 996         public boolean isNameCompatible(String simpleName, Kind kind) {
 997             return false;
 998         }
 999 
1000         @Override @DefinedBy(Api.COMPILER)
1001         public NestingKind getNestingKind() {
1002             return null;
1003         }
1004 
1005         @Override @DefinedBy(Api.COMPILER)
1006         public Modifier getAccessLevel() {
1007             return null;
1008         }
1009     }
1010 
1011     @Override @DefinedBy(Api.COMPILER_TREE)
1012     public DocCommentTree getDocCommentTree(FileObject fileObject) {
1013         JavaFileObject jfo = asJavaFileObject(fileObject);
1014         DiagnosticSource diagSource = new DiagnosticSource(jfo, log);
1015 
1016         final Comment comment = new Comment() {
1017             int offset = 0;
1018             @Override
1019             public String getText() {
1020                 try {
1021                     CharSequence rawDoc = fileObject.getCharContent(true);
1022                     return rawDoc.toString();
1023                 } catch (IOException ignore) {
1024                     // do nothing
1025                 }
1026                 return "";
1027             }
1028 
1029             @Override
1030             public int getSourcePos(int index) {
1031                 return offset + index;
1032             }
1033 
1034             @Override
1035             public CommentStyle getStyle() {
1036                 throw new UnsupportedOperationException();
1037             }
1038 
1039             @Override
1040             public boolean isDeprecated() {
1041                 throw new UnsupportedOperationException();
1042             }
1043         };
1044 
1045         return new DocCommentParser(parser, diagSource, comment, true).parse();
1046     }
1047 
1048     @Override @DefinedBy(Api.COMPILER_TREE)
1049     public DocTreePath getDocTreePath(FileObject fileObject, PackageElement packageElement) {
1050         JavaFileObject jfo = asJavaFileObject(fileObject);
1051         DocCommentTree docCommentTree = getDocCommentTree(jfo);
1052         if (docCommentTree == null)
1053             return null;
1054         TreePath treePath = makeTreePath((PackageSymbol)packageElement, jfo, docCommentTree);
1055         return new DocTreePath(treePath, docCommentTree);
1056     }
1057 
1058     @Override @DefinedBy(Api.COMPILER_TREE)
1059     public void setBreakIterator(BreakIterator breakiterator) {
1060         this.breakIterator = breakiterator;
1061     }
1062 
1063     /**
1064      * Makes a copy of a tree, noting the value resulting from copying a particular leaf.
1065      **/
1066     protected static class Copier extends TreeCopier<JCTree> {
1067         JCTree leafCopy = null;
1068 
1069         protected Copier(TreeMaker M) {
1070             super(M);
1071         }
1072 
1073         @Override
1074         public <T extends JCTree> T copy(T t, JCTree leaf) {
1075             T t2 = super.copy(t, leaf);
1076             if (t == leaf)
1077                 leafCopy = t2;
1078             return t2;
1079         }
1080     }
1081 
1082     protected Copier createCopier(TreeMaker maker) {
1083         return new Copier(maker);
1084     }
1085 
1086     /**
1087      * Returns the original type from the ErrorType object.
1088      * @param errorType The errorType for which we want to get the original type.
1089      * @return TypeMirror corresponding to the original type, replaced by the ErrorType.
1090      *         noType (type.tag == NONE) is returned if there is no original type.
1091      */
1092     @Override @DefinedBy(Api.COMPILER_TREE)
1093     public TypeMirror getOriginalType(javax.lang.model.type.ErrorType errorType) {
1094         if (errorType instanceof com.sun.tools.javac.code.Type.ErrorType) {
1095             return ((com.sun.tools.javac.code.Type.ErrorType)errorType).getOriginalType();
1096         }
1097         if (errorType instanceof com.sun.tools.javac.code.Type.ClassType &&
1098             errorType.getKind() == TypeKind.ERROR) {
1099             ClassType ct = (ClassType) errorType;
1100             return extraType2OriginalMap.computeIfAbsent(ct, tt ->
1101                     new ClassType(ct.getEnclosingType(), ct.typarams_field,
1102                                   ct.tsym, ct.getMetadata()) {
1103                         @Override
1104                         public Type baseType() { return ct; }
1105                         @Override
1106                         public TypeKind getKind() {
1107                             return TypeKind.DECLARED;
1108                         }
1109                     });
1110         }
1111 
1112         return com.sun.tools.javac.code.Type.noType;
1113     }
1114 
1115     /**
1116      * Prints a message of the specified kind at the location of the
1117      * tree within the provided compilation unit
1118      *
1119      * @param kind the kind of message
1120      * @param msg  the message, or an empty string if none
1121      * @param t    the tree to use as a position hint
1122      * @param root the compilation unit that contains tree
1123      */
1124     @Override @DefinedBy(Api.COMPILER_TREE)
1125     public void printMessage(Diagnostic.Kind kind, CharSequence msg,
1126             com.sun.source.tree.Tree t,
1127             com.sun.source.tree.CompilationUnitTree root) {
1128         printMessage(kind, msg, ((JCTree) t).pos(), root);
1129     }
1130 
1131     @Override @DefinedBy(Api.COMPILER_TREE)
1132     public void printMessage(Diagnostic.Kind kind, CharSequence msg,
1133             com.sun.source.doctree.DocTree t,
1134             com.sun.source.doctree.DocCommentTree c,
1135             com.sun.source.tree.CompilationUnitTree root) {
1136         printMessage(kind, msg, ((DCTree) t).pos((DCDocComment) c), root);
1137     }
1138 
1139     private void printMessage(Diagnostic.Kind kind, CharSequence msg,
1140             JCDiagnostic.DiagnosticPosition pos,
1141             com.sun.source.tree.CompilationUnitTree root) {
1142         JavaFileObject oldSource = null;
1143         JavaFileObject newSource = null;
1144 
1145         newSource = root.getSourceFile();
1146         if (newSource == null) {
1147             pos = null;
1148         } else {
1149             oldSource = log.useSource(newSource);
1150         }
1151 
1152         try {
1153             switch (kind) {
1154             case ERROR:
1155                 log.error(DiagnosticFlag.API, pos, Errors.ProcMessager(msg.toString()));
1156                 break;
1157 
1158             case WARNING:
1159                 log.warning(pos, Warnings.ProcMessager(msg.toString()));
1160                 break;
1161 
1162             case MANDATORY_WARNING:
1163                 log.mandatoryWarning(pos, Warnings.ProcMessager(msg.toString()));
1164                 break;
1165 
1166             default:
1167                 log.note(pos, Notes.ProcMessager(msg.toString()));
1168             }
1169         } finally {
1170             if (oldSource != null)
1171                 log.useSource(oldSource);
1172         }
1173     }
1174 
1175     @Override @DefinedBy(Api.COMPILER_TREE)
1176     public TypeMirror getLub(CatchTree tree) {
1177         JCCatch ct = (JCCatch) tree;
1178         JCVariableDecl v = ct.param;
1179         if (v.type != null && v.type.getKind() == TypeKind.UNION) {
1180             UnionClassType ut = (UnionClassType) v.type;
1181             return ut.getLub();
1182         } else {
1183             return v.type;
1184         }
1185     }
1186 
1187     private TreePath makeTreePath(final PackageSymbol psym, final JavaFileObject jfo,
1188             DocCommentTree dcTree) {
1189         JCCompilationUnit jcCompilationUnit = new JCCompilationUnit(List.nil()) {
1190             public int getPos() {
1191                 return Position.FIRSTPOS;
1192             }
1193 
1194             public JavaFileObject getSourcefile() {
1195                 return jfo;
1196             }
1197 
1198             @Override @DefinedBy(Api.COMPILER_TREE)
1199             public Position.LineMap getLineMap() {
1200                 try {
1201                     CharSequence content = jfo.getCharContent(true);
1202                     String s = content.toString();
1203                     return Position.makeLineMap(s.toCharArray(), s.length(), true);
1204                 } catch (IOException ignore) {}
1205                 return null;
1206             }
1207         };
1208 
1209         jcCompilationUnit.docComments = new DocCommentTable() {
1210             @Override
1211             public boolean hasComment(JCTree tree) {
1212                 return false;
1213             }
1214 
1215             @Override
1216             public Comment getComment(JCTree tree) {
1217                 throw new UnsupportedOperationException();
1218             }
1219 
1220             @Override
1221             public String getCommentText(JCTree tree) {
1222                 throw new UnsupportedOperationException();
1223             }
1224 
1225             @Override
1226             public DCDocComment getCommentTree(JCTree tree) {
1227                 return (DCDocComment)dcTree;
1228             }
1229 
1230             @Override
1231             public void putComment(JCTree tree, Comment c) {
1232                 throw new UnsupportedOperationException();
1233             }
1234 
1235         };
1236         jcCompilationUnit.lineMap = jcCompilationUnit.getLineMap();
1237         jcCompilationUnit.modle = psym.modle;
1238         jcCompilationUnit.sourcefile = jfo;
1239         jcCompilationUnit.namedImportScope = new NamedImportScope(psym);
1240         jcCompilationUnit.packge = psym;
1241         jcCompilationUnit.starImportScope = new StarImportScope(psym);
1242         jcCompilationUnit.toplevelScope = WriteableScope.create(psym);
1243         return new TreePath(jcCompilationUnit);
1244     }
1245 }