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