1 /*
2 * Copyright (c) 1999, 2025, 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.code;
27
28 import java.lang.annotation.Annotation;
29 import java.lang.annotation.Inherited;
30 import java.util.ArrayList;
31 import java.util.Collections;
32 import java.util.EnumSet;
33 import java.util.HashMap;
34 import java.util.Map;
35 import java.util.Set;
36 import java.util.concurrent.Callable;
37 import java.util.function.Supplier;
38 import java.util.function.Predicate;
39
40 import javax.lang.model.element.Element;
41 import javax.lang.model.element.ElementKind;
42 import javax.lang.model.element.ElementVisitor;
43 import javax.lang.model.element.ExecutableElement;
44 import javax.lang.model.element.Modifier;
45 import javax.lang.model.element.ModuleElement;
46 import javax.lang.model.element.NestingKind;
47 import javax.lang.model.element.PackageElement;
48 import javax.lang.model.element.RecordComponentElement;
49 import javax.lang.model.element.TypeElement;
50 import javax.lang.model.element.TypeParameterElement;
51 import javax.lang.model.element.VariableElement;
52 import javax.tools.JavaFileManager;
53 import javax.tools.JavaFileObject;
54
55 import com.sun.tools.javac.code.Kinds.Kind;
56 import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata;
57 import com.sun.tools.javac.code.Type.*;
58 import com.sun.tools.javac.comp.Attr;
59 import com.sun.tools.javac.comp.AttrContext;
60 import com.sun.tools.javac.comp.Env;
61 import com.sun.tools.javac.jvm.*;
62 import com.sun.tools.javac.jvm.PoolConstant;
63 import com.sun.tools.javac.tree.JCTree;
64 import com.sun.tools.javac.tree.JCTree.JCAnnotation;
65 import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
66 import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
67 import com.sun.tools.javac.tree.JCTree.Tag;
68 import com.sun.tools.javac.util.*;
69 import com.sun.tools.javac.util.DefinedBy.Api;
70 import com.sun.tools.javac.util.List;
71 import com.sun.tools.javac.util.Name;
72
73 import static com.sun.tools.javac.code.Flags.*;
74 import static com.sun.tools.javac.code.Kinds.*;
75 import static com.sun.tools.javac.code.Kinds.Kind.*;
76 import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
77 import com.sun.tools.javac.code.Scope.WriteableScope;
78 import static com.sun.tools.javac.code.TypeTag.CLASS;
79 import static com.sun.tools.javac.code.TypeTag.FORALL;
80 import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
81 import static com.sun.tools.javac.jvm.ByteCodes.iadd;
82 import static com.sun.tools.javac.jvm.ByteCodes.ishll;
83 import static com.sun.tools.javac.jvm.ByteCodes.lushrl;
84 import static com.sun.tools.javac.jvm.ByteCodes.lxor;
85 import static com.sun.tools.javac.jvm.ByteCodes.string_add;
86
87 /** Root class for Java symbols. It contains subclasses
88 * for specific sorts of symbols, such as variables, methods and operators,
89 * types, packages. Each subclass is represented as a static inner class
90 * inside Symbol.
91 *
92 * <p><b>This is NOT part of any supported API.
93 * If you write code that depends on this, you do so at your own risk.
94 * This code and its internal interfaces are subject to change or
95 * deletion without notice.</b>
96 */
97 public abstract class Symbol extends AnnoConstruct implements PoolConstant, Element {
98
99 /** The kind of this symbol.
100 * @see Kinds
101 */
102 public Kind kind;
103
104 /** The flags of this symbol.
105 */
106 public long flags_field;
107
108 /** An accessor method for the flags of this symbol.
109 * Flags of class symbols should be accessed through the accessor
110 * method to make sure that the class symbol is loaded.
111 */
112 public long flags() { return flags_field; }
113
114 /** The name of this symbol in Utf8 representation.
115 */
116 public Name name;
117
118 /** The type of this symbol.
119 */
120 public Type type;
121
122 /** The owner of this symbol.
123 */
124 public Symbol owner;
125
126 /** The completer of this symbol.
127 * This should never equal null (NULL_COMPLETER should be used instead).
128 */
129 public Completer completer;
130
131 /** A cache for the type erasure of this symbol.
132 */
133 public Type erasure_field;
134
135 // <editor-fold defaultstate="collapsed" desc="annotations">
136
137 /** The attributes of this symbol are contained in this
138 * SymbolMetadata. The SymbolMetadata instance is NOT immutable.
139 */
140 protected SymbolMetadata metadata;
141
142
143 /** An accessor method for the attributes of this symbol.
144 * Attributes of class symbols should be accessed through the accessor
145 * method to make sure that the class symbol is loaded.
146 */
147 public List<Attribute.Compound> getRawAttributes() {
148 return (metadata == null)
149 ? List.nil()
150 : metadata.getDeclarationAttributes();
151 }
152
153 /** An accessor method for the type attributes of this symbol.
154 * Attributes of class symbols should be accessed through the accessor
155 * method to make sure that the class symbol is loaded.
156 */
157 public List<Attribute.TypeCompound> getRawTypeAttributes() {
158 return (metadata == null)
159 ? List.nil()
160 : metadata.getTypeAttributes();
161 }
162
163 /** Fetch a particular annotation from a symbol. */
164 public Attribute.Compound attribute(Symbol anno) {
165 for (Attribute.Compound a : getRawAttributes()) {
166 if (a.type.tsym == anno) return a;
167 }
168 return null;
169 }
170
171 public boolean annotationsPendingCompletion() {
172 return metadata == null ? false : metadata.pendingCompletion();
173 }
174
175 public void appendAttributes(List<Attribute.Compound> l) {
176 if (l.nonEmpty()) {
177 initedMetadata().append(l);
178 }
179 }
180
181 public void appendClassInitTypeAttributes(List<Attribute.TypeCompound> l) {
182 if (l.nonEmpty()) {
183 initedMetadata().appendClassInitTypeAttributes(l);
184 }
185 }
186
187 public void appendInitTypeAttributes(List<Attribute.TypeCompound> l) {
188 if (l.nonEmpty()) {
189 initedMetadata().appendInitTypeAttributes(l);
190 }
191 }
192
193 public void appendUniqueTypeAttributes(List<Attribute.TypeCompound> l) {
194 if (l.nonEmpty()) {
195 initedMetadata().appendUniqueTypes(l);
196 }
197 }
198
199 public List<Attribute.TypeCompound> getClassInitTypeAttributes() {
200 return (metadata == null)
201 ? List.nil()
202 : metadata.getClassInitTypeAttributes();
203 }
204
205 public List<Attribute.TypeCompound> getInitTypeAttributes() {
206 return (metadata == null)
207 ? List.nil()
208 : metadata.getInitTypeAttributes();
209 }
210
211 public void setInitTypeAttributes(List<Attribute.TypeCompound> l) {
212 initedMetadata().setInitTypeAttributes(l);
213 }
214
215 public void setClassInitTypeAttributes(List<Attribute.TypeCompound> l) {
216 initedMetadata().setClassInitTypeAttributes(l);
217 }
218
219 public List<Attribute.Compound> getDeclarationAttributes() {
220 return (metadata == null)
221 ? List.nil()
222 : metadata.getDeclarationAttributes();
223 }
224
225 public boolean hasAnnotations() {
226 return (metadata != null && !metadata.isEmpty());
227 }
228
229 public boolean hasTypeAnnotations() {
230 return (metadata != null && !metadata.isTypesEmpty());
231 }
232
233 public boolean isCompleted() {
234 return completer.isTerminal();
235 }
236
237 public void prependAttributes(List<Attribute.Compound> l) {
238 if (l.nonEmpty()) {
239 initedMetadata().prepend(l);
240 }
241 }
242
243 public void resetAnnotations() {
244 initedMetadata().reset();
245 }
246
247 public void setAttributes(Symbol other) {
248 if (metadata != null || other.metadata != null) {
249 initedMetadata().setAttributes(other.metadata);
250 }
251 }
252
253 public void setDeclarationAttributes(List<Attribute.Compound> a) {
254 if (metadata != null || a.nonEmpty()) {
255 initedMetadata().setDeclarationAttributes(a);
256 }
257 }
258
259 public void setTypeAttributes(List<Attribute.TypeCompound> a) {
260 if (metadata != null || a.nonEmpty()) {
261 if (metadata == null)
262 metadata = new SymbolMetadata(this);
263 metadata.setTypeAttributes(a);
264 }
265 }
266
267 private SymbolMetadata initedMetadata() {
268 if (metadata == null)
269 metadata = new SymbolMetadata(this);
270 return metadata;
271 }
272
273 /** This method is intended for debugging only. */
274 public SymbolMetadata getMetadata() {
275 return metadata;
276 }
277
278 // </editor-fold>
279
280 /** Construct a symbol with given kind, flags, name, type and owner.
281 */
282 public Symbol(Kind kind, long flags, Name name, Type type, Symbol owner) {
283 this.kind = kind;
284 this.flags_field = flags;
285 this.type = type;
286 this.owner = owner;
287 this.completer = Completer.NULL_COMPLETER;
288 this.erasure_field = null;
289 this.name = name;
290 }
291
292 @Override
293 public int poolTag() {
294 throw new AssertionError("Invalid pool entry");
295 }
296
297 /** Clone this symbol with new owner.
298 * Legal only for fields and methods.
299 */
300 public Symbol clone(Symbol newOwner) {
301 throw new AssertionError();
302 }
303
304 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
305 return v.visitSymbol(this, p);
306 }
307
308 /** The Java source which this symbol represents.
309 * A description of this symbol; overrides Object.
310 */
311 public String toString() {
312 return name.toString();
313 }
314
315 /** A Java source description of the location of this symbol; used for
316 * error reporting.
317 *
318 * @return null if the symbol is a package or a toplevel class defined in
319 * the default package; otherwise, the owner symbol is returned
320 */
321 public Symbol location() {
322 if (owner.name == null || (owner.name.isEmpty() &&
323 (owner.flags() & BLOCK) == 0 &&
324 owner.kind != PCK &&
325 owner.kind != TYP)) {
326 return null;
327 }
328 return owner;
329 }
330
331 public Symbol location(Type site, Types types) {
332 if (owner.name == null || owner.name.isEmpty()) {
333 return location();
334 }
335 if (owner.type.hasTag(CLASS)) {
336 Type ownertype = types.asOuterSuper(site, owner);
337 if (ownertype != null) return ownertype.tsym;
338 }
339 return owner;
340 }
341
342 public Symbol baseSymbol() {
343 return this;
344 }
345
346 /** The symbol's erased type.
347 */
348 public Type erasure(Types types) {
349 if (erasure_field == null)
350 erasure_field = types.erasure(type);
351 return erasure_field;
352 }
353
354 /** The external type of a symbol. This is the symbol's erased type
355 * except for constructors of inner classes which get the enclosing
356 * instance class added as first argument.
357 */
358 public Type externalType(Types types) {
359 Type t = erasure(types);
360 if (name == name.table.names.init && owner.hasOuterInstance()) {
361 Type outerThisType = owner.innermostAccessibleEnclosingClass().erasure(types);
362 return new MethodType(t.getParameterTypes().prepend(outerThisType),
363 t.getReturnType(),
364 t.getThrownTypes(),
365 t.tsym);
366 } else {
367 return t;
368 }
369 }
370
371 public boolean isDeprecated() {
372 return (flags_field & DEPRECATED) != 0;
373 }
374
375 public boolean hasDeprecatedAnnotation() {
376 return (flags_field & DEPRECATED_ANNOTATION) != 0;
377 }
378
379 public boolean isDeprecatedForRemoval() {
380 return (flags_field & DEPRECATED_REMOVAL) != 0;
381 }
382
383 public boolean isPreviewApi() {
384 return (flags_field & PREVIEW_API) != 0;
385 }
386
387 public boolean isDeprecatableViaAnnotation() {
388 switch (getKind()) {
389 case LOCAL_VARIABLE:
390 case PACKAGE:
391 case PARAMETER:
392 case RESOURCE_VARIABLE:
393 case EXCEPTION_PARAMETER:
394 return false;
395 default:
396 return true;
397 }
398 }
399
400 public boolean isStatic() {
401 return
402 (flags() & STATIC) != 0 ||
403 (owner.flags() & INTERFACE) != 0 && kind != MTH &&
404 name != name.table.names._this;
405 }
406
407 public boolean isInterface() {
408 return (flags() & INTERFACE) != 0;
409 }
410
411 public boolean isAbstract() {
412 return (flags_field & ABSTRACT) != 0;
413 }
414
415 public boolean isPrivate() {
416 return (flags_field & Flags.AccessFlags) == PRIVATE;
417 }
418
419 public boolean isPublic() {
420 return (flags_field & Flags.AccessFlags) == PUBLIC;
421 }
422
423 public boolean isEnum() {
424 return (flags() & ENUM) != 0;
425 }
426
427 public boolean isSealed() {
428 return (flags_field & SEALED) != 0;
429 }
430
431 public boolean isNonSealed() {
432 return (flags_field & NON_SEALED) != 0;
433 }
434
435 public boolean isFinal() {
436 return (flags_field & FINAL) != 0;
437 }
438
439 public boolean isImplicit() {
440 return (flags_field & IMPLICIT_CLASS) != 0;
441 }
442
443 /** Is this symbol declared (directly or indirectly) local
444 * to a method or variable initializer?
445 * Also includes fields of inner classes which are in
446 * turn local to a method or variable initializer.
447 */
448 public boolean isDirectlyOrIndirectlyLocal() {
449 return
450 (owner.kind.matches(KindSelector.VAL_MTH) ||
451 (owner.kind == TYP && owner.isDirectlyOrIndirectlyLocal()));
452 }
453
454 /** Has this symbol an empty name? This includes anonymous
455 * inner classes.
456 */
457 public boolean isAnonymous() {
458 return name.isEmpty();
459 }
460
461 /** Is this symbol a constructor?
462 */
463 public boolean isConstructor() {
464 return name == name.table.names.init;
465 }
466
467 public boolean isDynamic() {
468 return false;
469 }
470
471 /** The fully qualified name of this symbol.
472 * This is the same as the symbol's name except for class symbols,
473 * which are handled separately.
474 */
475 public Name getQualifiedName() {
476 return name;
477 }
478
479 /** The fully qualified name of this symbol after converting to flat
480 * representation. This is the same as the symbol's name except for
481 * class symbols, which are handled separately.
482 */
483 public Name flatName() {
484 return getQualifiedName();
485 }
486
487 /** If this is a class or package, its members, otherwise null.
488 */
489 public WriteableScope members() {
490 return null;
491 }
492
493 /** A class is an inner class if it it has an enclosing instance class.
494 */
495 public boolean isInner() {
496 return kind == TYP && type.getEnclosingType().hasTag(CLASS);
497 }
498
499 /** An inner class has an outer instance if it is not an interface, enum or record,
500 * it has an enclosing instance class which might be referenced from the class.
501 * Nested classes can see instance members of their enclosing class.
502 * Their constructors carry an additional this$n parameter, inserted
503 * implicitly by the compiler.
504 *
505 * @see #isInner
506 */
507 public boolean hasOuterInstance() {
508 return
509 type.getEnclosingType().hasTag(CLASS) && (flags() & (INTERFACE | ENUM | RECORD)) == 0 &&
510 ((flags() & NOOUTERTHIS) == 0 || type.getEnclosingType().tsym.hasOuterInstance());
511 }
512
513 /** If the class containing this symbol is a local or an anonymous class, then it might be
514 * defined inside one or more pre-construction contexts, for which the corresponding enclosing
515 * instance is considered inaccessible. This method return the class symbol corresponding to the
516 * innermost enclosing type that is accessible from this symbol's class. Note: this method should
517 * only be called after checking that {@link #hasOuterInstance()} returns {@code true}.
518 */
519 public ClassSymbol innermostAccessibleEnclosingClass() {
520 Assert.check(enclClass().hasOuterInstance());
521 Type current = enclClass().type;
522 while ((current.tsym.flags() & NOOUTERTHIS) != 0) {
523 current = current.getEnclosingType();
524 }
525 return (ClassSymbol) current.getEnclosingType().tsym;
526 }
527
528 /** The closest enclosing class of this symbol's declaration.
529 * Warning: this (misnamed) method returns the receiver itself
530 * when the receiver is a class (as opposed to its enclosing
531 * class as one may be misled to believe.)
532 */
533 public ClassSymbol enclClass() {
534 Symbol c = this;
535 while (c != null &&
536 (!c.kind.matches(KindSelector.TYP) || !c.type.hasTag(CLASS))) {
537 c = c.owner;
538 }
539 return (ClassSymbol)c;
540 }
541
542 /** The outermost class which indirectly owns this symbol.
543 */
544 public ClassSymbol outermostClass() {
545 Symbol sym = this;
546 Symbol prev = null;
547 while (sym.kind != PCK) {
548 prev = sym;
549 sym = sym.owner;
550 }
551 return (ClassSymbol) prev;
552 }
553
554 /** The package which indirectly owns this symbol.
555 */
556 public PackageSymbol packge() {
557 Symbol sym = this;
558 while (sym.kind != PCK) {
559 sym = sym.owner;
560 }
561 return (PackageSymbol) sym;
562 }
563
564 /** Is this symbol a subclass of `base'? Only defined for ClassSymbols.
565 */
566 public boolean isSubClass(Symbol base, Types types) {
567 throw new AssertionError("isSubClass " + this);
568 }
569
570 /** Fully check membership: hierarchy, protection, and hiding.
571 * Does not exclude methods not inherited due to overriding.
572 */
573 public boolean isMemberOf(TypeSymbol clazz, Types types) {
574 return
575 owner == clazz ||
576 clazz.isSubClass(owner, types) &&
577 isInheritedIn(clazz, types) &&
578 !hiddenIn((ClassSymbol)clazz, types);
579 }
580
581 /** Is this symbol the same as or enclosed by the given class? */
582 public boolean isEnclosedBy(ClassSymbol clazz) {
583 for (Symbol sym = this; sym.kind != PCK; sym = sym.owner)
584 if (sym == clazz) return true;
585 return false;
586 }
587
588 private boolean hiddenIn(ClassSymbol clazz, Types types) {
589 Symbol sym = hiddenInInternal(clazz, types);
590 Assert.check(sym != null, "the result of hiddenInInternal() can't be null");
591 /* If we find the current symbol then there is no symbol hiding it
592 */
593 return sym != this;
594 }
595
596 /** This method looks in the supertypes graph that has the current class as the
597 * initial node, till it finds the current symbol or another symbol that hides it.
598 * If the current class has more than one supertype (extends one class and
599 * implements one or more interfaces) then null can be returned, meaning that
600 * a wrong path in the supertypes graph was selected. Null can only be returned
601 * as a temporary value, as a result of the recursive call.
602 */
603 private Symbol hiddenInInternal(ClassSymbol currentClass, Types types) {
604 if (currentClass == owner) {
605 return this;
606 }
607 for (Symbol sym : currentClass.members().getSymbolsByName(name)) {
608 if (sym.kind == kind &&
609 (kind != MTH ||
610 (sym.flags() & STATIC) != 0 &&
611 types.isSubSignature(sym.type, type))) {
612 return sym;
613 }
614 }
615 Symbol hiddenSym = null;
616 for (Type st : types.interfaces(currentClass.type)
617 .prepend(types.supertype(currentClass.type))) {
618 if (st != null && (st.hasTag(CLASS))) {
619 Symbol sym = hiddenInInternal((ClassSymbol)st.tsym, types);
620 if (sym == this) {
621 return this;
622 } else if (sym != null) {
623 hiddenSym = sym;
624 }
625 }
626 }
627 return hiddenSym;
628 }
629
630 /** Is this symbol accessible in a given class?
631 * PRE: If symbol's owner is a interface,
632 * it is already assumed that the interface is a superinterface
633 * the given class.
634 * @param clazz The class for which we want to establish membership.
635 * This must be a subclass of the member's owner.
636 */
637 public final boolean isAccessibleIn(Symbol clazz, Types types) {
638 switch ((int)(flags_field & Flags.AccessFlags)) {
639 default: // error recovery
640 case PUBLIC:
641 return true;
642 case PRIVATE:
643 return this.owner == clazz;
644 case PROTECTED:
645 // we model interfaces as extending Object
646 return (clazz.flags() & INTERFACE) == 0;
647 case 0:
648 PackageSymbol thisPackage = this.packge();
649 for (Symbol sup = clazz;
650 sup != null && sup != this.owner;
651 sup = types.supertype(sup.type).tsym) {
652 while (sup.type.hasTag(TYPEVAR))
653 sup = sup.type.getUpperBound().tsym;
654 if (sup.type.isErroneous())
655 return true; // error recovery
656 if ((sup.flags() & COMPOUND) != 0)
657 continue;
658 if (sup.packge() != thisPackage)
659 return false;
660 }
661 return (clazz.flags() & INTERFACE) == 0;
662 }
663 }
664
665 /** Is this symbol inherited into a given class?
666 * PRE: If symbol's owner is a interface,
667 * it is already assumed that the interface is a superinterface
668 * of the given class.
669 * @param clazz The class for which we want to establish membership.
670 * This must be a subclass of the member's owner.
671 */
672 public boolean isInheritedIn(Symbol clazz, Types types) {
673 return isAccessibleIn(clazz, types);
674 }
675
676 /** The (variable or method) symbol seen as a member of given
677 * class type`site' (this might change the symbol's type).
678 * This is used exclusively for producing diagnostics.
679 */
680 public Symbol asMemberOf(Type site, Types types) {
681 throw new AssertionError();
682 }
683
684 /** Does this method symbol override `other' symbol, when both are seen as
685 * members of class `origin'? It is assumed that _other is a member
686 * of origin.
687 *
688 * It is assumed that both symbols have the same name. The static
689 * modifier is ignored for this test.
690 *
691 * See JLS 8.4.8.1 (without transitivity) and 8.4.8.4
692 */
693 public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) {
694 return false;
695 }
696
697 /** Complete the elaboration of this symbol's definition.
698 */
699 public void complete() throws CompletionFailure {
700 if (completer != Completer.NULL_COMPLETER) {
701 Completer c = completer;
702 completer = Completer.NULL_COMPLETER;
703 c.complete(this);
704 }
705 }
706
707 public void apiComplete() throws CompletionFailure {
708 try {
709 complete();
710 } catch (CompletionFailure cf) {
711 cf.dcfh.handleAPICompletionFailure(cf);
712 }
713 }
714
715 /** True if the symbol represents an entity that exists.
716 */
717 public boolean exists() {
718 return true;
719 }
720
721 @DefinedBy(Api.LANGUAGE_MODEL)
722 public Type asType() {
723 return type;
724 }
725
726 @DefinedBy(Api.LANGUAGE_MODEL)
727 public Symbol getEnclosingElement() {
728 return owner;
729 }
730
731 @DefinedBy(Api.LANGUAGE_MODEL)
732 public ElementKind getKind() {
733 return ElementKind.OTHER; // most unkind
734 }
735
736 @DefinedBy(Api.LANGUAGE_MODEL)
737 public Set<Modifier> getModifiers() {
738 apiComplete();
739 return Flags.asModifierSet(flags());
740 }
741
742 @DefinedBy(Api.LANGUAGE_MODEL)
743 public Name getSimpleName() {
744 return name;
745 }
746
747 /**
748 * This is the implementation for {@code
749 * javax.lang.model.element.Element.getAnnotationMirrors()}.
750 */
751 @Override @DefinedBy(Api.LANGUAGE_MODEL)
752 public List<Attribute.Compound> getAnnotationMirrors() {
753 apiComplete();
754 return getRawAttributes();
755 }
756
757
758 // TODO: getEnclosedElements should return a javac List, fix in FilteredMemberList
759 @DefinedBy(Api.LANGUAGE_MODEL)
760 public java.util.List<Symbol> getEnclosedElements() {
761 return List.nil();
762 }
763
764 public List<TypeVariableSymbol> getTypeParameters() {
765 ListBuffer<TypeVariableSymbol> l = new ListBuffer<>();
766 for (Type t : type.getTypeArguments()) {
767 Assert.check(t.tsym.getKind() == ElementKind.TYPE_PARAMETER);
768 l.append((TypeVariableSymbol)t.tsym);
769 }
770 return l.toList();
771 }
772
773 public static class DelegatedSymbol<T extends Symbol> extends Symbol {
774 protected T other;
775 public DelegatedSymbol(T other) {
776 super(other.kind, other.flags_field, other.name, other.type, other.owner);
777 this.other = other;
778 }
779 public String toString() { return other.toString(); }
780 public Symbol location() { return other.location(); }
781 public Symbol location(Type site, Types types) { return other.location(site, types); }
782 public Symbol baseSymbol() { return other; }
783 public Type erasure(Types types) { return other.erasure(types); }
784 public Type externalType(Types types) { return other.externalType(types); }
785 public boolean isDirectlyOrIndirectlyLocal() { return other.isDirectlyOrIndirectlyLocal(); }
786 public boolean isConstructor() { return other.isConstructor(); }
787 public Name getQualifiedName() { return other.getQualifiedName(); }
788 public Name flatName() { return other.flatName(); }
789 public WriteableScope members() { return other.members(); }
790 public boolean isInner() { return other.isInner(); }
791 public boolean hasOuterInstance() { return other.hasOuterInstance(); }
792 public ClassSymbol enclClass() { return other.enclClass(); }
793 public ClassSymbol outermostClass() { return other.outermostClass(); }
794 public PackageSymbol packge() { return other.packge(); }
795 public boolean isSubClass(Symbol base, Types types) { return other.isSubClass(base, types); }
796 public boolean isMemberOf(TypeSymbol clazz, Types types) { return other.isMemberOf(clazz, types); }
797 public boolean isEnclosedBy(ClassSymbol clazz) { return other.isEnclosedBy(clazz); }
798 public boolean isInheritedIn(Symbol clazz, Types types) { return other.isInheritedIn(clazz, types); }
799 public Symbol asMemberOf(Type site, Types types) { return other.asMemberOf(site, types); }
800 public void complete() throws CompletionFailure { other.complete(); }
801
802 @DefinedBy(Api.LANGUAGE_MODEL)
803 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
804 return other.accept(v, p);
805 }
806
807 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
808 return v.visitSymbol(other, p);
809 }
810
811 public T getUnderlyingSymbol() {
812 return other;
813 }
814 }
815
816 /** A base class for Symbols representing types.
817 */
818 public abstract static class TypeSymbol extends Symbol {
819 public TypeSymbol(Kind kind, long flags, Name name, Type type, Symbol owner) {
820 super(kind, flags, name, type, owner);
821 }
822 /** form a fully qualified name from a name and an owner
823 */
824 public static Name formFullName(Name name, Symbol owner) {
825 if (owner == null) return name;
826 if ((owner.kind != ERR) &&
827 (owner.kind.matches(KindSelector.VAL_MTH) ||
828 (owner.kind == TYP && owner.type.hasTag(TYPEVAR))
829 )) return name;
830 Name prefix = owner.getQualifiedName();
831 if (prefix == null || prefix == prefix.table.names.empty)
832 return name;
833 else return prefix.append('.', name);
834 }
835
836 /** form a fully qualified name from a name and an owner, after
837 * converting to flat representation
838 */
839 public static Name formFlatName(Name name, Symbol owner) {
840 if (owner == null || owner.kind.matches(KindSelector.VAL_MTH) ||
841 (owner.kind == TYP && owner.type.hasTag(TYPEVAR))
842 ) return name;
843 char sep = owner.kind == TYP ? '$' : '.';
844 Name prefix = owner.flatName();
845 if (prefix == null || prefix == prefix.table.names.empty)
846 return name;
847 else return prefix.append(sep, name);
848 }
849
850 /**
851 * A partial ordering between type symbols that refines the
852 * class inheritance graph.
853 *
854 * Type variables always precede other kinds of symbols.
855 */
856 public final boolean precedes(TypeSymbol that, Types types) {
857 if (this == that)
858 return false;
859 if (type.hasTag(that.type.getTag())) {
860 if (type.hasTag(CLASS)) {
861 return
862 types.rank(that.type) < types.rank(this.type) ||
863 (types.rank(that.type) == types.rank(this.type) &&
864 this.getQualifiedName().compareTo(that.getQualifiedName()) < 0);
865 } else if (type.hasTag(TYPEVAR)) {
866 return types.isSubtype(this.type, that.type);
867 }
868 }
869 return type.hasTag(TYPEVAR);
870 }
871
872 @Override @DefinedBy(Api.LANGUAGE_MODEL)
873 public List<Symbol> getEnclosedElements() {
874 List<Symbol> list = List.nil();
875 if (kind == TYP && type.hasTag(TYPEVAR)) {
876 return list;
877 }
878 apiComplete();
879 for (Symbol sym : members().getSymbols(NON_RECURSIVE)) {
880 sym.apiComplete();
881 if ((sym.flags() & SYNTHETIC) == 0 && sym.owner == this && sym.kind != ERR) {
882 list = list.prepend(sym);
883 }
884 }
885 return list;
886 }
887
888 public AnnotationTypeMetadata getAnnotationTypeMetadata() {
889 Assert.error("Only on ClassSymbol");
890 return null; //unreachable
891 }
892
893 public boolean isAnnotationType() { return false; }
894
895 @Override
896 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
897 return v.visitTypeSymbol(this, p);
898 }
899 }
900
901 /**
902 * Type variables are represented by instances of this class.
903 */
904 public static class TypeVariableSymbol
905 extends TypeSymbol implements TypeParameterElement {
906
907 public TypeVariableSymbol(long flags, Name name, Type type, Symbol owner) {
908 super(TYP, flags, name, type, owner);
909 }
910
911 @DefinedBy(Api.LANGUAGE_MODEL)
912 public ElementKind getKind() {
913 return ElementKind.TYPE_PARAMETER;
914 }
915
916 @Override @DefinedBy(Api.LANGUAGE_MODEL)
917 public Symbol getGenericElement() {
918 return owner;
919 }
920
921 @DefinedBy(Api.LANGUAGE_MODEL)
922 public List<Type> getBounds() {
923 TypeVar t = (TypeVar)type;
924 Type bound = t.getUpperBound();
925 if (!bound.isCompound())
926 return List.of(bound);
927 ClassType ct = (ClassType)bound;
928 if (!ct.tsym.erasure_field.isInterface()) {
929 return ct.interfaces_field.prepend(ct.supertype_field);
930 } else {
931 // No superclass was given in bounds.
932 // In this case, supertype is Object, erasure is first interface.
933 return ct.interfaces_field;
934 }
935 }
936
937 @Override @DefinedBy(Api.LANGUAGE_MODEL)
938 public List<Attribute.Compound> getAnnotationMirrors() {
939 // Declaration annotations on type variables are stored in type attributes
940 // on the owner of the TypeVariableSymbol
941 List<Attribute.TypeCompound> candidates = owner.getRawTypeAttributes();
942 int index = owner.getTypeParameters().indexOf(this);
943 List<Attribute.Compound> res = List.nil();
944 for (Attribute.TypeCompound a : candidates) {
945 if (isCurrentSymbolsAnnotation(a, index))
946 res = res.prepend(a);
947 }
948
949 return res.reverse();
950 }
951
952 // Helper to getAnnotation[s]
953 @Override
954 public <A extends Annotation> Attribute.Compound getAttribute(Class<A> annoType) {
955 String name = annoType.getName();
956
957 // Declaration annotations on type variables are stored in type attributes
958 // on the owner of the TypeVariableSymbol
959 List<Attribute.TypeCompound> candidates = owner.getRawTypeAttributes();
960 int index = owner.getTypeParameters().indexOf(this);
961 for (Attribute.TypeCompound anno : candidates)
962 if (isCurrentSymbolsAnnotation(anno, index) &&
963 name.contentEquals(anno.type.tsym.flatName()))
964 return anno;
965
966 return null;
967 }
968 //where:
969 boolean isCurrentSymbolsAnnotation(Attribute.TypeCompound anno, int index) {
970 return (anno.position.type == TargetType.CLASS_TYPE_PARAMETER ||
971 anno.position.type == TargetType.METHOD_TYPE_PARAMETER) &&
972 anno.position.parameter_index == index &&
973 anno.type.tsym.flatName() != name.table.names.requiresIdentityInternal;
974 }
975
976
977 @Override @DefinedBy(Api.LANGUAGE_MODEL)
978 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
979 return v.visitTypeParameter(this, p);
980 }
981 }
982 /** A class for module symbols.
983 */
984 public static class ModuleSymbol extends TypeSymbol
985 implements ModuleElement {
986
987 public Name version;
988 public JavaFileManager.Location sourceLocation;
989 public JavaFileManager.Location classLocation;
990 public JavaFileManager.Location patchLocation;
991 public JavaFileManager.Location patchOutputLocation;
992
993 /** All directives, in natural order. */
994 public List<com.sun.tools.javac.code.Directive> directives;
995 public List<com.sun.tools.javac.code.Directive.RequiresDirective> requires;
996 public List<com.sun.tools.javac.code.Directive.ExportsDirective> exports;
997 public List<com.sun.tools.javac.code.Directive.OpensDirective> opens;
998 public List<com.sun.tools.javac.code.Directive.ProvidesDirective> provides;
999 public List<com.sun.tools.javac.code.Directive.UsesDirective> uses;
1000
1001 public ClassSymbol module_info;
1002
1003 public PackageSymbol unnamedPackage;
1004 public Map<Name, PackageSymbol> visiblePackages;
1005 public Set<ModuleSymbol> readModules;
1006 public List<Symbol> enclosedPackages = List.nil();
1007
1008 public Completer usesProvidesCompleter = Completer.NULL_COMPLETER;
1009 public final Set<ModuleFlags> flags = EnumSet.noneOf(ModuleFlags.class);
1010 public final Set<ModuleResolutionFlags> resolutionFlags = EnumSet.noneOf(ModuleResolutionFlags.class);
1011
1012 /**
1013 * Create a ModuleSymbol with an associated module-info ClassSymbol.
1014 */
1015 public static ModuleSymbol create(Name name, Name module_info) {
1016 ModuleSymbol msym = new ModuleSymbol(name, null);
1017 ClassSymbol info = new ClassSymbol(Flags.MODULE, module_info, msym);
1018 info.fullname = formFullName(module_info, msym);
1019 info.flatname = info.fullname;
1020 info.members_field = WriteableScope.create(info);
1021 msym.module_info = info;
1022 return msym;
1023 }
1024
1025 @SuppressWarnings("this-escape")
1026 public ModuleSymbol(Name name, Symbol owner) {
1027 super(MDL, 0, name, null, owner);
1028 Assert.checkNonNull(name);
1029 this.type = new ModuleType(this);
1030 }
1031
1032 @Override
1033 public int poolTag() {
1034 return ClassFile.CONSTANT_Module;
1035 }
1036
1037 @Override @DefinedBy(Api.LANGUAGE_MODEL)
1038 public Name getSimpleName() {
1039 return Convert.shortName(name);
1040 }
1041
1042 @Override @DefinedBy(Api.LANGUAGE_MODEL)
1043 public boolean isOpen() {
1044 return flags.contains(ModuleFlags.OPEN);
1045 }
1046
1047 @Override @DefinedBy(Api.LANGUAGE_MODEL)
1048 public boolean isUnnamed() {
1049 return name.isEmpty() && owner == null;
1050 }
1051
1052 @Override
1053 public boolean isDeprecated() {
1054 return hasDeprecatedAnnotation();
1055 }
1056
1057 public boolean isNoModule() {
1058 return false;
1059 }
1060
1061 @Override @DefinedBy(Api.LANGUAGE_MODEL)
1062 public ElementKind getKind() {
1063 return ElementKind.MODULE;
1064 }
1065
1066 @Override @DefinedBy(Api.LANGUAGE_MODEL)
1067 public java.util.List<Directive> getDirectives() {
1068 apiComplete();
1069 completeUsesProvides();
1070 return Collections.unmodifiableList(directives);
1071 }
1072
1073 public void completeUsesProvides() {
1074 if (usesProvidesCompleter != Completer.NULL_COMPLETER) {
1075 Completer c = usesProvidesCompleter;
1076 usesProvidesCompleter = Completer.NULL_COMPLETER;
1077 c.complete(this);
1078 }
1079 }
1080
1081 @Override
1082 public ClassSymbol outermostClass() {
1083 return null;
1084 }
1085
1086 @Override
1087 public String toString() {
1088 // TODO: the following strings should be localized
1089 // Do this with custom anon subtypes in Symtab
1090 String n = (name == null) ? "<unknown>"
1091 : (name.isEmpty()) ? "<unnamed>"
1092 : String.valueOf(name);
1093 return n;
1094 }
1095
1096 @Override @DefinedBy(Api.LANGUAGE_MODEL)
1097 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1098 return v.visitModule(this, p);
1099 }
1100
1101 @Override @DefinedBy(Api.LANGUAGE_MODEL)
1102 public List<Symbol> getEnclosedElements() {
1103 List<Symbol> list = List.nil();
1104 for (Symbol sym : enclosedPackages) {
1105 if (sym.members().anyMatch(m -> m.kind == TYP))
1106 list = list.prepend(sym);
1107 }
1108 return list;
1109 }
1110
1111 public void reset() {
1112 this.directives = null;
1113 this.requires = null;
1114 this.exports = null;
1115 this.provides = null;
1116 this.uses = null;
1117 this.visiblePackages = null;
1118 }
1119
1120 }
1121
1122 public enum ModuleFlags {
1123 OPEN(0x0020),
1124 SYNTHETIC(0x1000),
1125 MANDATED(0x8000);
1126
1127 public static int value(Set<ModuleFlags> s) {
1128 int v = 0;
1129 for (ModuleFlags f: s)
1130 v |= f.value;
1131 return v;
1132 }
1133
1134 private ModuleFlags(int value) {
1135 this.value = value;
1136 }
1137
1138 public final int value;
1139 }
1140
1141 public enum ModuleResolutionFlags {
1142 DO_NOT_RESOLVE_BY_DEFAULT(0x0001),
1143 WARN_DEPRECATED(0x0002),
1144 WARN_DEPRECATED_REMOVAL(0x0004),
1145 WARN_INCUBATING(0x0008);
1146
1147 public static int value(Set<ModuleResolutionFlags> s) {
1148 int v = 0;
1149 for (ModuleResolutionFlags f: s)
1150 v |= f.value;
1151 return v;
1152 }
1153
1154 private ModuleResolutionFlags(int value) {
1155 this.value = value;
1156 }
1157
1158 public final int value;
1159 }
1160
1161 /** A class for package symbols
1162 */
1163 public static class PackageSymbol extends TypeSymbol
1164 implements PackageElement {
1165
1166 public WriteableScope members_field;
1167 public Name fullname;
1168 public ClassSymbol package_info; // see bug 6443073
1169 public ModuleSymbol modle;
1170 // the file containing the documentation comments for the package
1171 public JavaFileObject sourcefile;
1172
1173 public PackageSymbol(Name name, Type type, Symbol owner) {
1174 super(PCK, 0, name, type, owner);
1175 this.members_field = null;
1176 this.fullname = formFullName(name, owner);
1177 }
1178
1179 @SuppressWarnings("this-escape")
1180 public PackageSymbol(Name name, Symbol owner) {
1181 this(name, null, owner);
1182 this.type = new PackageType(this);
1183 }
1184
1185 public String toString() {
1186 return fullname.toString();
1187 }
1188
1189 @DefinedBy(Api.LANGUAGE_MODEL)
1190 public Name getQualifiedName() {
1191 return fullname;
1192 }
1193
1194 @DefinedBy(Api.LANGUAGE_MODEL)
1195 public boolean isUnnamed() {
1196 return name.isEmpty() && owner != null;
1197 }
1198
1199 public WriteableScope members() {
1200 complete();
1201 return members_field;
1202 }
1203
1204 @Override
1205 public int poolTag() {
1206 return ClassFile.CONSTANT_Package;
1207 }
1208
1209 public long flags() {
1210 complete();
1211 return flags_field;
1212 }
1213
1214 @Override
1215 public List<Attribute.Compound> getRawAttributes() {
1216 complete();
1217 if (package_info != null) {
1218 package_info.complete();
1219 mergeAttributes();
1220 }
1221 return super.getRawAttributes();
1222 }
1223
1224 private void mergeAttributes() {
1225 if (metadata == null &&
1226 package_info.metadata != null) {
1227 metadata = new SymbolMetadata(this);
1228 metadata.setAttributes(package_info.metadata);
1229 }
1230 }
1231
1232 /** A package "exists" if a type or package that exists has
1233 * been seen within it.
1234 */
1235 public boolean exists() {
1236 return (flags_field & EXISTS) != 0;
1237 }
1238
1239 @DefinedBy(Api.LANGUAGE_MODEL)
1240 public ElementKind getKind() {
1241 return ElementKind.PACKAGE;
1242 }
1243
1244 @DefinedBy(Api.LANGUAGE_MODEL)
1245 public Symbol getEnclosingElement() {
1246 return modle != null && !modle.isNoModule() ? modle : null;
1247 }
1248
1249 @DefinedBy(Api.LANGUAGE_MODEL)
1250 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1251 return v.visitPackage(this, p);
1252 }
1253
1254 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1255 return v.visitPackageSymbol(this, p);
1256 }
1257
1258 /**Resets the Symbol into the state good for next round of annotation processing.*/
1259 public void reset() {
1260 metadata = null;
1261 }
1262
1263 }
1264
1265 public static class RootPackageSymbol extends PackageSymbol {
1266 public final MissingInfoHandler missingInfoHandler;
1267 public final boolean allowPrivateInvokeVirtual;
1268
1269 public RootPackageSymbol(Name name, Symbol owner,
1270 MissingInfoHandler missingInfoHandler,
1271 boolean allowPrivateInvokeVirtual) {
1272 super(name, owner);
1273 this.missingInfoHandler = missingInfoHandler;
1274 this.allowPrivateInvokeVirtual = allowPrivateInvokeVirtual;
1275 }
1276
1277 }
1278
1279 /** A class for class symbols
1280 */
1281 public static class ClassSymbol extends TypeSymbol implements TypeElement {
1282
1283 /** a scope for all class members; variables, methods and inner classes
1284 * type parameters are not part of this scope
1285 */
1286 public WriteableScope members_field;
1287
1288 /** the fully qualified name of the class, i.e. pck.outer.inner.
1289 * null for anonymous classes
1290 */
1291 public Name fullname;
1292
1293 /** the fully qualified name of the class after converting to flat
1294 * representation, i.e. pck.outer$inner,
1295 * set externally for local and anonymous classes
1296 */
1297 public Name flatname;
1298
1299 /** the sourcefile where the class came from
1300 */
1301 public JavaFileObject sourcefile;
1302
1303 /** the classfile from where to load this class
1304 * this will have extension .class or .java
1305 */
1306 public JavaFileObject classfile;
1307
1308 /** the list of translated local classes (used for generating
1309 * InnerClasses attribute)
1310 */
1311 public List<ClassSymbol> trans_local;
1312
1313 /** the annotation metadata attached to this class */
1314 private AnnotationTypeMetadata annotationTypeMetadata;
1315
1316 /* the list of any of record components, only non empty if the class is a record
1317 * and it has at least one record component
1318 */
1319 private List<RecordComponent> recordComponents = List.nil();
1320
1321 // sealed classes related fields
1322 /** The classes, or interfaces, permitted to extend this class, or interface
1323 */
1324 private java.util.List<PermittedClassWithPos> permitted;
1325
1326 public boolean isPermittedExplicit = false;
1327
1328 private record PermittedClassWithPos(Symbol permittedClass, int pos) {}
1329
1330 public ClassSymbol(long flags, Name name, Type type, Symbol owner) {
1331 super(TYP, flags, name, type, owner);
1332 this.members_field = null;
1333 this.fullname = formFullName(name, owner);
1334 this.flatname = formFlatName(name, owner);
1335 this.sourcefile = null;
1336 this.classfile = null;
1337 this.annotationTypeMetadata = AnnotationTypeMetadata.notAnAnnotationType();
1338 this.permitted = new ArrayList<>();
1339 }
1340
1341 public ClassSymbol(long flags, Name name, Symbol owner) {
1342 this(
1343 flags,
1344 name,
1345 new ClassType(Type.noType, null, null),
1346 owner);
1347 this.type.tsym = this;
1348 }
1349
1350 public void addPermittedSubclass(ClassSymbol csym, int pos) {
1351 Assert.check(!isPermittedExplicit);
1352 // we need to insert at the right pos
1353 PermittedClassWithPos element = new PermittedClassWithPos(csym, pos);
1354 int index = Collections.binarySearch(permitted, element, java.util.Comparator.comparing(PermittedClassWithPos::pos));
1355 if (index < 0) {
1356 index = -index - 1;
1357 permitted.add(index, element);
1358 }
1359 }
1360
1361 public boolean isPermittedSubclass(Symbol csym) {
1362 for (PermittedClassWithPos permittedClassWithPos : permitted) {
1363 if (permittedClassWithPos.permittedClass.equals(csym)) {
1364 return true;
1365 }
1366 }
1367 return false;
1368 }
1369
1370 public void clearPermittedSubclasses() {
1371 permitted.clear();
1372 }
1373
1374 public void setPermittedSubclasses(List<Symbol> permittedSubs) {
1375 permitted.clear();
1376 for (Symbol csym : permittedSubs) {
1377 permitted.add(new PermittedClassWithPos(csym, 0));
1378 }
1379 }
1380
1381 /** The Java source which this symbol represents.
1382 */
1383 public String toString() {
1384 return className();
1385 }
1386
1387 public long flags() {
1388 complete();
1389 return flags_field;
1390 }
1391
1392 public WriteableScope members() {
1393 complete();
1394 return members_field;
1395 }
1396
1397 @Override
1398 public List<Attribute.Compound> getRawAttributes() {
1399 complete();
1400 return super.getRawAttributes();
1401 }
1402
1403 @Override
1404 public List<Attribute.TypeCompound> getRawTypeAttributes() {
1405 complete();
1406 return super.getRawTypeAttributes();
1407 }
1408
1409 public Type erasure(Types types) {
1410 if (erasure_field == null)
1411 erasure_field = new ClassType(types.erasure(type.getEnclosingType()),
1412 List.nil(), this,
1413 type.getMetadata());
1414 return erasure_field;
1415 }
1416
1417 public String className() {
1418 if (name.isEmpty())
1419 return
1420 Log.getLocalizedString("anonymous.class", flatname);
1421 else
1422 return fullname.toString();
1423 }
1424
1425 @Override @DefinedBy(Api.LANGUAGE_MODEL)
1426 public Name getQualifiedName() {
1427 return fullname;
1428 }
1429
1430 @Override @DefinedBy(Api.LANGUAGE_MODEL)
1431 public Name getSimpleName() {
1432 return name;
1433 }
1434
1435 @Override @DefinedBy(Api.LANGUAGE_MODEL)
1436 public List<Symbol> getEnclosedElements() {
1437 List<Symbol> result = super.getEnclosedElements();
1438 if (!recordComponents.isEmpty()) {
1439 List<RecordComponent> reversed = recordComponents.reverse();
1440 for (RecordComponent rc : reversed) {
1441 result = result.prepend(rc);
1442 }
1443 }
1444 return result;
1445 }
1446
1447 public Name flatName() {
1448 return flatname;
1449 }
1450
1451 public boolean isSubClass(Symbol base, Types types) {
1452 if (this == base) {
1453 return true;
1454 } else if ((base.flags() & INTERFACE) != 0) {
1455 for (Type t = type; t.hasTag(CLASS); t = types.supertype(t))
1456 for (List<Type> is = types.interfaces(t);
1457 is.nonEmpty();
1458 is = is.tail)
1459 if (is.head.tsym.isSubClass(base, types)) return true;
1460 } else {
1461 for (Type t = type; t.hasTag(CLASS); t = types.supertype(t))
1462 if (t.tsym == base) return true;
1463 }
1464 return false;
1465 }
1466
1467 /** Complete the elaboration of this symbol's definition.
1468 */
1469 public void complete() throws CompletionFailure {
1470 Completer origCompleter = completer;
1471 try {
1472 super.complete();
1473 } catch (CompletionFailure ex) {
1474 ex.dcfh.classSymbolCompleteFailed(this, origCompleter);
1475 // quiet error recovery
1476 flags_field |= (PUBLIC|STATIC);
1477 this.type = new ErrorType(this, Type.noType);
1478 throw ex;
1479 }
1480 }
1481
1482 @DefinedBy(Api.LANGUAGE_MODEL)
1483 public List<Type> getInterfaces() {
1484 apiComplete();
1485 if (type instanceof ClassType classType) {
1486 if (classType.interfaces_field == null) // FIXME: shouldn't be null
1487 classType.interfaces_field = List.nil();
1488 if (classType.all_interfaces_field != null)
1489 return Type.getModelTypes(classType.all_interfaces_field);
1490 return classType.interfaces_field;
1491 } else {
1492 return List.nil();
1493 }
1494 }
1495
1496 @DefinedBy(Api.LANGUAGE_MODEL)
1497 public Type getSuperclass() {
1498 apiComplete();
1499 if (type instanceof ClassType classType) {
1500 if (classType.supertype_field == null) // FIXME: shouldn't be null
1501 classType.supertype_field = Type.noType;
1502 // An interface has no superclass; its supertype is Object.
1503 return classType.isInterface()
1504 ? Type.noType
1505 : classType.supertype_field.getModelType();
1506 } else {
1507 return Type.noType;
1508 }
1509 }
1510
1511 /**
1512 * Returns the next class to search for inherited annotations or {@code null}
1513 * if the next class can't be found.
1514 */
1515 private ClassSymbol getSuperClassToSearchForAnnotations() {
1516
1517 Type sup = getSuperclass();
1518
1519 if (!sup.hasTag(CLASS) || sup.isErroneous())
1520 return null;
1521
1522 return (ClassSymbol) sup.tsym;
1523 }
1524
1525
1526 @Override
1527 protected <A extends Annotation> A[] getInheritedAnnotations(Class<A> annoType) {
1528
1529 ClassSymbol sup = getSuperClassToSearchForAnnotations();
1530
1531 return sup == null ? super.getInheritedAnnotations(annoType)
1532 : sup.getAnnotationsByType(annoType);
1533 }
1534
1535
1536 @DefinedBy(Api.LANGUAGE_MODEL)
1537 public ElementKind getKind() {
1538 apiComplete();
1539 long flags = flags();
1540 if ((flags & ANNOTATION) != 0)
1541 return ElementKind.ANNOTATION_TYPE;
1542 else if ((flags & INTERFACE) != 0)
1543 return ElementKind.INTERFACE;
1544 else if ((flags & ENUM) != 0)
1545 return ElementKind.ENUM;
1546 else if ((flags & RECORD) != 0)
1547 return ElementKind.RECORD;
1548 else
1549 return ElementKind.CLASS;
1550 }
1551
1552 @Override @DefinedBy(Api.LANGUAGE_MODEL)
1553 public Set<Modifier> getModifiers() {
1554 apiComplete();
1555 long flags = flags();
1556 return Flags.asModifierSet(flags & ~DEFAULT);
1557 }
1558
1559 public RecordComponent getRecordComponent(VarSymbol field) {
1560 for (RecordComponent rc : recordComponents) {
1561 if (rc.name == field.name) {
1562 return rc;
1563 }
1564 }
1565 return null;
1566 }
1567
1568 /* creates a record component if non is related to the given variable and recreates a brand new one
1569 * in other case
1570 */
1571 public RecordComponent createRecordComponent(RecordComponent existing, JCVariableDecl rcDecl, VarSymbol varSym) {
1572 RecordComponent rc = null;
1573 if (existing != null && !recordComponents.isEmpty()) {
1574 ListBuffer<RecordComponent> newRComps = new ListBuffer<>();
1575 for (RecordComponent rcomp : recordComponents) {
1576 if (existing == rcomp) {
1577 newRComps.add(rc = new RecordComponent(varSym, existing.ast, existing.isVarargs));
1578 } else {
1579 newRComps.add(rcomp);
1580 }
1581 }
1582 recordComponents = newRComps.toList();
1583 } else {
1584 // Didn't find the record component: create one.
1585 recordComponents = recordComponents.append(rc = new RecordComponent(varSym, rcDecl));
1586 }
1587 return rc;
1588 }
1589
1590 @Override @DefinedBy(Api.LANGUAGE_MODEL)
1591 public List<? extends RecordComponent> getRecordComponents() {
1592 return recordComponents;
1593 }
1594
1595 public void setRecordComponents(List<RecordComponent> recordComponents) {
1596 this.recordComponents = recordComponents;
1597 }
1598
1599 @DefinedBy(Api.LANGUAGE_MODEL)
1600 public NestingKind getNestingKind() {
1601 apiComplete();
1602 if (owner.kind == PCK) // Handles implicitly declared classes as well
1603 return NestingKind.TOP_LEVEL;
1604 else if (name.isEmpty())
1605 return NestingKind.ANONYMOUS;
1606 else if (owner.kind == MTH)
1607 return NestingKind.LOCAL;
1608 else
1609 return NestingKind.MEMBER;
1610 }
1611
1612 @Override
1613 protected <A extends Annotation> Attribute.Compound getAttribute(final Class<A> annoType) {
1614
1615 Attribute.Compound attrib = super.getAttribute(annoType);
1616
1617 boolean inherited = annoType.isAnnotationPresent(Inherited.class);
1618 if (attrib != null || !inherited)
1619 return attrib;
1620
1621 // Search supertypes
1622 ClassSymbol superType = getSuperClassToSearchForAnnotations();
1623 return superType == null ? null
1624 : superType.getAttribute(annoType);
1625 }
1626
1627 @DefinedBy(Api.LANGUAGE_MODEL)
1628 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1629 return v.visitType(this, p);
1630 }
1631
1632 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1633 return v.visitClassSymbol(this, p);
1634 }
1635
1636 public void markAbstractIfNeeded(Types types) {
1637 if (types.enter.getEnv(this) != null &&
1638 (flags() & ENUM) != 0 && types.supertype(type).tsym == types.syms.enumSym &&
1639 (flags() & (FINAL | ABSTRACT)) == 0) {
1640 if (types.firstUnimplementedAbstract(this) != null)
1641 // add the ABSTRACT flag to an enum
1642 flags_field |= ABSTRACT;
1643 }
1644 }
1645
1646 /**Resets the Symbol into the state good for next round of annotation processing.*/
1647 public void reset() {
1648 kind = TYP;
1649 erasure_field = null;
1650 members_field = null;
1651 flags_field = 0;
1652 if (type instanceof ClassType classType) {
1653 classType.setEnclosingType(Type.noType);
1654 classType.rank_field = -1;
1655 classType.typarams_field = null;
1656 classType.allparams_field = null;
1657 classType.supertype_field = null;
1658 classType.interfaces_field = null;
1659 classType.all_interfaces_field = null;
1660 }
1661 clearAnnotationMetadata();
1662 }
1663
1664 public void clearAnnotationMetadata() {
1665 metadata = null;
1666 annotationTypeMetadata = AnnotationTypeMetadata.notAnAnnotationType();
1667 }
1668
1669 @Override
1670 public AnnotationTypeMetadata getAnnotationTypeMetadata() {
1671 return annotationTypeMetadata;
1672 }
1673
1674 @Override
1675 public boolean isAnnotationType() {
1676 return (flags_field & Flags.ANNOTATION) != 0;
1677 }
1678
1679 public void setAnnotationTypeMetadata(AnnotationTypeMetadata a) {
1680 Assert.checkNonNull(a);
1681 Assert.check(!annotationTypeMetadata.isMetadataForAnnotationType());
1682 this.annotationTypeMetadata = a;
1683 }
1684
1685 public boolean isRecord() {
1686 return (flags_field & RECORD) != 0;
1687 }
1688
1689 @DefinedBy(Api.LANGUAGE_MODEL)
1690 public List<Type> getPermittedSubclasses() {
1691 return permitted.stream().map(s -> s.permittedClass().type).collect(List.collector());
1692 }
1693 }
1694
1695
1696 /** A class for variable symbols
1697 */
1698 public static class VarSymbol extends Symbol implements VariableElement {
1699
1700 /** The variable's declaration position.
1701 */
1702 public int pos = Position.NOPOS;
1703
1704 /** The variable's address. Used for different purposes during
1705 * flow analysis, translation and code generation.
1706 * Flow analysis:
1707 * If this is a blank final or local variable, its sequence number.
1708 * Translation:
1709 * If this is a private field, its access number.
1710 * Code generation:
1711 * If this is a local variable, its logical slot number.
1712 */
1713 public int adr = -1;
1714
1715 /** Construct a variable symbol, given its flags, name, type and owner.
1716 */
1717 public VarSymbol(long flags, Name name, Type type, Symbol owner) {
1718 super(VAR, flags, name, type, owner);
1719 }
1720
1721 @Override
1722 public int poolTag() {
1723 return ClassFile.CONSTANT_Fieldref;
1724 }
1725
1726 public MethodHandleSymbol asMethodHandle(boolean getter) {
1727 return new MethodHandleSymbol(this, getter);
1728 }
1729
1730 /** Clone this symbol with new owner.
1731 */
1732 public VarSymbol clone(Symbol newOwner) {
1733 VarSymbol v = new VarSymbol(flags_field, name, type, newOwner) {
1734 @Override
1735 public Symbol baseSymbol() {
1736 return VarSymbol.this;
1737 }
1738
1739 @Override
1740 public Object poolKey(Types types) {
1741 return new Pair<>(newOwner, baseSymbol());
1742 }
1743 };
1744 v.pos = pos;
1745 v.adr = adr;
1746 v.data = data;
1747 // System.out.println("clone " + v + " in " + newOwner);//DEBUG
1748 return v;
1749 }
1750
1751 public String toString() {
1752 return name.toString();
1753 }
1754
1755 public Symbol asMemberOf(Type site, Types types) {
1756 return new VarSymbol(flags_field, name, types.memberType(site, this), owner);
1757 }
1758
1759 @DefinedBy(Api.LANGUAGE_MODEL)
1760 public ElementKind getKind() {
1761 long flags = flags();
1762 if ((flags & PARAMETER) != 0) {
1763 if (isExceptionParameter())
1764 return ElementKind.EXCEPTION_PARAMETER;
1765 else
1766 return ElementKind.PARAMETER;
1767 } else if ((flags & ENUM) != 0) {
1768 return ElementKind.ENUM_CONSTANT;
1769 } else if (owner.kind == TYP || owner.kind == ERR) {
1770 return ElementKind.FIELD;
1771 } else if (isResourceVariable()) {
1772 return ElementKind.RESOURCE_VARIABLE;
1773 } else if ((flags & MATCH_BINDING) != 0) {
1774 ElementKind kind = ElementKind.BINDING_VARIABLE;
1775 return kind;
1776 } else {
1777 return ElementKind.LOCAL_VARIABLE;
1778 }
1779 }
1780
1781 @DefinedBy(Api.LANGUAGE_MODEL)
1782 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1783 return v.visitVariable(this, p);
1784 }
1785
1786 @DefinedBy(Api.LANGUAGE_MODEL)
1787 public Object getConstantValue() { // Mirror API
1788 return Constants.decode(getConstValue(), type);
1789 }
1790
1791 public void setLazyConstValue(final Env<AttrContext> env,
1792 final Env<AttrContext> enclosingEnv,
1793 final Attr attr,
1794 final JCVariableDecl variable)
1795 {
1796 setData((Callable<Object>)() -> attr.attribLazyConstantValue(env, enclosingEnv, variable, type));
1797 }
1798
1799 /**
1800 * The variable's constant value, if this is a constant.
1801 * Before the constant value is evaluated, it points to an
1802 * initializer environment. If this is not a constant, it can
1803 * be used for other stuff.
1804 */
1805 private Object data;
1806
1807 public boolean isExceptionParameter() {
1808 return data == ElementKind.EXCEPTION_PARAMETER;
1809 }
1810
1811 public boolean isResourceVariable() {
1812 return data == ElementKind.RESOURCE_VARIABLE;
1813 }
1814
1815 public Object getConstValue() {
1816 // TODO: Consider if getConstValue and getConstantValue can be collapsed
1817 if (data == ElementKind.EXCEPTION_PARAMETER ||
1818 data == ElementKind.RESOURCE_VARIABLE) {
1819 return null;
1820 } else if (data instanceof Callable<?> callableData) {
1821 // In this case, this is a final variable, with an as
1822 // yet unevaluated initializer.
1823 data = null; // to make sure we don't evaluate this twice.
1824 try {
1825 data = callableData.call();
1826 } catch (Exception ex) {
1827 throw new AssertionError(ex);
1828 }
1829 }
1830 return data;
1831 }
1832
1833 public void setData(Object data) {
1834 Assert.check(!(data instanceof Env<?>), this);
1835 this.data = data;
1836 }
1837
1838 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
1839 return v.visitVarSymbol(this, p);
1840 }
1841
1842 public boolean isUnnamedVariable() {
1843 return name.isEmpty();
1844 }
1845 }
1846
1847 public static class RecordComponent extends VarSymbol implements RecordComponentElement {
1848 public MethodSymbol accessor;
1849 public JCTree.JCMethodDecl accessorMeth;
1850
1851 /* if the user happens to erroneously declare two components with the same name, we need a way to differentiate
1852 * them, the code will fail anyway but we need to keep the information for better error recovery
1853 */
1854 private final int pos;
1855
1856 private final boolean isVarargs;
1857
1858 private JCVariableDecl ast;
1859
1860 /**
1861 * Construct a record component, given its flags, name, type and owner.
1862 */
1863 public RecordComponent(Name name, Type type, Symbol owner) {
1864 super(PUBLIC, name, type, owner);
1865 pos = -1;
1866 ast = null;
1867 isVarargs = false;
1868 }
1869
1870 public RecordComponent(VarSymbol field, JCVariableDecl ast) {
1871 this(field, ast, field.type.hasTag(TypeTag.ARRAY) && ((ArrayType)field.type).isVarargs());
1872 }
1873
1874 public RecordComponent(VarSymbol field, JCVariableDecl ast, boolean isVarargs) {
1875 super(PUBLIC, field.name, field.type, field.owner);
1876 this.ast = ast;
1877 this.pos = field.pos;
1878 /* it is better to store the original information for this one, instead of relying
1879 * on the info in the type of the symbol. This is because on the presence of APs
1880 * the symbol will be blown out and we won't be able to know if the original
1881 * record component was declared varargs or not.
1882 */
1883 this.isVarargs = isVarargs;
1884 }
1885
1886 public List<JCAnnotation> getOriginalAnnos() { return this.ast == null ? List.nil() : this.ast.mods.annotations; }
1887
1888 public JCVariableDecl declarationFor() { return this.ast; }
1889
1890 public boolean isVarargs() {
1891 return isVarargs;
1892 }
1893
1894 @Override @DefinedBy(Api.LANGUAGE_MODEL)
1895 public ElementKind getKind() {
1896 return ElementKind.RECORD_COMPONENT;
1897 }
1898
1899 @Override @DefinedBy(Api.LANGUAGE_MODEL)
1900 public ExecutableElement getAccessor() {
1901 return accessor;
1902 }
1903
1904 @Override @DefinedBy(Api.LANGUAGE_MODEL)
1905 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
1906 return v.visitRecordComponent(this, p);
1907 }
1908 }
1909
1910 public static class ParamSymbol extends VarSymbol {
1911 public ParamSymbol(long flags, Name name, Type type, Symbol owner) {
1912 super(flags, name, type, owner);
1913 }
1914
1915 @Override
1916 public Name getSimpleName() {
1917 if ((flags_field & NAME_FILLED) == 0) {
1918 flags_field |= NAME_FILLED;
1919 Symbol rootPack = this;
1920 while (rootPack != null && !(rootPack instanceof RootPackageSymbol)) {
1921 rootPack = rootPack.owner;
1922 }
1923 if (rootPack != null) {
1924 Name inferredName =
1925 ((RootPackageSymbol) rootPack).missingInfoHandler.getParameterName(this);
1926 if (inferredName != null) {
1927 this.name = inferredName;
1928 }
1929 }
1930 }
1931 return super.getSimpleName();
1932 }
1933
1934 }
1935
1936 public static class BindingSymbol extends VarSymbol {
1937
1938 public BindingSymbol(long flags, Name name, Type type, Symbol owner) {
1939 super(flags | Flags.HASINIT | Flags.MATCH_BINDING, name, type, owner);
1940 }
1941
1942 public boolean isAliasFor(BindingSymbol b) {
1943 return aliases().containsAll(b.aliases());
1944 }
1945
1946 List<BindingSymbol> aliases() {
1947 return List.of(this);
1948 }
1949
1950 public void preserveBinding() {
1951 flags_field |= Flags.MATCH_BINDING_TO_OUTER;
1952 }
1953
1954 public boolean isPreserved() {
1955 return (flags_field & Flags.MATCH_BINDING_TO_OUTER) != 0;
1956 }
1957 }
1958
1959 /** A class for method symbols.
1960 */
1961 public static class MethodSymbol extends Symbol implements ExecutableElement {
1962
1963 /** The code of the method. */
1964 public Code code = null;
1965
1966 /** The extra (synthetic/mandated) parameters of the method. */
1967 public List<VarSymbol> extraParams = List.nil();
1968
1969 /** The captured local variables in an anonymous class */
1970 public List<VarSymbol> capturedLocals = List.nil();
1971
1972 /** The parameters of the method. */
1973 public List<VarSymbol> params = null;
1974
1975 /** For an annotation type element, its default value if any.
1976 * The value is null if none appeared in the method
1977 * declaration.
1978 */
1979 public Attribute defaultValue = null;
1980
1981 /** Construct a method symbol, given its flags, name, type and owner.
1982 */
1983 public MethodSymbol(long flags, Name name, Type type, Symbol owner) {
1984 super(MTH, flags, name, type, owner);
1985 if (owner.type.hasTag(TYPEVAR)) Assert.error(owner + "." + name);
1986 }
1987
1988 /** Clone this symbol with new owner.
1989 */
1990 public MethodSymbol clone(Symbol newOwner) {
1991 MethodSymbol m = new MethodSymbol(flags_field, name, type, newOwner) {
1992 @Override
1993 public Symbol baseSymbol() {
1994 return MethodSymbol.this;
1995 }
1996
1997 @Override
1998 public Object poolKey(Types types) {
1999 return new Pair<>(newOwner, baseSymbol());
2000 }
2001 };
2002 m.code = code;
2003 return m;
2004 }
2005
2006 @Override @DefinedBy(Api.LANGUAGE_MODEL)
2007 public Set<Modifier> getModifiers() {
2008 // just in case the method is restricted but that is not a modifier
2009 long flags = flags() & ~RESTRICTED;
2010 return Flags.asModifierSet((flags & DEFAULT) != 0 ? flags & ~ABSTRACT : flags);
2011 }
2012
2013 /** The Java source which this symbol represents.
2014 */
2015 public String toString() {
2016 if ((flags() & BLOCK) != 0) {
2017 return owner.name.toString();
2018 } else {
2019 String s = (name == name.table.names.init)
2020 ? owner.name.toString()
2021 : name.toString();
2022 if (type != null) {
2023 if (type.hasTag(FORALL))
2024 s = "<" + ((ForAll)type).getTypeArguments() + ">" + s;
2025 s += "(" + type.argtypes((flags() & VARARGS) != 0) + ")";
2026 }
2027 return s;
2028 }
2029 }
2030
2031 @Override
2032 public int poolTag() {
2033 return owner.isInterface() ?
2034 ClassFile.CONSTANT_InterfaceMethodref : ClassFile.CONSTANT_Methodref;
2035 }
2036
2037 public boolean isHandle() {
2038 return false;
2039 }
2040
2041
2042 public MethodHandleSymbol asHandle() {
2043 return new MethodHandleSymbol(this);
2044 }
2045
2046 /** find a symbol that this (proxy method) symbol implements.
2047 * @param c The class whose members are searched for
2048 * implementations
2049 */
2050 public Symbol implemented(TypeSymbol c, Types types) {
2051 Symbol impl = null;
2052 for (List<Type> is = types.interfaces(c.type);
2053 impl == null && is.nonEmpty();
2054 is = is.tail) {
2055 TypeSymbol i = is.head.tsym;
2056 impl = implementedIn(i, types);
2057 if (impl == null)
2058 impl = implemented(i, types);
2059 }
2060 return impl;
2061 }
2062
2063 public Symbol implementedIn(TypeSymbol c, Types types) {
2064 Symbol impl = null;
2065 for (Symbol sym : c.members().getSymbolsByName(name)) {
2066 if (this.overrides(sym, (TypeSymbol)owner, types, true) &&
2067 // FIXME: I suspect the following requires a
2068 // subst() for a parametric return type.
2069 types.isSameType(type.getReturnType(),
2070 types.memberType(owner.type, sym).getReturnType())) {
2071 impl = sym;
2072 }
2073 }
2074 return impl;
2075 }
2076
2077 /** Will the erasure of this method be considered by the VM to
2078 * override the erasure of the other when seen from class `origin'?
2079 */
2080 public boolean binaryOverrides(Symbol _other, TypeSymbol origin, Types types) {
2081 if (isConstructor() || _other.kind != MTH) return false;
2082
2083 if (this == _other) return true;
2084 MethodSymbol other = (MethodSymbol)_other;
2085
2086 // check for a direct implementation
2087 if (other.isOverridableIn((TypeSymbol)owner) &&
2088 types.asSuper(owner.type, other.owner) != null &&
2089 types.isSameType(erasure(types), other.erasure(types)))
2090 return true;
2091
2092 // check for an inherited implementation
2093 return
2094 (flags() & ABSTRACT) == 0 &&
2095 other.isOverridableIn(origin) &&
2096 this.isMemberOf(origin, types) &&
2097 types.isSameType(erasure(types), other.erasure(types));
2098 }
2099
2100 /** The implementation of this (abstract) symbol in class origin,
2101 * from the VM's point of view, null if method does not have an
2102 * implementation in class.
2103 * @param origin The class of which the implementation is a member.
2104 */
2105 public MethodSymbol binaryImplementation(ClassSymbol origin, Types types) {
2106 for (TypeSymbol c = origin; c != null; c = types.supertype(c.type).tsym) {
2107 for (Symbol sym : c.members().getSymbolsByName(name)) {
2108 if (sym.kind == MTH &&
2109 ((MethodSymbol)sym).binaryOverrides(this, origin, types))
2110 return (MethodSymbol)sym;
2111 }
2112 }
2113 return null;
2114 }
2115
2116 /** Does this symbol override `other' symbol, when both are seen as
2117 * members of class `origin'? It is assumed that _other is a member
2118 * of origin.
2119 *
2120 * It is assumed that both symbols have the same name. The static
2121 * modifier is ignored for this test.
2122 *
2123 * A quirk in the works is that if the receiver is a method symbol for
2124 * an inherited abstract method we answer false summarily all else being
2125 * immaterial. Abstract "own" methods (i.e `this' is a direct member of
2126 * origin) don't get rejected as summarily and are put to test against the
2127 * suitable criteria.
2128 *
2129 * See JLS 8.4.8.1 (without transitivity) and 8.4.8.4
2130 */
2131 public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult) {
2132 return overrides(_other, origin, types, checkResult, true);
2133 }
2134
2135 /** Does this symbol override `other' symbol, when both are seen as
2136 * members of class `origin'? It is assumed that _other is a member
2137 * of origin.
2138 *
2139 * Caveat: If `this' is an abstract inherited member of origin, it is
2140 * deemed to override `other' only when `requireConcreteIfInherited'
2141 * is false.
2142 *
2143 * It is assumed that both symbols have the same name. The static
2144 * modifier is ignored for this test.
2145 *
2146 * See JLS 8.4.8.1 (without transitivity) and 8.4.8.4
2147 */
2148 public boolean overrides(Symbol _other, TypeSymbol origin, Types types, boolean checkResult,
2149 boolean requireConcreteIfInherited) {
2150 if (isConstructor() || _other.kind != MTH) return false;
2151
2152 if (this == _other) return true;
2153 MethodSymbol other = (MethodSymbol)_other;
2154
2155 // check for a direct implementation
2156 if (other.isOverridableIn((TypeSymbol)owner) &&
2157 types.asSuper(owner.type, other.owner) != null) {
2158 Type mt = types.memberType(owner.type, this);
2159 Type ot = types.memberType(owner.type, other);
2160 if (types.isSubSignature(mt, ot)) {
2161 if (!checkResult)
2162 return true;
2163 if (types.returnTypeSubstitutable(mt, ot))
2164 return true;
2165 }
2166 }
2167
2168 // check for an inherited implementation
2169 if (((flags() & ABSTRACT) != 0 && requireConcreteIfInherited) ||
2170 ((other.flags() & ABSTRACT) == 0 && (other.flags() & DEFAULT) == 0) ||
2171 !other.isOverridableIn(origin) ||
2172 !this.isMemberOf(origin, types))
2173 return false;
2174
2175 // assert types.asSuper(origin.type, other.owner) != null;
2176 Type mt = types.memberType(origin.type, this);
2177 Type ot = types.memberType(origin.type, other);
2178 return
2179 types.isSubSignature(mt, ot) &&
2180 (!checkResult || types.resultSubtype(mt, ot, types.noWarnings));
2181 }
2182
2183 private boolean isOverridableIn(TypeSymbol origin) {
2184 // JLS 8.4.8.1
2185 switch ((int)(flags_field & Flags.AccessFlags)) {
2186 case Flags.PRIVATE:
2187 return false;
2188 case Flags.PUBLIC:
2189 return !this.owner.isInterface() ||
2190 (flags_field & STATIC) == 0;
2191 case Flags.PROTECTED:
2192 return (origin.flags() & INTERFACE) == 0;
2193 case 0:
2194 // for package private: can only override in the same
2195 // package
2196 return
2197 this.packge() == origin.packge() &&
2198 (origin.flags() & INTERFACE) == 0;
2199 default:
2200 return false;
2201 }
2202 }
2203
2204 @Override
2205 public boolean isInheritedIn(Symbol clazz, Types types) {
2206 switch ((int)(flags_field & Flags.AccessFlags)) {
2207 case PUBLIC:
2208 return !this.owner.isInterface() ||
2209 clazz == owner ||
2210 (flags_field & STATIC) == 0;
2211 default:
2212 return super.isInheritedIn(clazz, types);
2213 }
2214 }
2215
2216 public boolean isLambdaMethod() {
2217 return (flags() & LAMBDA_METHOD) == LAMBDA_METHOD;
2218 }
2219
2220 /** override this method to point to the original enclosing method if this method symbol represents a synthetic
2221 * lambda method
2222 */
2223 public MethodSymbol originalEnclosingMethod() {
2224 return this;
2225 }
2226
2227 /** The implementation of this (abstract) symbol in class origin;
2228 * null if none exists. Synthetic methods are not considered
2229 * as possible implementations.
2230 */
2231 public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) {
2232 return implementation(origin, types, checkResult, implementation_filter);
2233 }
2234 // where
2235 public static final Predicate<Symbol> implementation_filter = s ->
2236 s.kind == MTH && (s.flags() & SYNTHETIC) == 0;
2237
2238 public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult, Predicate<Symbol> implFilter) {
2239 MethodSymbol res = types.implementation(this, origin, checkResult, implFilter);
2240 if (res != null)
2241 return res;
2242 // if origin is derived from a raw type, we might have missed
2243 // an implementation because we do not know enough about instantiations.
2244 // in this case continue with the supertype as origin.
2245 if (types.isDerivedRaw(origin.type) && !origin.isInterface())
2246 return implementation(types.supertype(origin.type).tsym, types, checkResult);
2247 else
2248 return null;
2249 }
2250
2251 public List<VarSymbol> params() {
2252 owner.complete();
2253 if (params == null) {
2254 ListBuffer<VarSymbol> newParams = new ListBuffer<>();
2255 int i = 0;
2256 for (Type t : type.getParameterTypes()) {
2257 Name paramName = name.table.fromString("arg" + i);
2258 VarSymbol param = new VarSymbol(PARAMETER, paramName, t, this);
2259 newParams.append(param);
2260 i++;
2261 }
2262 params = newParams.toList();
2263 }
2264 Assert.checkNonNull(params);
2265 return params;
2266 }
2267
2268 public Symbol asMemberOf(Type site, Types types) {
2269 return new MethodSymbol(flags_field, name, types.memberType(site, this), owner);
2270 }
2271
2272 @DefinedBy(Api.LANGUAGE_MODEL)
2273 public ElementKind getKind() {
2274 if (name == name.table.names.init)
2275 return ElementKind.CONSTRUCTOR;
2276 else if (name == name.table.names.clinit)
2277 return ElementKind.STATIC_INIT;
2278 else if ((flags() & BLOCK) != 0)
2279 return isStatic() ? ElementKind.STATIC_INIT : ElementKind.INSTANCE_INIT;
2280 else
2281 return ElementKind.METHOD;
2282 }
2283
2284 public boolean isStaticOrInstanceInit() {
2285 return getKind() == ElementKind.STATIC_INIT ||
2286 getKind() == ElementKind.INSTANCE_INIT;
2287 }
2288
2289 @DefinedBy(Api.LANGUAGE_MODEL)
2290 public Attribute getDefaultValue() {
2291 return defaultValue;
2292 }
2293
2294 @DefinedBy(Api.LANGUAGE_MODEL)
2295 public List<VarSymbol> getParameters() {
2296 return params();
2297 }
2298
2299 @DefinedBy(Api.LANGUAGE_MODEL)
2300 public boolean isVarArgs() {
2301 return (flags() & VARARGS) != 0;
2302 }
2303
2304 @DefinedBy(Api.LANGUAGE_MODEL)
2305 public boolean isDefault() {
2306 return (flags() & DEFAULT) != 0;
2307 }
2308
2309 @DefinedBy(Api.LANGUAGE_MODEL)
2310 public <R, P> R accept(ElementVisitor<R, P> v, P p) {
2311 return v.visitExecutable(this, p);
2312 }
2313
2314 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
2315 return v.visitMethodSymbol(this, p);
2316 }
2317
2318 @DefinedBy(Api.LANGUAGE_MODEL)
2319 public Type getReceiverType() {
2320 return asType().getReceiverType();
2321 }
2322
2323 public Type implicitReceiverType() {
2324 ClassSymbol enclosingClass = enclClass();
2325 if (enclosingClass == null) {
2326 return null;
2327 }
2328 Type enclosingType = enclosingClass.type;
2329 if (isConstructor()) {
2330 return enclosingType.getEnclosingType();
2331 }
2332 if (!isStatic()) {
2333 return enclosingType;
2334 }
2335 return null;
2336 }
2337
2338 @DefinedBy(Api.LANGUAGE_MODEL)
2339 public Type getReturnType() {
2340 return asType().getReturnType();
2341 }
2342
2343 @DefinedBy(Api.LANGUAGE_MODEL)
2344 public List<Type> getThrownTypes() {
2345 return asType().getThrownTypes();
2346 }
2347 }
2348
2349 /** A class for invokedynamic method calls.
2350 */
2351 public static class DynamicMethodSymbol extends MethodSymbol implements Dynamic {
2352
2353 public LoadableConstant[] staticArgs;
2354 public MethodHandleSymbol bsm;
2355
2356 public DynamicMethodSymbol(Name name, Symbol owner, MethodHandleSymbol bsm, Type type, LoadableConstant[] staticArgs) {
2357 super(0, name, type, owner);
2358 this.bsm = bsm;
2359 this.staticArgs = staticArgs;
2360 }
2361
2362 @Override
2363 public Name name() {
2364 return name;
2365 }
2366
2367 @Override
2368 public boolean isDynamic() {
2369 return true;
2370 }
2371
2372 @Override
2373 public LoadableConstant[] staticArgs() {
2374 return staticArgs;
2375 }
2376
2377 @Override
2378 public MethodHandleSymbol bootstrapMethod() {
2379 return bsm;
2380 }
2381
2382 @Override
2383 public int poolTag() {
2384 return ClassFile.CONSTANT_InvokeDynamic;
2385 }
2386
2387 @Override
2388 public Type dynamicType() {
2389 return type;
2390 }
2391 }
2392
2393 /** A class for condy.
2394 */
2395 public static class DynamicVarSymbol extends VarSymbol implements Dynamic, LoadableConstant {
2396 public LoadableConstant[] staticArgs;
2397 public MethodHandleSymbol bsm;
2398
2399 public DynamicVarSymbol(Name name, Symbol owner, MethodHandleSymbol bsm, Type type, LoadableConstant[] staticArgs) {
2400 super(0, name, type, owner);
2401 this.bsm = bsm;
2402 this.staticArgs = staticArgs;
2403 }
2404
2405 @Override
2406 public Name name() {
2407 return name;
2408 }
2409
2410 @Override
2411 public boolean isDynamic() {
2412 return true;
2413 }
2414
2415 @Override
2416 public PoolConstant dynamicType() {
2417 return type;
2418 }
2419
2420 @Override
2421 public LoadableConstant[] staticArgs() {
2422 return staticArgs;
2423 }
2424
2425 @Override
2426 public LoadableConstant bootstrapMethod() {
2427 return bsm;
2428 }
2429
2430 @Override
2431 public int poolTag() {
2432 return ClassFile.CONSTANT_Dynamic;
2433 }
2434 }
2435
2436 /** A class for method handles.
2437 */
2438 public static class MethodHandleSymbol extends MethodSymbol implements LoadableConstant {
2439
2440 private Symbol refSym;
2441 private boolean getter;
2442
2443 public MethodHandleSymbol(Symbol msym) {
2444 this(msym, false);
2445 }
2446
2447 public MethodHandleSymbol(Symbol msym, boolean getter) {
2448 super(msym.flags_field, msym.name, msym.type, msym.owner);
2449 this.refSym = msym;
2450 this.getter = getter;
2451 }
2452
2453 /**
2454 * Returns the kind associated with this method handle.
2455 */
2456 public int referenceKind() {
2457 if (refSym.kind == VAR) {
2458 return getter ?
2459 refSym.isStatic() ? ClassFile.REF_getStatic : ClassFile.REF_getField :
2460 refSym.isStatic() ? ClassFile.REF_putStatic : ClassFile.REF_putField;
2461 } else {
2462 if (refSym.isConstructor()) {
2463 return ClassFile.REF_newInvokeSpecial;
2464 } else {
2465 if (refSym.isStatic()) {
2466 return ClassFile.REF_invokeStatic;
2467 } else if ((refSym.flags() & PRIVATE) != 0 && !allowPrivateInvokeVirtual()) {
2468 return ClassFile.REF_invokeSpecial;
2469 } else if (refSym.enclClass().isInterface()) {
2470 return ClassFile.REF_invokeInterface;
2471 } else {
2472 return ClassFile.REF_invokeVirtual;
2473 }
2474 }
2475 }
2476 }
2477
2478 private boolean allowPrivateInvokeVirtual() {
2479 Symbol rootPack = this;
2480 while (rootPack != null && !(rootPack instanceof RootPackageSymbol)) {
2481 rootPack = rootPack.owner;
2482 }
2483 return rootPack != null && ((RootPackageSymbol) rootPack).allowPrivateInvokeVirtual;
2484 }
2485 @Override
2486 public int poolTag() {
2487 return ClassFile.CONSTANT_MethodHandle;
2488 }
2489
2490 @Override
2491 public Object poolKey(Types types) {
2492 return new Pair<>(baseSymbol(), referenceKind());
2493 }
2494
2495 @Override
2496 public MethodHandleSymbol asHandle() {
2497 return this;
2498 }
2499
2500 @Override
2501 public Symbol baseSymbol() {
2502 return refSym;
2503 }
2504
2505
2506 @Override
2507 public boolean isHandle() {
2508 return true;
2509 }
2510 }
2511
2512 /** A class for predefined operators.
2513 */
2514 public static class OperatorSymbol extends MethodSymbol {
2515
2516 public int opcode;
2517 private int accessCode = Integer.MIN_VALUE;
2518
2519 public OperatorSymbol(Name name, Type type, int opcode, Symbol owner) {
2520 super(PUBLIC | STATIC, name, type, owner);
2521 this.opcode = opcode;
2522 }
2523
2524 @Override
2525 public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
2526 return v.visitOperatorSymbol(this, p);
2527 }
2528
2529 public int getAccessCode(Tag tag) {
2530 if (accessCode != Integer.MIN_VALUE && !tag.isIncOrDecUnaryOp()) {
2531 return accessCode;
2532 }
2533 accessCode = AccessCode.from(tag, opcode);
2534 return accessCode;
2535 }
2536
2537 /** Access codes for dereferencing, assignment,
2538 * and pre/post increment/decrement.
2539
2540 * All access codes for accesses to the current class are even.
2541 * If a member of the superclass should be accessed instead (because
2542 * access was via a qualified super), add one to the corresponding code
2543 * for the current class, making the number odd.
2544 * This numbering scheme is used by the backend to decide whether
2545 * to issue an invokevirtual or invokespecial call.
2546 *
2547 * @see Gen#visitSelect(JCFieldAccess tree)
2548 */
2549 public enum AccessCode {
2550 UNKNOWN(-1, Tag.NO_TAG),
2551 DEREF(0, Tag.NO_TAG),
2552 ASSIGN(2, Tag.ASSIGN),
2553 PREINC(4, Tag.PREINC),
2554 PREDEC(6, Tag.PREDEC),
2555 POSTINC(8, Tag.POSTINC),
2556 POSTDEC(10, Tag.POSTDEC),
2557 FIRSTASGOP(12, Tag.NO_TAG);
2558
2559 public final int code;
2560 public final Tag tag;
2561 public static final int numberOfAccessCodes = (lushrl - ishll + lxor + 2 - iadd) * 2 + FIRSTASGOP.code + 2;
2562
2563 AccessCode(int code, Tag tag) {
2564 this.code = code;
2565 this.tag = tag;
2566 }
2567
2568 public static AccessCode getFromCode(int code) {
2569 for (AccessCode aCodes : AccessCode.values()) {
2570 if (aCodes.code == code) {
2571 return aCodes;
2572 }
2573 }
2574 return UNKNOWN;
2575 }
2576
2577 static int from(Tag tag, int opcode) {
2578 /** Map bytecode of binary operation to access code of corresponding
2579 * assignment operation. This is always an even number.
2580 */
2581 switch (tag) {
2582 case PREINC:
2583 return AccessCode.PREINC.code;
2584 case PREDEC:
2585 return AccessCode.PREDEC.code;
2586 case POSTINC:
2587 return AccessCode.POSTINC.code;
2588 case POSTDEC:
2589 return AccessCode.POSTDEC.code;
2590 }
2591 if (iadd <= opcode && opcode <= lxor) {
2592 return (opcode - iadd) * 2 + FIRSTASGOP.code;
2593 } else if (opcode == string_add) {
2594 return (lxor + 1 - iadd) * 2 + FIRSTASGOP.code;
2595 } else if (ishll <= opcode && opcode <= lushrl) {
2596 return (opcode - ishll + lxor + 2 - iadd) * 2 + FIRSTASGOP.code;
2597 }
2598 return -1;
2599 }
2600 }
2601 }
2602
2603 /** Symbol completer interface.
2604 */
2605 public static interface Completer {
2606
2607 /** Dummy completer to be used when the symbol has been completed or
2608 * does not need completion.
2609 */
2610 public static final Completer NULL_COMPLETER = new Completer() {
2611 public void complete(Symbol sym) { }
2612 public boolean isTerminal() { return true; }
2613 };
2614
2615 void complete(Symbol sym) throws CompletionFailure;
2616
2617 /** Returns true if this completer is <em>terminal</em>. A terminal
2618 * completer is used as a place holder when the symbol is completed.
2619 * Calling complete on a terminal completer will not affect the symbol.
2620 *
2621 * The dummy NULL_COMPLETER and the GraphDependencies completer are
2622 * examples of terminal completers.
2623 *
2624 * @return true iff this completer is terminal
2625 */
2626 default boolean isTerminal() {
2627 return false;
2628 }
2629 }
2630
2631 public static class CompletionFailure extends RuntimeException {
2632 private static final long serialVersionUID = 0;
2633 public final transient DeferredCompletionFailureHandler dcfh;
2634 public transient Symbol sym;
2635
2636 /** A diagnostic object describing the failure
2637 */
2638 private transient JCDiagnostic diag;
2639
2640 private transient Supplier<JCDiagnostic> diagSupplier;
2641
2642 public CompletionFailure(Symbol sym, Supplier<JCDiagnostic> diagSupplier, DeferredCompletionFailureHandler dcfh) {
2643 this.dcfh = dcfh;
2644 this.sym = sym;
2645 this.diagSupplier = diagSupplier;
2646 // this.printStackTrace();//DEBUG
2647 }
2648
2649 public JCDiagnostic getDiagnostic() {
2650 if (diag == null && diagSupplier != null) {
2651 diag = diagSupplier.get();
2652 }
2653 return diag;
2654 }
2655
2656 @Override
2657 public String getMessage() {
2658 return getDiagnostic().getMessage(null);
2659 }
2660
2661 public JCDiagnostic getDetailValue() {
2662 return getDiagnostic();
2663 }
2664
2665 @Override
2666 public CompletionFailure initCause(Throwable cause) {
2667 super.initCause(cause);
2668 return this;
2669 }
2670
2671 public void resetDiagnostic(Supplier<JCDiagnostic> diagSupplier) {
2672 this.diagSupplier = diagSupplier;
2673 this.diag = null;
2674 }
2675
2676 }
2677
2678 /**
2679 * A visitor for symbols. A visitor is used to implement operations
2680 * (or relations) on symbols. Most common operations on types are
2681 * binary relations and this interface is designed for binary
2682 * relations, that is, operations on the form
2683 * Symbol × P → R.
2684 * <!-- In plain text: Type x P -> R -->
2685 *
2686 * @param <R> the return type of the operation implemented by this
2687 * visitor; use Void if no return type is needed.
2688 * @param <P> the type of the second argument (the first being the
2689 * symbol itself) of the operation implemented by this visitor; use
2690 * Void if a second argument is not needed.
2691 */
2692 public interface Visitor<R,P> {
2693 R visitClassSymbol(ClassSymbol s, P arg);
2694 R visitMethodSymbol(MethodSymbol s, P arg);
2695 R visitPackageSymbol(PackageSymbol s, P arg);
2696 R visitOperatorSymbol(OperatorSymbol s, P arg);
2697 R visitVarSymbol(VarSymbol s, P arg);
2698 R visitTypeSymbol(TypeSymbol s, P arg);
2699 R visitSymbol(Symbol s, P arg);
2700 }
2701 }