35 import javax.lang.model.element.ElementVisitor;
36
37 import com.sun.tools.javac.code.Scope.WriteableScope;
38 import com.sun.tools.javac.code.Source.Feature;
39 import com.sun.tools.javac.code.Symbol.ClassSymbol;
40 import com.sun.tools.javac.code.Symbol.Completer;
41 import com.sun.tools.javac.code.Symbol.CompletionFailure;
42 import com.sun.tools.javac.code.Symbol.MethodSymbol;
43 import com.sun.tools.javac.code.Symbol.ModuleSymbol;
44 import com.sun.tools.javac.code.Symbol.PackageSymbol;
45 import com.sun.tools.javac.code.Symbol.RootPackageSymbol;
46 import com.sun.tools.javac.code.Symbol.TypeSymbol;
47 import com.sun.tools.javac.code.Symbol.VarSymbol;
48 import com.sun.tools.javac.code.Type.BottomType;
49 import com.sun.tools.javac.code.Type.ClassType;
50 import com.sun.tools.javac.code.Type.ErrorType;
51 import com.sun.tools.javac.code.Type.JCPrimitiveType;
52 import com.sun.tools.javac.code.Type.JCVoidType;
53 import com.sun.tools.javac.code.Type.MethodType;
54 import com.sun.tools.javac.code.Type.UnknownType;
55 import com.sun.tools.javac.code.Types.UniqueType;
56 import com.sun.tools.javac.comp.Modules;
57 import com.sun.tools.javac.jvm.Target;
58 import com.sun.tools.javac.util.Assert;
59 import com.sun.tools.javac.util.Context;
60 import com.sun.tools.javac.util.Convert;
61 import com.sun.tools.javac.util.DefinedBy;
62 import com.sun.tools.javac.util.DefinedBy.Api;
63 import com.sun.tools.javac.util.Iterators;
64 import com.sun.tools.javac.util.JavacMessages;
65 import com.sun.tools.javac.util.List;
66 import com.sun.tools.javac.util.Name;
67 import com.sun.tools.javac.util.Names;
68
69 import static com.sun.tools.javac.code.Flags.*;
70 import static com.sun.tools.javac.code.Kinds.Kind.*;
71 import static com.sun.tools.javac.code.TypeTag.*;
72
73 /** A class that defines all predefined constants and operators
74 * as well as special classes such as java.lang.Object, which need
75 * to be known to the compiler. All symbols are held in instance
76 * fields. This makes it possible to work in multiple concurrent
77 * projects, which might use different class files for library classes.
78 *
79 * <p><b>This is NOT part of any supported API.
80 * If you write code that depends on this, you do so at your own risk.
81 * This code and its internal interfaces are subject to change or
82 * deletion without notice.</b>
83 */
84 public class Symtab {
85 /** The context key for the symbol table. */
86 protected static final Context.Key<Symtab> symtabKey = new Context.Key<>();
87
88 /** Get the symbol table instance. */
89 public static Symtab instance(Context context) {
90 Symtab instance = context.get(symtabKey);
91 if (instance == null)
92 instance = new Symtab(context);
93 return instance;
94 }
95
96 /** Builtin types.
97 */
98 public final JCPrimitiveType byteType = new JCPrimitiveType(BYTE, null);
99 public final JCPrimitiveType charType = new JCPrimitiveType(CHAR, null);
100 public final JCPrimitiveType shortType = new JCPrimitiveType(SHORT, null);
101 public final JCPrimitiveType intType = new JCPrimitiveType(INT, null);
102 public final JCPrimitiveType longType = new JCPrimitiveType(LONG, null);
103 public final JCPrimitiveType floatType = new JCPrimitiveType(FLOAT, null);
104 public final JCPrimitiveType doubleType = new JCPrimitiveType(DOUBLE, null);
105 public final JCPrimitiveType booleanType = new JCPrimitiveType(BOOLEAN, null);
106 public final Type botType = new BottomType();
107 public final JCVoidType voidType = new JCVoidType();
108
109 private final Names names;
110 private final JavacMessages messages;
111 private final Completer initialCompleter;
112 private final Completer moduleCompleter;
113
114 /** A symbol for the unnamed module.
115 */
270 * by compiled source files.
271 */
272 private final Map<Name, Map<ModuleSymbol,ClassSymbol>> classes = new HashMap<>();
273
274 /** A hashtable containing the encountered packages.
275 * the table should be updated from outside to reflect packages defined
276 * by compiled source files.
277 */
278 private final Map<Name, Map<ModuleSymbol,PackageSymbol>> packages = new HashMap<>();
279
280 /** A hashtable giving the encountered modules.
281 */
282 private final Map<Name, ModuleSymbol> modules = new LinkedHashMap<>();
283
284 private final Map<Types.UniqueType, VarSymbol> classFields = new HashMap<>();
285
286 public VarSymbol getClassField(Type type, Types types) {
287 return classFields.computeIfAbsent(
288 new UniqueType(type, types), k -> {
289 Type arg = null;
290 if (type.getTag() == ARRAY || type.getTag() == CLASS)
291 arg = types.erasure(type);
292 else if (type.isPrimitiveOrVoid())
293 arg = types.boxedClass(type).type;
294 else
295 throw new AssertionError(type);
296
297 Type t = new ClassType(
298 classType.getEnclosingType(), List.of(arg), classType.tsym);
299 return new VarSymbol(
300 STATIC | PUBLIC | FINAL, names._class, t, type.tsym);
301 });
302 }
303
304 public void initType(Type type, ClassSymbol c) {
305 type.tsym = c;
306 typeOfTag[type.getTag().ordinal()] = type;
307 }
308
309 public void initType(Type type, String name) {
310 initType(
311 type,
660 ClassType arrayClassType = (ClassType)arrayClass.type;
661 arrayClassType.supertype_field = objectType;
662 arrayClassType.interfaces_field = List.of(cloneableType, serializableType);
663 arrayClass.members_field = WriteableScope.create(arrayClass);
664 lengthVar = new VarSymbol(
665 PUBLIC | FINAL,
666 names.length,
667 intType,
668 arrayClass);
669 arrayClass.members().enter(lengthVar);
670 arrayCloneMethod = new MethodSymbol(
671 PUBLIC,
672 names.clone,
673 new MethodType(List.nil(), objectType,
674 List.nil(), methodClass),
675 arrayClass);
676 arrayClass.members().enter(arrayCloneMethod);
677
678 if (java_base != noModule)
679 java_base.completer = moduleCompleter::complete; //bootstrap issues
680
681 }
682
683 /** Define a new class given its name and owner.
684 */
685 public ClassSymbol defineClass(Name name, Symbol owner) {
686 ClassSymbol c = new ClassSymbol(0, name, owner);
687 c.completer = initialCompleter;
688 return c;
689 }
690
691 /** Create a new toplevel or member class symbol with given name
692 * and owner and enter in `classes' unless already there.
693 */
694 public ClassSymbol enterClass(ModuleSymbol msym, Name name, TypeSymbol owner) {
695 Assert.checkNonNull(msym);
696 Name flatname = TypeSymbol.formFlatName(name, owner);
697 ClassSymbol c = getClass(msym, flatname);
698 if (c == null) {
699 c = defineClass(name, owner);
700 doEnterClass(msym, c);
|
35 import javax.lang.model.element.ElementVisitor;
36
37 import com.sun.tools.javac.code.Scope.WriteableScope;
38 import com.sun.tools.javac.code.Source.Feature;
39 import com.sun.tools.javac.code.Symbol.ClassSymbol;
40 import com.sun.tools.javac.code.Symbol.Completer;
41 import com.sun.tools.javac.code.Symbol.CompletionFailure;
42 import com.sun.tools.javac.code.Symbol.MethodSymbol;
43 import com.sun.tools.javac.code.Symbol.ModuleSymbol;
44 import com.sun.tools.javac.code.Symbol.PackageSymbol;
45 import com.sun.tools.javac.code.Symbol.RootPackageSymbol;
46 import com.sun.tools.javac.code.Symbol.TypeSymbol;
47 import com.sun.tools.javac.code.Symbol.VarSymbol;
48 import com.sun.tools.javac.code.Type.BottomType;
49 import com.sun.tools.javac.code.Type.ClassType;
50 import com.sun.tools.javac.code.Type.ErrorType;
51 import com.sun.tools.javac.code.Type.JCPrimitiveType;
52 import com.sun.tools.javac.code.Type.JCVoidType;
53 import com.sun.tools.javac.code.Type.MethodType;
54 import com.sun.tools.javac.code.Type.UnknownType;
55 import com.sun.tools.javac.code.Type.WildcardType;
56 import com.sun.tools.javac.code.Types.UniqueType;
57 import com.sun.tools.javac.comp.Modules;
58 import com.sun.tools.javac.jvm.Target;
59 import com.sun.tools.javac.util.Assert;
60 import com.sun.tools.javac.util.Context;
61 import com.sun.tools.javac.util.Convert;
62 import com.sun.tools.javac.util.DefinedBy;
63 import com.sun.tools.javac.util.DefinedBy.Api;
64 import com.sun.tools.javac.util.Iterators;
65 import com.sun.tools.javac.util.JavacMessages;
66 import com.sun.tools.javac.util.List;
67 import com.sun.tools.javac.util.Name;
68 import com.sun.tools.javac.util.Names;
69 import com.sun.tools.javac.util.Options;
70
71 import static com.sun.tools.javac.code.Flags.*;
72 import static com.sun.tools.javac.code.Kinds.Kind.*;
73 import static com.sun.tools.javac.code.TypeTag.*;
74
75 /** A class that defines all predefined constants and operators
76 * as well as special classes such as java.lang.Object, which need
77 * to be known to the compiler. All symbols are held in instance
78 * fields. This makes it possible to work in multiple concurrent
79 * projects, which might use different class files for library classes.
80 *
81 * <p><b>This is NOT part of any supported API.
82 * If you write code that depends on this, you do so at your own risk.
83 * This code and its internal interfaces are subject to change or
84 * deletion without notice.</b>
85 */
86 public class Symtab {
87 /** The context key for the symbol table. */
88 protected static final Context.Key<Symtab> symtabKey = new Context.Key<>();
89
90 /** Get the symbol table instance. */
91 public static Symtab instance(Context context) {
92 Symtab instance = context.get(symtabKey);
93 if (instance == null)
94 instance = new Symtab(context);
95 return instance;
96 }
97
98 private final boolean allowPrimitiveClasses;
99
100 /** Builtin types.
101 */
102 public final JCPrimitiveType byteType = new JCPrimitiveType(BYTE, null);
103 public final JCPrimitiveType charType = new JCPrimitiveType(CHAR, null);
104 public final JCPrimitiveType shortType = new JCPrimitiveType(SHORT, null);
105 public final JCPrimitiveType intType = new JCPrimitiveType(INT, null);
106 public final JCPrimitiveType longType = new JCPrimitiveType(LONG, null);
107 public final JCPrimitiveType floatType = new JCPrimitiveType(FLOAT, null);
108 public final JCPrimitiveType doubleType = new JCPrimitiveType(DOUBLE, null);
109 public final JCPrimitiveType booleanType = new JCPrimitiveType(BOOLEAN, null);
110 public final Type botType = new BottomType();
111 public final JCVoidType voidType = new JCVoidType();
112
113 private final Names names;
114 private final JavacMessages messages;
115 private final Completer initialCompleter;
116 private final Completer moduleCompleter;
117
118 /** A symbol for the unnamed module.
119 */
274 * by compiled source files.
275 */
276 private final Map<Name, Map<ModuleSymbol,ClassSymbol>> classes = new HashMap<>();
277
278 /** A hashtable containing the encountered packages.
279 * the table should be updated from outside to reflect packages defined
280 * by compiled source files.
281 */
282 private final Map<Name, Map<ModuleSymbol,PackageSymbol>> packages = new HashMap<>();
283
284 /** A hashtable giving the encountered modules.
285 */
286 private final Map<Name, ModuleSymbol> modules = new LinkedHashMap<>();
287
288 private final Map<Types.UniqueType, VarSymbol> classFields = new HashMap<>();
289
290 public VarSymbol getClassField(Type type, Types types) {
291 return classFields.computeIfAbsent(
292 new UniqueType(type, types), k -> {
293 Type arg = null;
294 if (type.getTag() == ARRAY || type.getTag() == CLASS) {
295 /* Temporary treatment for primitive class: Given a primitive class V that implements
296 I1, I2, ... In, V.class is typed to be Class<? extends Object & I1 & I2 .. & In>
297 */
298 if (allowPrimitiveClasses && type.isPrimitiveClass()) {
299 List<Type> bounds = List.of(objectType).appendList(((ClassSymbol) type.tsym).getInterfaces());
300 arg = new WildcardType(bounds.size() > 1 ? types.makeIntersectionType(bounds) : objectType, BoundKind.EXTENDS, boundClass);
301 } else {
302 arg = types.erasure(type);
303 }
304 }
305 else if (type.isPrimitiveOrVoid())
306 arg = types.boxedClass(type).type;
307 else
308 throw new AssertionError(type);
309
310 Type t = new ClassType(
311 classType.getEnclosingType(), List.of(arg), classType.tsym);
312 return new VarSymbol(
313 STATIC | PUBLIC | FINAL, names._class, t, type.tsym);
314 });
315 }
316
317 public void initType(Type type, ClassSymbol c) {
318 type.tsym = c;
319 typeOfTag[type.getTag().ordinal()] = type;
320 }
321
322 public void initType(Type type, String name) {
323 initType(
324 type,
673 ClassType arrayClassType = (ClassType)arrayClass.type;
674 arrayClassType.supertype_field = objectType;
675 arrayClassType.interfaces_field = List.of(cloneableType, serializableType);
676 arrayClass.members_field = WriteableScope.create(arrayClass);
677 lengthVar = new VarSymbol(
678 PUBLIC | FINAL,
679 names.length,
680 intType,
681 arrayClass);
682 arrayClass.members().enter(lengthVar);
683 arrayCloneMethod = new MethodSymbol(
684 PUBLIC,
685 names.clone,
686 new MethodType(List.nil(), objectType,
687 List.nil(), methodClass),
688 arrayClass);
689 arrayClass.members().enter(arrayCloneMethod);
690
691 if (java_base != noModule)
692 java_base.completer = moduleCompleter::complete; //bootstrap issues
693 Options options = Options.instance(context);
694 allowPrimitiveClasses = Feature.PRIMITIVE_CLASSES.allowedInSource(source) && options.isSet("enablePrimitiveClasses");
695 }
696
697 /** Define a new class given its name and owner.
698 */
699 public ClassSymbol defineClass(Name name, Symbol owner) {
700 ClassSymbol c = new ClassSymbol(0, name, owner);
701 c.completer = initialCompleter;
702 return c;
703 }
704
705 /** Create a new toplevel or member class symbol with given name
706 * and owner and enter in `classes' unless already there.
707 */
708 public ClassSymbol enterClass(ModuleSymbol msym, Name name, TypeSymbol owner) {
709 Assert.checkNonNull(msym);
710 Name flatname = TypeSymbol.formFlatName(name, owner);
711 ClassSymbol c = getClass(msym, flatname);
712 if (c == null) {
713 c = defineClass(name, owner);
714 doEnterClass(msym, c);
|