JavacElements.java revision 3376:4c740bddc648
1239310Sdim/* 2239310Sdim * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. 3239310Sdim * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4239310Sdim * 5239310Sdim * This code is free software; you can redistribute it and/or modify it 6239310Sdim * under the terms of the GNU General Public License version 2 only, as 7239310Sdim * published by the Free Software Foundation. Oracle designates this 8239310Sdim * particular file as subject to the "Classpath" exception as provided 9239310Sdim * by Oracle in the LICENSE file that accompanied this code. 10239310Sdim * 11239310Sdim * This code is distributed in the hope that it will be useful, but WITHOUT 12239310Sdim * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13239310Sdim * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14239310Sdim * version 2 for more details (a copy is included in the LICENSE file that 15239310Sdim * accompanied this code). 16239310Sdim * 17239310Sdim * You should have received a copy of the GNU General Public License version 18239310Sdim * 2 along with this work; if not, write to the Free Software Foundation, 19239310Sdim * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20239310Sdim * 21249423Sdim * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22239310Sdim * or visit www.oracle.com if you need additional information or have any 23239310Sdim * questions. 24239310Sdim */ 25239310Sdim 26239310Sdimpackage com.sun.tools.javac.model; 27239310Sdim 28239310Sdimimport java.util.Map; 29239310Sdim 30239310Sdimimport javax.lang.model.SourceVersion; 31239310Sdimimport javax.lang.model.element.*; 32249423Sdimimport javax.lang.model.type.DeclaredType; 33249423Sdimimport javax.lang.model.util.Elements; 34249423Sdimimport javax.tools.JavaFileObject; 35239310Sdimimport static javax.lang.model.util.ElementFilter.methodsIn; 36249423Sdim 37239310Sdimimport com.sun.source.util.JavacTask; 38239310Sdimimport com.sun.tools.javac.api.JavacTaskImpl; 39239310Sdimimport com.sun.tools.javac.code.*; 40239310Sdimimport com.sun.tools.javac.code.Scope.WriteableScope; 41239310Sdimimport com.sun.tools.javac.code.Symbol.*; 42239310Sdimimport com.sun.tools.javac.comp.AttrContext; 43239310Sdimimport com.sun.tools.javac.comp.Enter; 44239310Sdimimport com.sun.tools.javac.comp.Env; 45239310Sdimimport com.sun.tools.javac.main.JavaCompiler; 46239310Sdimimport com.sun.tools.javac.processing.PrintingProcessor; 47239310Sdimimport com.sun.tools.javac.tree.JCTree; 48239310Sdimimport com.sun.tools.javac.tree.JCTree.*; 49239310Sdimimport com.sun.tools.javac.tree.TreeInfo; 50239310Sdimimport com.sun.tools.javac.tree.TreeScanner; 51239310Sdimimport com.sun.tools.javac.util.*; 52239310Sdimimport com.sun.tools.javac.util.DefinedBy.Api; 53239310Sdimimport com.sun.tools.javac.util.Name; 54239310Sdimimport static com.sun.tools.javac.code.Kinds.Kind.*; 55239310Sdimimport static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE; 56239310Sdimimport static com.sun.tools.javac.code.TypeTag.CLASS; 57239310Sdimimport com.sun.tools.javac.comp.CompileStates; 58239310Sdimimport com.sun.tools.javac.comp.CompileStates.CompileState; 59239310Sdimimport com.sun.tools.javac.comp.Modules; 60239310Sdimimport static com.sun.tools.javac.tree.JCTree.Tag.*; 61249423Sdim 62249423Sdim/** 63249423Sdim * Utility methods for operating on program elements. 64249423Sdim * 65249423Sdim * <p><b>This is NOT part of any supported API. 66239310Sdim * If you write code that depends on this, you do so at your own 67239310Sdim * risk. This code and its internal interfaces are subject to change 68239310Sdim * or deletion without notice.</b></p> 69249423Sdim */ 70249423Sdimpublic class JavacElements implements Elements { 71239310Sdim 72239310Sdim private final JavaCompiler javaCompiler; 73239310Sdim private final Symtab syms; 74239310Sdim private final Modules modules; 75239310Sdim private final Names names; 76239310Sdim private final Types types; 77249423Sdim private final Enter enter; 78249423Sdim private final JavacTaskImpl javacTaskImpl; 79239310Sdim private final CompileStates compileStates; 80239310Sdim 81239310Sdim public static JavacElements instance(Context context) { 82239310Sdim JavacElements instance = context.get(JavacElements.class); 83239310Sdim if (instance == null) 84249423Sdim instance = new JavacElements(context); 85239310Sdim return instance; 86239310Sdim } 87239310Sdim 88239310Sdim protected JavacElements(Context context) { 89239310Sdim context.put(JavacElements.class, this); 90239310Sdim javaCompiler = JavaCompiler.instance(context); 91 syms = Symtab.instance(context); 92 modules = Modules.instance(context); 93 names = Names.instance(context); 94 types = Types.instance(context); 95 enter = Enter.instance(context); 96 JavacTask t = context.get(JavacTask.class); 97 javacTaskImpl = t instanceof JavacTaskImpl ? (JavacTaskImpl) t : null; 98 compileStates = CompileStates.instance(context); 99 } 100 101 @Override @DefinedBy(Api.LANGUAGE_MODEL) 102 public ModuleSymbol getModuleElement(CharSequence name) { 103 ensureEntered("getModuleElement"); 104 String strName = name.toString(); 105 if (strName.equals("")) 106 return syms.unnamedModule; 107 return modules.getObservableModule(names.fromString(strName)); 108 } 109 110 @Override @DefinedBy(Api.LANGUAGE_MODEL) 111 public PackageSymbol getPackageElement(CharSequence name) { 112 ensureEntered("getPackageElement"); 113 return getPackageElement(modules.getDefaultModule(), name); 114 } 115 116 @Override @DefinedBy(Api.LANGUAGE_MODEL) 117 public PackageSymbol getPackageElement(ModuleElement module, CharSequence name) { 118 String strName = name.toString(); 119 if (strName.equals("")) 120 return syms.unnamedModule.unnamedPackage; 121 return SourceVersion.isName(strName) 122 ? nameToSymbol((ModuleSymbol) module, strName, PackageSymbol.class) 123 : null; 124 } 125 126 @Override @DefinedBy(Api.LANGUAGE_MODEL) 127 public ClassSymbol getTypeElement(CharSequence name) { 128 ensureEntered("getTypeElement"); 129 return getTypeElement(modules.getDefaultModule(), name); 130 } 131 132 @Override @DefinedBy(Api.LANGUAGE_MODEL) 133 public ClassSymbol getTypeElement(ModuleElement module, CharSequence name) { 134 String strName = name.toString(); 135 return SourceVersion.isName(strName) 136 ? nameToSymbol((ModuleSymbol) module, strName, ClassSymbol.class) 137 : null; 138 } 139 140 /** 141 * Returns a symbol given the type's or package's canonical name, 142 * or null if the name isn't found. 143 */ 144 private <S extends Symbol> S nameToSymbol(ModuleSymbol module, String nameStr, Class<S> clazz) { 145 Name name = names.fromString(nameStr); 146 // First check cache. 147 Symbol sym = (clazz == ClassSymbol.class) 148 ? syms.getClass(module, name) 149 : syms.lookupPackage(module, name); 150 151 try { 152 if (sym == null) 153 sym = javaCompiler.resolveIdent(module, nameStr); 154 155 sym.complete(); 156 157 return (sym.kind != ERR && 158 sym.exists() && 159 clazz.isInstance(sym) && 160 name.equals(sym.getQualifiedName())) 161 ? clazz.cast(sym) 162 : null; 163 } catch (CompletionFailure e) { 164 return null; 165 } 166 } 167 168 public JavacSourcePosition getSourcePosition(Element e) { 169 Pair<JCTree, JCCompilationUnit> treeTop = getTreeAndTopLevel(e); 170 if (treeTop == null) 171 return null; 172 JCTree tree = treeTop.fst; 173 JCCompilationUnit toplevel = treeTop.snd; 174 JavaFileObject sourcefile = toplevel.sourcefile; 175 if (sourcefile == null) 176 return null; 177 return new JavacSourcePosition(sourcefile, tree.pos, toplevel.lineMap); 178 } 179 180 public JavacSourcePosition getSourcePosition(Element e, AnnotationMirror a) { 181 Pair<JCTree, JCCompilationUnit> treeTop = getTreeAndTopLevel(e); 182 if (treeTop == null) 183 return null; 184 JCTree tree = treeTop.fst; 185 JCCompilationUnit toplevel = treeTop.snd; 186 JavaFileObject sourcefile = toplevel.sourcefile; 187 if (sourcefile == null) 188 return null; 189 190 JCTree annoTree = matchAnnoToTree(a, e, tree); 191 if (annoTree == null) 192 return null; 193 return new JavacSourcePosition(sourcefile, annoTree.pos, 194 toplevel.lineMap); 195 } 196 197 public JavacSourcePosition getSourcePosition(Element e, AnnotationMirror a, 198 AnnotationValue v) { 199 // TODO: better accuracy in getSourcePosition(... AnnotationValue) 200 return getSourcePosition(e, a); 201 } 202 203 /** 204 * Returns the tree for an annotation given the annotated element 205 * and the element's own tree. Returns null if the tree cannot be found. 206 */ 207 private JCTree matchAnnoToTree(AnnotationMirror findme, 208 Element e, JCTree tree) { 209 Symbol sym = cast(Symbol.class, e); 210 class Vis extends JCTree.Visitor { 211 List<JCAnnotation> result = null; 212 public void visitPackageDef(JCPackageDecl tree) { 213 result = tree.annotations; 214 } 215 public void visitClassDef(JCClassDecl tree) { 216 result = tree.mods.annotations; 217 } 218 public void visitMethodDef(JCMethodDecl tree) { 219 result = tree.mods.annotations; 220 } 221 public void visitVarDef(JCVariableDecl tree) { 222 result = tree.mods.annotations; 223 } 224 @Override 225 public void visitTypeParameter(JCTypeParameter tree) { 226 result = tree.annotations; 227 } 228 } 229 Vis vis = new Vis(); 230 tree.accept(vis); 231 if (vis.result == null) 232 return null; 233 234 List<Attribute.Compound> annos = sym.getAnnotationMirrors(); 235 return matchAnnoToTree(cast(Attribute.Compound.class, findme), 236 annos, 237 vis.result); 238 } 239 240 /** 241 * Returns the tree for an annotation given a list of annotations 242 * in which to search (recursively) and their corresponding trees. 243 * Returns null if the tree cannot be found. 244 */ 245 private JCTree matchAnnoToTree(Attribute.Compound findme, 246 List<Attribute.Compound> annos, 247 List<JCAnnotation> trees) { 248 for (Attribute.Compound anno : annos) { 249 for (JCAnnotation tree : trees) { 250 JCTree match = matchAnnoToTree(findme, anno, tree); 251 if (match != null) 252 return match; 253 } 254 } 255 return null; 256 } 257 258 /** 259 * Returns the tree for an annotation given an Attribute to 260 * search (recursively) and its corresponding tree. 261 * Returns null if the tree cannot be found. 262 */ 263 private JCTree matchAnnoToTree(final Attribute.Compound findme, 264 final Attribute attr, 265 final JCTree tree) { 266 if (attr == findme) 267 return (tree.type.tsym == findme.type.tsym) ? tree : null; 268 269 class Vis implements Attribute.Visitor { 270 JCTree result = null; 271 public void visitConstant(Attribute.Constant value) { 272 } 273 public void visitClass(Attribute.Class clazz) { 274 } 275 public void visitCompound(Attribute.Compound anno) { 276 for (Pair<MethodSymbol, Attribute> pair : anno.values) { 277 JCExpression expr = scanForAssign(pair.fst, tree); 278 if (expr != null) { 279 JCTree match = matchAnnoToTree(findme, pair.snd, expr); 280 if (match != null) { 281 result = match; 282 return; 283 } 284 } 285 } 286 } 287 public void visitArray(Attribute.Array array) { 288 if (tree.hasTag(NEWARRAY) && 289 types.elemtype(array.type).tsym == findme.type.tsym) { 290 List<JCExpression> elems = ((JCNewArray) tree).elems; 291 for (Attribute value : array.values) { 292 if (value == findme) { 293 result = elems.head; 294 return; 295 } 296 elems = elems.tail; 297 } 298 } 299 } 300 public void visitEnum(Attribute.Enum e) { 301 } 302 public void visitError(Attribute.Error e) { 303 } 304 } 305 Vis vis = new Vis(); 306 attr.accept(vis); 307 return vis.result; 308 } 309 310 /** 311 * Scans for a JCAssign node with a LHS matching a given 312 * symbol, and returns its RHS. Does not scan nested JCAnnotations. 313 */ 314 private JCExpression scanForAssign(final MethodSymbol sym, 315 final JCTree tree) { 316 class TS extends TreeScanner { 317 JCExpression result = null; 318 public void scan(JCTree t) { 319 if (t != null && result == null) 320 t.accept(this); 321 } 322 public void visitAnnotation(JCAnnotation t) { 323 if (t == tree) 324 scan(t.args); 325 } 326 public void visitAssign(JCAssign t) { 327 if (t.lhs.hasTag(IDENT)) { 328 JCIdent ident = (JCIdent) t.lhs; 329 if (ident.sym == sym) 330 result = t.rhs; 331 } 332 } 333 } 334 TS scanner = new TS(); 335 tree.accept(scanner); 336 return scanner.result; 337 } 338 339 /** 340 * Returns the tree node corresponding to this element, or null 341 * if none can be found. 342 */ 343 public JCTree getTree(Element e) { 344 Pair<JCTree, ?> treeTop = getTreeAndTopLevel(e); 345 return (treeTop != null) ? treeTop.fst : null; 346 } 347 348 @DefinedBy(Api.LANGUAGE_MODEL) 349 public String getDocComment(Element e) { 350 // Our doc comment is contained in a map in our toplevel, 351 // indexed by our tree. Find our enter environment, which gives 352 // us our toplevel. It also gives us a tree that contains our 353 // tree: walk it to find our tree. This is painful. 354 Pair<JCTree, JCCompilationUnit> treeTop = getTreeAndTopLevel(e); 355 if (treeTop == null) 356 return null; 357 JCTree tree = treeTop.fst; 358 JCCompilationUnit toplevel = treeTop.snd; 359 if (toplevel.docComments == null) 360 return null; 361 return toplevel.docComments.getCommentText(tree); 362 } 363 364 @DefinedBy(Api.LANGUAGE_MODEL) 365 public PackageElement getPackageOf(Element e) { 366 return cast(Symbol.class, e).packge(); 367 } 368 369 @DefinedBy(Api.LANGUAGE_MODEL) 370 public ModuleElement getModuleOf(Element e) { 371 Symbol sym = cast(Symbol.class, e); 372 return (sym.kind == MDL) ? ((ModuleElement) e) : sym.packge().modle; 373 } 374 375 @DefinedBy(Api.LANGUAGE_MODEL) 376 public boolean isDeprecated(Element e) { 377 Symbol sym = cast(Symbol.class, e); 378 return (sym.flags() & Flags.DEPRECATED) != 0; 379 } 380 381 @DefinedBy(Api.LANGUAGE_MODEL) 382 public Name getBinaryName(TypeElement type) { 383 return cast(TypeSymbol.class, type).flatName(); 384 } 385 386 @DefinedBy(Api.LANGUAGE_MODEL) 387 public Map<MethodSymbol, Attribute> getElementValuesWithDefaults( 388 AnnotationMirror a) { 389 Attribute.Compound anno = cast(Attribute.Compound.class, a); 390 DeclaredType annotype = a.getAnnotationType(); 391 Map<MethodSymbol, Attribute> valmap = anno.getElementValues(); 392 393 for (ExecutableElement ex : 394 methodsIn(annotype.asElement().getEnclosedElements())) { 395 MethodSymbol meth = (MethodSymbol) ex; 396 Attribute defaultValue = meth.getDefaultValue(); 397 if (defaultValue != null && !valmap.containsKey(meth)) { 398 valmap.put(meth, defaultValue); 399 } 400 } 401 return valmap; 402 } 403 404 /** 405 * {@inheritDoc} 406 */ 407 @DefinedBy(Api.LANGUAGE_MODEL) 408 public FilteredMemberList getAllMembers(TypeElement element) { 409 Symbol sym = cast(Symbol.class, element); 410 WriteableScope scope = sym.members().dupUnshared(); 411 List<Type> closure = types.closure(sym.asType()); 412 for (Type t : closure) 413 addMembers(scope, t); 414 return new FilteredMemberList(scope); 415 } 416 // where 417 private void addMembers(WriteableScope scope, Type type) { 418 members: 419 for (Symbol e : type.asElement().members().getSymbols(NON_RECURSIVE)) { 420 for (Symbol overrider : scope.getSymbolsByName(e.getSimpleName())) { 421 if (overrider.kind == e.kind && (overrider.flags() & Flags.SYNTHETIC) == 0) { 422 if (overrider.getKind() == ElementKind.METHOD && 423 overrides((ExecutableElement)overrider, (ExecutableElement)e, (TypeElement)type.asElement())) { 424 continue members; 425 } 426 } 427 } 428 boolean derived = e.getEnclosingElement() != scope.owner; 429 ElementKind kind = e.getKind(); 430 boolean initializer = kind == ElementKind.CONSTRUCTOR 431 || kind == ElementKind.INSTANCE_INIT 432 || kind == ElementKind.STATIC_INIT; 433 if (!derived || (!initializer && e.isInheritedIn(scope.owner, types))) 434 scope.enter(e); 435 } 436 } 437 438 /** 439 * Returns all annotations of an element, whether 440 * inherited or directly present. 441 * 442 * @param e the element being examined 443 * @return all annotations of the element 444 */ 445 @Override @DefinedBy(Api.LANGUAGE_MODEL) 446 public List<Attribute.Compound> getAllAnnotationMirrors(Element e) { 447 Symbol sym = cast(Symbol.class, e); 448 List<Attribute.Compound> annos = sym.getAnnotationMirrors(); 449 while (sym.getKind() == ElementKind.CLASS) { 450 Type sup = ((ClassSymbol) sym).getSuperclass(); 451 if (!sup.hasTag(CLASS) || sup.isErroneous() || 452 sup.tsym == syms.objectType.tsym) { 453 break; 454 } 455 sym = sup.tsym; 456 List<Attribute.Compound> oldAnnos = annos; 457 List<Attribute.Compound> newAnnos = sym.getAnnotationMirrors(); 458 for (Attribute.Compound anno : newAnnos) { 459 if (isInherited(anno.type) && 460 !containsAnnoOfType(oldAnnos, anno.type)) { 461 annos = annos.prepend(anno); 462 } 463 } 464 } 465 return annos; 466 } 467 468 /** 469 * Tests whether an annotation type is @Inherited. 470 */ 471 private boolean isInherited(Type annotype) { 472 return annotype.tsym.attribute(syms.inheritedType.tsym) != null; 473 } 474 475 /** 476 * Tests whether a list of annotations contains an annotation 477 * of a given type. 478 */ 479 private static boolean containsAnnoOfType(List<Attribute.Compound> annos, 480 Type type) { 481 for (Attribute.Compound anno : annos) { 482 if (anno.type.tsym == type.tsym) 483 return true; 484 } 485 return false; 486 } 487 488 @DefinedBy(Api.LANGUAGE_MODEL) 489 public boolean hides(Element hiderEl, Element hideeEl) { 490 Symbol hider = cast(Symbol.class, hiderEl); 491 Symbol hidee = cast(Symbol.class, hideeEl); 492 493 // Fields only hide fields; methods only methods; types only types. 494 // Names must match. Nothing hides itself (just try it). 495 if (hider == hidee || 496 hider.kind != hidee.kind || 497 hider.name != hidee.name) { 498 return false; 499 } 500 501 // Only static methods can hide other methods. 502 // Methods only hide methods with matching signatures. 503 if (hider.kind == MTH) { 504 if (!hider.isStatic() || 505 !types.isSubSignature(hider.type, hidee.type)) { 506 return false; 507 } 508 } 509 510 // Hider must be in a subclass of hidee's class. 511 // Note that if M1 hides M2, and M2 hides M3, and M3 is accessible 512 // in M1's class, then M1 and M2 both hide M3. 513 ClassSymbol hiderClass = hider.owner.enclClass(); 514 ClassSymbol hideeClass = hidee.owner.enclClass(); 515 if (hiderClass == null || hideeClass == null || 516 !hiderClass.isSubClass(hideeClass, types)) { 517 return false; 518 } 519 520 // Hidee must be accessible in hider's class. 521 // The method isInheritedIn is poorly named: it checks only access. 522 return hidee.isInheritedIn(hiderClass, types); 523 } 524 525 @DefinedBy(Api.LANGUAGE_MODEL) 526 public boolean overrides(ExecutableElement riderEl, 527 ExecutableElement rideeEl, TypeElement typeEl) { 528 MethodSymbol rider = cast(MethodSymbol.class, riderEl); 529 MethodSymbol ridee = cast(MethodSymbol.class, rideeEl); 530 ClassSymbol origin = cast(ClassSymbol.class, typeEl); 531 532 return rider.name == ridee.name && 533 534 // not reflexive as per JLS 535 rider != ridee && 536 537 // we don't care if ridee is static, though that wouldn't 538 // compile 539 !rider.isStatic() && 540 541 // Symbol.overrides assumes the following 542 ridee.isMemberOf(origin, types) && 543 544 // check access and signatures; don't check return types 545 rider.overrides(ridee, origin, types, false); 546 } 547 548 @DefinedBy(Api.LANGUAGE_MODEL) 549 public String getConstantExpression(Object value) { 550 return Constants.format(value); 551 } 552 553 /** 554 * Print a representation of the elements to the given writer in 555 * the specified order. The main purpose of this method is for 556 * diagnostics. The exact format of the output is <em>not</em> 557 * specified and is subject to change. 558 * 559 * @param w the writer to print the output to 560 * @param elements the elements to print 561 */ 562 @DefinedBy(Api.LANGUAGE_MODEL) 563 public void printElements(java.io.Writer w, Element... elements) { 564 for (Element element : elements) 565 (new PrintingProcessor.PrintingElementVisitor(w, this)).visit(element).flush(); 566 } 567 568 @DefinedBy(Api.LANGUAGE_MODEL) 569 public Name getName(CharSequence cs) { 570 return names.fromString(cs.toString()); 571 } 572 573 @Override @DefinedBy(Api.LANGUAGE_MODEL) 574 public boolean isFunctionalInterface(TypeElement element) { 575 if (element.getKind() != ElementKind.INTERFACE) 576 return false; 577 else { 578 TypeSymbol tsym = cast(TypeSymbol.class, element); 579 return types.isFunctionalInterface(tsym); 580 } 581 } 582 583 /** 584 * Returns the tree node and compilation unit corresponding to this 585 * element, or null if they can't be found. 586 */ 587 private Pair<JCTree, JCCompilationUnit> getTreeAndTopLevel(Element e) { 588 Symbol sym = cast(Symbol.class, e); 589 Env<AttrContext> enterEnv = getEnterEnv(sym); 590 if (enterEnv == null) 591 return null; 592 JCTree tree = TreeInfo.declarationFor(sym, enterEnv.tree); 593 if (tree == null || enterEnv.toplevel == null) 594 return null; 595 return new Pair<>(tree, enterEnv.toplevel); 596 } 597 598 /** 599 * Returns the best approximation for the tree node and compilation unit 600 * corresponding to the given element, annotation and value. 601 * If the element is null, null is returned. 602 * If the annotation is null or cannot be found, the tree node and 603 * compilation unit for the element is returned. 604 * If the annotation value is null or cannot be found, the tree node and 605 * compilation unit for the annotation is returned. 606 */ 607 public Pair<JCTree, JCCompilationUnit> getTreeAndTopLevel( 608 Element e, AnnotationMirror a, AnnotationValue v) { 609 if (e == null) 610 return null; 611 612 Pair<JCTree, JCCompilationUnit> elemTreeTop = getTreeAndTopLevel(e); 613 if (elemTreeTop == null) 614 return null; 615 616 if (a == null) 617 return elemTreeTop; 618 619 JCTree annoTree = matchAnnoToTree(a, e, elemTreeTop.fst); 620 if (annoTree == null) 621 return elemTreeTop; 622 623 // 6388543: if v != null, we should search within annoTree to find 624 // the tree matching v. For now, we ignore v and return the tree of 625 // the annotation. 626 return new Pair<>(annoTree, elemTreeTop.snd); 627 } 628 629 /** 630 * Returns a symbol's enter environment, or null if it has none. 631 */ 632 private Env<AttrContext> getEnterEnv(Symbol sym) { 633 // Get enclosing class of sym, or sym itself if it is a class 634 // package, or module. 635 TypeSymbol ts = null; 636 switch (sym.kind) { 637 case PCK: 638 ts = (PackageSymbol)sym; 639 break; 640 case MDL: 641 ts = (ModuleSymbol)sym; 642 break; 643 default: 644 ts = sym.enclClass(); 645 } 646 return (ts != null) 647 ? enter.getEnv(ts) 648 : null; 649 } 650 651 private void ensureEntered(String methodName) { 652 if (javacTaskImpl != null) { 653 javacTaskImpl.ensureEntered(); 654 } 655 if (!javaCompiler.isEnterDone()) { 656 throw new IllegalStateException("Cannot use Elements." + methodName + " before the TaskEvent.Kind.ENTER finished event."); 657 } 658 } 659 660 /** 661 * Returns an object cast to the specified type. 662 * @throws NullPointerException if the object is {@code null} 663 * @throws IllegalArgumentException if the object is of the wrong type 664 */ 665 private static <T> T cast(Class<T> clazz, Object o) { 666 if (! clazz.isInstance(o)) 667 throw new IllegalArgumentException(o.toString()); 668 return clazz.cast(o); 669 } 670} 671