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