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 */
258 * by compiled source files.
259 */
260 private final Map<Name, Map<ModuleSymbol,ClassSymbol>> classes = new HashMap<>();
261
262 /** A hashtable containing the encountered packages.
263 * the table should be updated from outside to reflect packages defined
264 * by compiled source files.
265 */
266 private final Map<Name, Map<ModuleSymbol,PackageSymbol>> packages = new HashMap<>();
267
268 /** A hashtable giving the encountered modules.
269 */
270 private final Map<Name, ModuleSymbol> modules = new LinkedHashMap<>();
271
272 private final Map<Types.UniqueType, VarSymbol> classFields = new HashMap<>();
273
274 public VarSymbol getClassField(Type type, Types types) {
275 return classFields.computeIfAbsent(
276 new UniqueType(type, types), k -> {
277 Type arg = null;
278 if (type.getTag() == ARRAY || type.getTag() == CLASS)
279 arg = types.erasure(type);
280 else if (type.isPrimitiveOrVoid())
281 arg = types.boxedClass(type).type;
282 else
283 throw new AssertionError(type);
284
285 Type t = new ClassType(
286 classType.getEnclosingType(), List.of(arg), classType.tsym);
287 return new VarSymbol(
288 STATIC | PUBLIC | FINAL, names._class, t, type.tsym);
289 });
290 }
291
292 public void initType(Type type, ClassSymbol c) {
293 type.tsym = c;
294 typeOfTag[type.getTag().ordinal()] = type;
295 }
296
297 public void initType(Type type, String name) {
298 initType(
299 type,
637 ClassType arrayClassType = (ClassType)arrayClass.type;
638 arrayClassType.supertype_field = objectType;
639 arrayClassType.interfaces_field = List.of(cloneableType, serializableType);
640 arrayClass.members_field = WriteableScope.create(arrayClass);
641 lengthVar = new VarSymbol(
642 PUBLIC | FINAL,
643 names.length,
644 intType,
645 arrayClass);
646 arrayClass.members().enter(lengthVar);
647 arrayCloneMethod = new MethodSymbol(
648 PUBLIC,
649 names.clone,
650 new MethodType(List.nil(), objectType,
651 List.nil(), methodClass),
652 arrayClass);
653 arrayClass.members().enter(arrayCloneMethod);
654
655 if (java_base != noModule)
656 java_base.completer = moduleCompleter::complete; //bootstrap issues
657
658 }
659
660 /** Define a new class given its name and owner.
661 */
662 public ClassSymbol defineClass(Name name, Symbol owner) {
663 ClassSymbol c = new ClassSymbol(0, name, owner);
664 c.completer = initialCompleter;
665 return c;
666 }
667
668 /** Create a new toplevel or member class symbol with given name
669 * and owner and enter in `classes' unless already there.
670 */
671 public ClassSymbol enterClass(ModuleSymbol msym, Name name, TypeSymbol owner) {
672 Assert.checkNonNull(msym);
673 Name flatname = TypeSymbol.formFlatName(name, owner);
674 ClassSymbol c = getClass(msym, flatname);
675 if (c == null) {
676 c = defineClass(name, owner);
677 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 */
262 * by compiled source files.
263 */
264 private final Map<Name, Map<ModuleSymbol,ClassSymbol>> classes = new HashMap<>();
265
266 /** A hashtable containing the encountered packages.
267 * the table should be updated from outside to reflect packages defined
268 * by compiled source files.
269 */
270 private final Map<Name, Map<ModuleSymbol,PackageSymbol>> packages = new HashMap<>();
271
272 /** A hashtable giving the encountered modules.
273 */
274 private final Map<Name, ModuleSymbol> modules = new LinkedHashMap<>();
275
276 private final Map<Types.UniqueType, VarSymbol> classFields = new HashMap<>();
277
278 public VarSymbol getClassField(Type type, Types types) {
279 return classFields.computeIfAbsent(
280 new UniqueType(type, types), k -> {
281 Type arg = null;
282 if (type.getTag() == ARRAY || type.getTag() == CLASS) {
283 /* Temporary treatment for primitive class: Given a primitive class V that implements
284 I1, I2, ... In, V.class is typed to be Class<? extends Object & I1 & I2 .. & In>
285 */
286 if (allowPrimitiveClasses && type.isPrimitiveClass()) {
287 List<Type> bounds = List.of(objectType).appendList(((ClassSymbol) type.tsym).getInterfaces());
288 arg = new WildcardType(bounds.size() > 1 ? types.makeIntersectionType(bounds) : objectType, BoundKind.EXTENDS, boundClass);
289 } else {
290 arg = types.erasure(type);
291 }
292 }
293 else if (type.isPrimitiveOrVoid())
294 arg = types.boxedClass(type).type;
295 else
296 throw new AssertionError(type);
297
298 Type t = new ClassType(
299 classType.getEnclosingType(), List.of(arg), classType.tsym);
300 return new VarSymbol(
301 STATIC | PUBLIC | FINAL, names._class, t, type.tsym);
302 });
303 }
304
305 public void initType(Type type, ClassSymbol c) {
306 type.tsym = c;
307 typeOfTag[type.getTag().ordinal()] = type;
308 }
309
310 public void initType(Type type, String name) {
311 initType(
312 type,
650 ClassType arrayClassType = (ClassType)arrayClass.type;
651 arrayClassType.supertype_field = objectType;
652 arrayClassType.interfaces_field = List.of(cloneableType, serializableType);
653 arrayClass.members_field = WriteableScope.create(arrayClass);
654 lengthVar = new VarSymbol(
655 PUBLIC | FINAL,
656 names.length,
657 intType,
658 arrayClass);
659 arrayClass.members().enter(lengthVar);
660 arrayCloneMethod = new MethodSymbol(
661 PUBLIC,
662 names.clone,
663 new MethodType(List.nil(), objectType,
664 List.nil(), methodClass),
665 arrayClass);
666 arrayClass.members().enter(arrayCloneMethod);
667
668 if (java_base != noModule)
669 java_base.completer = moduleCompleter::complete; //bootstrap issues
670 Options options = Options.instance(context);
671 allowPrimitiveClasses = Feature.PRIMITIVE_CLASSES.allowedInSource(source) && options.isSet("enablePrimitiveClasses");
672 }
673
674 /** Define a new class given its name and owner.
675 */
676 public ClassSymbol defineClass(Name name, Symbol owner) {
677 ClassSymbol c = new ClassSymbol(0, name, owner);
678 c.completer = initialCompleter;
679 return c;
680 }
681
682 /** Create a new toplevel or member class symbol with given name
683 * and owner and enter in `classes' unless already there.
684 */
685 public ClassSymbol enterClass(ModuleSymbol msym, Name name, TypeSymbol owner) {
686 Assert.checkNonNull(msym);
687 Name flatname = TypeSymbol.formFlatName(name, owner);
688 ClassSymbol c = getClass(msym, flatname);
689 if (c == null) {
690 c = defineClass(name, owner);
691 doEnterClass(msym, c);
|