JavacElements.java revision 3824:376ee1fd40c3
1/* 2 * Copyright (c) 2005, 2016, 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 26package com.sun.tools.javac.model; 27 28import java.util.LinkedHashSet; 29import java.util.Map; 30import java.util.Set; 31 32import javax.lang.model.SourceVersion; 33import javax.lang.model.element.*; 34import javax.lang.model.type.DeclaredType; 35import javax.lang.model.util.Elements; 36import javax.tools.JavaFileObject; 37import static javax.lang.model.util.ElementFilter.methodsIn; 38 39import com.sun.source.util.JavacTask; 40import com.sun.tools.javac.api.JavacTaskImpl; 41import com.sun.tools.javac.code.*; 42import com.sun.tools.javac.code.Scope.WriteableScope; 43import com.sun.tools.javac.code.Symbol.*; 44import com.sun.tools.javac.comp.AttrContext; 45import com.sun.tools.javac.comp.Enter; 46import com.sun.tools.javac.comp.Env; 47import com.sun.tools.javac.main.JavaCompiler; 48import com.sun.tools.javac.processing.PrintingProcessor; 49import com.sun.tools.javac.tree.JCTree; 50import com.sun.tools.javac.tree.JCTree.*; 51import com.sun.tools.javac.tree.TreeInfo; 52import com.sun.tools.javac.tree.TreeScanner; 53import com.sun.tools.javac.util.*; 54import com.sun.tools.javac.util.DefinedBy.Api; 55import com.sun.tools.javac.util.Name; 56import static com.sun.tools.javac.code.Kinds.Kind.*; 57import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE; 58import static com.sun.tools.javac.code.TypeTag.CLASS; 59import com.sun.tools.javac.comp.Modules; 60import com.sun.tools.javac.comp.Resolve; 61import com.sun.tools.javac.comp.Resolve.RecoveryLoadClass; 62import static com.sun.tools.javac.tree.JCTree.Tag.*; 63 64/** 65 * Utility methods for operating on program elements. 66 * 67 * <p><b>This is NOT part of any supported API. 68 * If you write code that depends on this, you do so at your own 69 * risk. This code and its internal interfaces are subject to change 70 * or deletion without notice.</b></p> 71 */ 72public class JavacElements implements Elements { 73 74 private final JavaCompiler javaCompiler; 75 private final Symtab syms; 76 private final Modules modules; 77 private final Names names; 78 private final Types types; 79 private final Enter enter; 80 private final Resolve resolve; 81 private final JavacTaskImpl javacTaskImpl; 82 83 public static JavacElements instance(Context context) { 84 JavacElements instance = context.get(JavacElements.class); 85 if (instance == null) 86 instance = new JavacElements(context); 87 return instance; 88 } 89 90 protected JavacElements(Context context) { 91 context.put(JavacElements.class, this); 92 javaCompiler = JavaCompiler.instance(context); 93 syms = Symtab.instance(context); 94 modules = Modules.instance(context); 95 names = Names.instance(context); 96 types = Types.instance(context); 97 enter = Enter.instance(context); 98 resolve = Resolve.instance(context); 99 JavacTask t = context.get(JavacTask.class); 100 javacTaskImpl = t instanceof JavacTaskImpl ? (JavacTaskImpl) t : null; 101 } 102 103 @Override @DefinedBy(Api.LANGUAGE_MODEL) 104 public ModuleSymbol getModuleElement(CharSequence name) { 105 ensureEntered("getModuleElement"); 106 if (modules.getDefaultModule() == syms.noModule) 107 return null; 108 String strName = name.toString(); 109 if (strName.equals("")) 110 return syms.unnamedModule; 111 return modules.getObservableModule(names.fromString(strName)); 112 } 113 114 @Override @DefinedBy(Api.LANGUAGE_MODEL) 115 public PackageSymbol getPackageElement(CharSequence name) { 116 return doGetPackageElement(null, name); 117 } 118 119 @Override @DefinedBy(Api.LANGUAGE_MODEL) 120 public PackageSymbol getPackageElement(ModuleElement module, CharSequence name) { 121 module.getClass(); 122 return doGetPackageElement(module, name); 123 } 124 125 private PackageSymbol doGetPackageElement(ModuleElement module, CharSequence name) { 126 ensureEntered("getPackageElement"); 127 if (name.length() == 0) 128 return syms.unnamedModule.unnamedPackage; 129 return doGetElement(module, name, PackageSymbol.class); 130 } 131 132 @Override @DefinedBy(Api.LANGUAGE_MODEL) 133 public ClassSymbol getTypeElement(CharSequence name) { 134 return doGetTypeElement(null, name); 135 } 136 137 @Override @DefinedBy(Api.LANGUAGE_MODEL) 138 public ClassSymbol getTypeElement(ModuleElement module, CharSequence name) { 139 module.getClass(); 140 141 return doGetTypeElement(module, name); 142 } 143 144 private ClassSymbol doGetTypeElement(ModuleElement module, CharSequence name) { 145 ensureEntered("getTypeElement"); 146 return doGetElement(module, name, ClassSymbol.class); 147 } 148 149 private <S extends Symbol> S doGetElement(ModuleElement module, CharSequence name, Class<S> clazz) { 150 String strName = name.toString(); 151 if (!SourceVersion.isName(strName)) { 152 return null; 153 } 154 if (module == null) { 155 return unboundNameToSymbol(strName, clazz); 156 } else { 157 return nameToSymbol((ModuleSymbol) module, strName, clazz); 158 } 159 } 160 161 private <S extends Symbol> S unboundNameToSymbol(String nameStr, Class<S> clazz) { 162 if (modules.getDefaultModule() == syms.noModule) { //not a modular mode: 163 return nameToSymbol(syms.noModule, nameStr, clazz); 164 } 165 166 RecoveryLoadClass prevRecoveryLoadClass = resolve.setRecoveryLoadClass((env, name) -> null); 167 try { 168 Set<S> found = new LinkedHashSet<>(); 169 170 for (ModuleSymbol msym : modules.allModules()) { 171 S sym = nameToSymbol(msym, nameStr, clazz); 172 173 if (sym != null) { 174 found.add(sym); 175 } 176 } 177 178 if (found.size() == 1) { 179 return found.iterator().next(); 180 } else { 181 //not found, or more than one element found: 182 return null; 183 } 184 } finally { 185 resolve.setRecoveryLoadClass(prevRecoveryLoadClass); 186 } 187 } 188 189 /** 190 * Returns a symbol given the type's or package's canonical name, 191 * or null if the name isn't found. 192 */ 193 private <S extends Symbol> S nameToSymbol(ModuleSymbol module, String nameStr, Class<S> clazz) { 194 Name name = names.fromString(nameStr); 195 // First check cache. 196 Symbol sym = (clazz == ClassSymbol.class) 197 ? syms.getClass(module, name) 198 : syms.lookupPackage(module, name); 199 200 try { 201 if (sym == null) 202 sym = javaCompiler.resolveIdent(module, nameStr); 203 204 sym.complete(); 205 206 return (sym.kind != ERR && 207 sym.exists() && 208 clazz.isInstance(sym) && 209 name.equals(sym.getQualifiedName())) 210 ? clazz.cast(sym) 211 : null; 212 } catch (CompletionFailure e) { 213 return null; 214 } 215 } 216 217 public JavacSourcePosition getSourcePosition(Element e) { 218 Pair<JCTree, JCCompilationUnit> treeTop = getTreeAndTopLevel(e); 219 if (treeTop == null) 220 return null; 221 JCTree tree = treeTop.fst; 222 JCCompilationUnit toplevel = treeTop.snd; 223 JavaFileObject sourcefile = toplevel.sourcefile; 224 if (sourcefile == null) 225 return null; 226 return new JavacSourcePosition(sourcefile, tree.pos, toplevel.lineMap); 227 } 228 229 public JavacSourcePosition getSourcePosition(Element e, AnnotationMirror a) { 230 Pair<JCTree, JCCompilationUnit> treeTop = getTreeAndTopLevel(e); 231 if (treeTop == null) 232 return null; 233 JCTree tree = treeTop.fst; 234 JCCompilationUnit toplevel = treeTop.snd; 235 JavaFileObject sourcefile = toplevel.sourcefile; 236 if (sourcefile == null) 237 return null; 238 239 JCTree annoTree = matchAnnoToTree(a, e, tree); 240 if (annoTree == null) 241 return null; 242 return new JavacSourcePosition(sourcefile, annoTree.pos, 243 toplevel.lineMap); 244 } 245 246 public JavacSourcePosition getSourcePosition(Element e, AnnotationMirror a, 247 AnnotationValue v) { 248 // TODO: better accuracy in getSourcePosition(... AnnotationValue) 249 return getSourcePosition(e, a); 250 } 251 252 /** 253 * Returns the tree for an annotation given the annotated element 254 * and the element's own tree. Returns null if the tree cannot be found. 255 */ 256 private JCTree matchAnnoToTree(AnnotationMirror findme, 257 Element e, JCTree tree) { 258 Symbol sym = cast(Symbol.class, e); 259 class Vis extends JCTree.Visitor { 260 List<JCAnnotation> result = null; 261 public void visitPackageDef(JCPackageDecl tree) { 262 result = tree.annotations; 263 } 264 public void visitClassDef(JCClassDecl tree) { 265 result = tree.mods.annotations; 266 } 267 public void visitMethodDef(JCMethodDecl tree) { 268 result = tree.mods.annotations; 269 } 270 public void visitVarDef(JCVariableDecl tree) { 271 result = tree.mods.annotations; 272 } 273 @Override 274 public void visitTypeParameter(JCTypeParameter tree) { 275 result = tree.annotations; 276 } 277 } 278 Vis vis = new Vis(); 279 tree.accept(vis); 280 if (vis.result == null) 281 return null; 282 283 List<Attribute.Compound> annos = sym.getAnnotationMirrors(); 284 return matchAnnoToTree(cast(Attribute.Compound.class, findme), 285 annos, 286 vis.result); 287 } 288 289 /** 290 * Returns the tree for an annotation given a list of annotations 291 * in which to search (recursively) and their corresponding trees. 292 * Returns null if the tree cannot be found. 293 */ 294 private JCTree matchAnnoToTree(Attribute.Compound findme, 295 List<Attribute.Compound> annos, 296 List<JCAnnotation> trees) { 297 for (Attribute.Compound anno : annos) { 298 for (JCAnnotation tree : trees) { 299 JCTree match = matchAnnoToTree(findme, anno, tree); 300 if (match != null) 301 return match; 302 } 303 } 304 return null; 305 } 306 307 /** 308 * Returns the tree for an annotation given an Attribute to 309 * search (recursively) and its corresponding tree. 310 * Returns null if the tree cannot be found. 311 */ 312 private JCTree matchAnnoToTree(final Attribute.Compound findme, 313 final Attribute attr, 314 final JCTree tree) { 315 if (attr == findme) 316 return (tree.type.tsym == findme.type.tsym) ? tree : null; 317 318 class Vis implements Attribute.Visitor { 319 JCTree result = null; 320 public void visitConstant(Attribute.Constant value) { 321 } 322 public void visitClass(Attribute.Class clazz) { 323 } 324 public void visitCompound(Attribute.Compound anno) { 325 for (Pair<MethodSymbol, Attribute> pair : anno.values) { 326 JCExpression expr = scanForAssign(pair.fst, tree); 327 if (expr != null) { 328 JCTree match = matchAnnoToTree(findme, pair.snd, expr); 329 if (match != null) { 330 result = match; 331 return; 332 } 333 } 334 } 335 } 336 public void visitArray(Attribute.Array array) { 337 if (tree.hasTag(NEWARRAY) && 338 types.elemtype(array.type).tsym == findme.type.tsym) { 339 List<JCExpression> elems = ((JCNewArray) tree).elems; 340 for (Attribute value : array.values) { 341 if (value == findme) { 342 result = elems.head; 343 return; 344 } 345 elems = elems.tail; 346 } 347 } 348 } 349 public void visitEnum(Attribute.Enum e) { 350 } 351 public void visitError(Attribute.Error e) { 352 } 353 } 354 Vis vis = new Vis(); 355 attr.accept(vis); 356 return vis.result; 357 } 358 359 /** 360 * Scans for a JCAssign node with a LHS matching a given 361 * symbol, and returns its RHS. Does not scan nested JCAnnotations. 362 */ 363 private JCExpression scanForAssign(final MethodSymbol sym, 364 final JCTree tree) { 365 class TS extends TreeScanner { 366 JCExpression result = null; 367 public void scan(JCTree t) { 368 if (t != null && result == null) 369 t.accept(this); 370 } 371 public void visitAnnotation(JCAnnotation t) { 372 if (t == tree) 373 scan(t.args); 374 } 375 public void visitAssign(JCAssign t) { 376 if (t.lhs.hasTag(IDENT)) { 377 JCIdent ident = (JCIdent) t.lhs; 378 if (ident.sym == sym) 379 result = t.rhs; 380 } 381 } 382 } 383 TS scanner = new TS(); 384 tree.accept(scanner); 385 return scanner.result; 386 } 387 388 /** 389 * Returns the tree node corresponding to this element, or null 390 * if none can be found. 391 */ 392 public JCTree getTree(Element e) { 393 Pair<JCTree, ?> treeTop = getTreeAndTopLevel(e); 394 return (treeTop != null) ? treeTop.fst : null; 395 } 396 397 @DefinedBy(Api.LANGUAGE_MODEL) 398 public String getDocComment(Element e) { 399 // Our doc comment is contained in a map in our toplevel, 400 // indexed by our tree. Find our enter environment, which gives 401 // us our toplevel. It also gives us a tree that contains our 402 // tree: walk it to find our tree. This is painful. 403 Pair<JCTree, JCCompilationUnit> treeTop = getTreeAndTopLevel(e); 404 if (treeTop == null) 405 return null; 406 JCTree tree = treeTop.fst; 407 JCCompilationUnit toplevel = treeTop.snd; 408 if (toplevel.docComments == null) 409 return null; 410 return toplevel.docComments.getCommentText(tree); 411 } 412 413 @DefinedBy(Api.LANGUAGE_MODEL) 414 public PackageElement getPackageOf(Element e) { 415 return cast(Symbol.class, e).packge(); 416 } 417 418 @DefinedBy(Api.LANGUAGE_MODEL) 419 public ModuleElement getModuleOf(Element e) { 420 Symbol sym = cast(Symbol.class, e); 421 if (modules.getDefaultModule() == syms.noModule) 422 return null; 423 return (sym.kind == MDL) ? ((ModuleElement) e) : sym.packge().modle; 424 } 425 426 @DefinedBy(Api.LANGUAGE_MODEL) 427 public boolean isDeprecated(Element e) { 428 Symbol sym = cast(Symbol.class, e); 429 sym.complete(); 430 return sym.isDeprecated(); 431 } 432 433 @DefinedBy(Api.LANGUAGE_MODEL) 434 public Name getBinaryName(TypeElement type) { 435 return cast(TypeSymbol.class, type).flatName(); 436 } 437 438 @DefinedBy(Api.LANGUAGE_MODEL) 439 public Map<MethodSymbol, Attribute> getElementValuesWithDefaults( 440 AnnotationMirror a) { 441 Attribute.Compound anno = cast(Attribute.Compound.class, a); 442 DeclaredType annotype = a.getAnnotationType(); 443 Map<MethodSymbol, Attribute> valmap = anno.getElementValues(); 444 445 for (ExecutableElement ex : 446 methodsIn(annotype.asElement().getEnclosedElements())) { 447 MethodSymbol meth = (MethodSymbol) ex; 448 Attribute defaultValue = meth.getDefaultValue(); 449 if (defaultValue != null && !valmap.containsKey(meth)) { 450 valmap.put(meth, defaultValue); 451 } 452 } 453 return valmap; 454 } 455 456 /** 457 * {@inheritDoc} 458 */ 459 @DefinedBy(Api.LANGUAGE_MODEL) 460 public FilteredMemberList getAllMembers(TypeElement element) { 461 Symbol sym = cast(Symbol.class, element); 462 WriteableScope scope = sym.members().dupUnshared(); 463 List<Type> closure = types.closure(sym.asType()); 464 for (Type t : closure) 465 addMembers(scope, t); 466 return new FilteredMemberList(scope); 467 } 468 // where 469 private void addMembers(WriteableScope scope, Type type) { 470 members: 471 for (Symbol e : type.asElement().members().getSymbols(NON_RECURSIVE)) { 472 for (Symbol overrider : scope.getSymbolsByName(e.getSimpleName())) { 473 if (overrider.kind == e.kind && (overrider.flags() & Flags.SYNTHETIC) == 0) { 474 if (overrider.getKind() == ElementKind.METHOD && 475 overrides((ExecutableElement)overrider, (ExecutableElement)e, (TypeElement)type.asElement())) { 476 continue members; 477 } 478 } 479 } 480 boolean derived = e.getEnclosingElement() != scope.owner; 481 ElementKind kind = e.getKind(); 482 boolean initializer = kind == ElementKind.CONSTRUCTOR 483 || kind == ElementKind.INSTANCE_INIT 484 || kind == ElementKind.STATIC_INIT; 485 if (!derived || (!initializer && e.isInheritedIn(scope.owner, types))) 486 scope.enter(e); 487 } 488 } 489 490 /** 491 * Returns all annotations of an element, whether 492 * inherited or directly present. 493 * 494 * @param e the element being examined 495 * @return all annotations of the element 496 */ 497 @Override @DefinedBy(Api.LANGUAGE_MODEL) 498 public List<Attribute.Compound> getAllAnnotationMirrors(Element e) { 499 Symbol sym = cast(Symbol.class, e); 500 List<Attribute.Compound> annos = sym.getAnnotationMirrors(); 501 while (sym.getKind() == ElementKind.CLASS) { 502 Type sup = ((ClassSymbol) sym).getSuperclass(); 503 if (!sup.hasTag(CLASS) || sup.isErroneous() || 504 sup.tsym == syms.objectType.tsym) { 505 break; 506 } 507 sym = sup.tsym; 508 List<Attribute.Compound> oldAnnos = annos; 509 List<Attribute.Compound> newAnnos = sym.getAnnotationMirrors(); 510 for (Attribute.Compound anno : newAnnos) { 511 if (isInherited(anno.type) && 512 !containsAnnoOfType(oldAnnos, anno.type)) { 513 annos = annos.prepend(anno); 514 } 515 } 516 } 517 return annos; 518 } 519 520 /** 521 * Tests whether an annotation type is @Inherited. 522 */ 523 private boolean isInherited(Type annotype) { 524 return annotype.tsym.attribute(syms.inheritedType.tsym) != null; 525 } 526 527 /** 528 * Tests whether a list of annotations contains an annotation 529 * of a given type. 530 */ 531 private static boolean containsAnnoOfType(List<Attribute.Compound> annos, 532 Type type) { 533 for (Attribute.Compound anno : annos) { 534 if (anno.type.tsym == type.tsym) 535 return true; 536 } 537 return false; 538 } 539 540 @DefinedBy(Api.LANGUAGE_MODEL) 541 public boolean hides(Element hiderEl, Element hideeEl) { 542 Symbol hider = cast(Symbol.class, hiderEl); 543 Symbol hidee = cast(Symbol.class, hideeEl); 544 545 // Fields only hide fields; methods only methods; types only types. 546 // Names must match. Nothing hides itself (just try it). 547 if (hider == hidee || 548 hider.kind != hidee.kind || 549 hider.name != hidee.name) { 550 return false; 551 } 552 553 // Only static methods can hide other methods. 554 // Methods only hide methods with matching signatures. 555 if (hider.kind == MTH) { 556 if (!hider.isStatic() || 557 !types.isSubSignature(hider.type, hidee.type)) { 558 return false; 559 } 560 } 561 562 // Hider must be in a subclass of hidee's class. 563 // Note that if M1 hides M2, and M2 hides M3, and M3 is accessible 564 // in M1's class, then M1 and M2 both hide M3. 565 ClassSymbol hiderClass = hider.owner.enclClass(); 566 ClassSymbol hideeClass = hidee.owner.enclClass(); 567 if (hiderClass == null || hideeClass == null || 568 !hiderClass.isSubClass(hideeClass, types)) { 569 return false; 570 } 571 572 // Hidee must be accessible in hider's class. 573 // The method isInheritedIn is poorly named: it checks only access. 574 return hidee.isInheritedIn(hiderClass, types); 575 } 576 577 @DefinedBy(Api.LANGUAGE_MODEL) 578 public boolean overrides(ExecutableElement riderEl, 579 ExecutableElement rideeEl, TypeElement typeEl) { 580 MethodSymbol rider = cast(MethodSymbol.class, riderEl); 581 MethodSymbol ridee = cast(MethodSymbol.class, rideeEl); 582 ClassSymbol origin = cast(ClassSymbol.class, typeEl); 583 584 return rider.name == ridee.name && 585 586 // not reflexive as per JLS 587 rider != ridee && 588 589 // we don't care if ridee is static, though that wouldn't 590 // compile 591 !rider.isStatic() && 592 593 // Symbol.overrides assumes the following 594 ridee.isMemberOf(origin, types) && 595 596 // check access and signatures; don't check return types 597 rider.overrides(ridee, origin, types, false); 598 } 599 600 @DefinedBy(Api.LANGUAGE_MODEL) 601 public String getConstantExpression(Object value) { 602 return Constants.format(value); 603 } 604 605 /** 606 * Print a representation of the elements to the given writer in 607 * the specified order. The main purpose of this method is for 608 * diagnostics. The exact format of the output is <em>not</em> 609 * specified and is subject to change. 610 * 611 * @param w the writer to print the output to 612 * @param elements the elements to print 613 */ 614 @DefinedBy(Api.LANGUAGE_MODEL) 615 public void printElements(java.io.Writer w, Element... elements) { 616 for (Element element : elements) 617 (new PrintingProcessor.PrintingElementVisitor(w, this)).visit(element).flush(); 618 } 619 620 @DefinedBy(Api.LANGUAGE_MODEL) 621 public Name getName(CharSequence cs) { 622 return names.fromString(cs.toString()); 623 } 624 625 @Override @DefinedBy(Api.LANGUAGE_MODEL) 626 public boolean isFunctionalInterface(TypeElement element) { 627 if (element.getKind() != ElementKind.INTERFACE) 628 return false; 629 else { 630 TypeSymbol tsym = cast(TypeSymbol.class, element); 631 return types.isFunctionalInterface(tsym); 632 } 633 } 634 635 /** 636 * Returns the tree node and compilation unit corresponding to this 637 * element, or null if they can't be found. 638 */ 639 private Pair<JCTree, JCCompilationUnit> getTreeAndTopLevel(Element e) { 640 Symbol sym = cast(Symbol.class, e); 641 Env<AttrContext> enterEnv = getEnterEnv(sym); 642 if (enterEnv == null) 643 return null; 644 JCTree tree = TreeInfo.declarationFor(sym, enterEnv.tree); 645 if (tree == null || enterEnv.toplevel == null) 646 return null; 647 return new Pair<>(tree, enterEnv.toplevel); 648 } 649 650 /** 651 * Returns the best approximation for the tree node and compilation unit 652 * corresponding to the given element, annotation and value. 653 * If the element is null, null is returned. 654 * If the annotation is null or cannot be found, the tree node and 655 * compilation unit for the element is returned. 656 * If the annotation value is null or cannot be found, the tree node and 657 * compilation unit for the annotation is returned. 658 */ 659 public Pair<JCTree, JCCompilationUnit> getTreeAndTopLevel( 660 Element e, AnnotationMirror a, AnnotationValue v) { 661 if (e == null) 662 return null; 663 664 Pair<JCTree, JCCompilationUnit> elemTreeTop = getTreeAndTopLevel(e); 665 if (elemTreeTop == null) 666 return null; 667 668 if (a == null) 669 return elemTreeTop; 670 671 JCTree annoTree = matchAnnoToTree(a, e, elemTreeTop.fst); 672 if (annoTree == null) 673 return elemTreeTop; 674 675 // 6388543: if v != null, we should search within annoTree to find 676 // the tree matching v. For now, we ignore v and return the tree of 677 // the annotation. 678 return new Pair<>(annoTree, elemTreeTop.snd); 679 } 680 681 /** 682 * Returns a symbol's enter environment, or null if it has none. 683 */ 684 private Env<AttrContext> getEnterEnv(Symbol sym) { 685 // Get enclosing class of sym, or sym itself if it is a class 686 // package, or module. 687 TypeSymbol ts = null; 688 switch (sym.kind) { 689 case PCK: 690 ts = (PackageSymbol)sym; 691 break; 692 case MDL: 693 ts = (ModuleSymbol)sym; 694 break; 695 default: 696 ts = sym.enclClass(); 697 } 698 return (ts != null) 699 ? enter.getEnv(ts) 700 : null; 701 } 702 703 private void ensureEntered(String methodName) { 704 if (javacTaskImpl != null) { 705 javacTaskImpl.ensureEntered(); 706 } 707 if (!javaCompiler.isEnterDone()) { 708 throw new IllegalStateException("Cannot use Elements." + methodName + " before the TaskEvent.Kind.ENTER finished event."); 709 } 710 } 711 712 /** 713 * Returns an object cast to the specified type. 714 * @throws NullPointerException if the object is {@code null} 715 * @throws IllegalArgumentException if the object is of the wrong type 716 */ 717 private static <T> T cast(Class<T> clazz, Object o) { 718 if (! clazz.isInstance(o)) 719 throw new IllegalArgumentException(o.toString()); 720 return clazz.cast(o); 721 } 722} 723