1 /* 2 * Copyright (c) 1999, 2018, 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.util.Collection; 29 import java.util.Collections; 30 import java.util.EnumSet; 31 import java.util.HashMap; 32 import java.util.LinkedHashMap; 33 import java.util.Map; 34 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.TypeSymbol; 46 import com.sun.tools.javac.code.Symbol.VarSymbol; 47 import com.sun.tools.javac.code.Type.BottomType; 48 import com.sun.tools.javac.code.Type.ClassType; 49 import com.sun.tools.javac.code.Type.ErrorType; 50 import com.sun.tools.javac.code.Type.JCPrimitiveType; 51 import com.sun.tools.javac.code.Type.JCVoidType; 52 import com.sun.tools.javac.code.Type.MethodType; 53 import com.sun.tools.javac.code.Type.UnknownType; 54 import com.sun.tools.javac.code.Types.UniqueType; 55 import com.sun.tools.javac.comp.Modules; 56 import com.sun.tools.javac.util.Assert; 57 import com.sun.tools.javac.util.Context; 58 import com.sun.tools.javac.util.Convert; 59 import com.sun.tools.javac.util.DefinedBy; 60 import com.sun.tools.javac.util.DefinedBy.Api; 61 import com.sun.tools.javac.util.Iterators; 62 import com.sun.tools.javac.util.JavacMessages; 63 import com.sun.tools.javac.util.List; 64 import com.sun.tools.javac.util.Name; 65 import com.sun.tools.javac.util.Names; 66 67 import static com.sun.tools.javac.code.Flags.*; 68 import static com.sun.tools.javac.code.Kinds.Kind.*; 69 import static com.sun.tools.javac.code.TypeTag.*; 70 71 /** A class that defines all predefined constants and operators 72 * as well as special classes such as java.lang.Object, which need 73 * to be known to the compiler. All symbols are held in instance 74 * fields. This makes it possible to work in multiple concurrent 75 * projects, which might use different class files for library classes. 76 * 77 * <p><b>This is NOT part of any supported API. 78 * If you write code that depends on this, you do so at your own risk. 79 * This code and its internal interfaces are subject to change or 80 * deletion without notice.</b> 81 */ 82 public class Symtab { 83 /** The context key for the symbol table. */ 84 protected static final Context.Key<Symtab> symtabKey = new Context.Key<>(); 85 86 /** Get the symbol table instance. */ 87 public static Symtab instance(Context context) { 88 Symtab instance = context.get(symtabKey); 89 if (instance == null) 90 instance = new Symtab(context); 91 return instance; 92 } 93 94 /** Builtin types. 95 */ 96 public final JCPrimitiveType byteType = new JCPrimitiveType(BYTE, null); 97 public final JCPrimitiveType charType = new JCPrimitiveType(CHAR, null); 98 public final JCPrimitiveType shortType = new JCPrimitiveType(SHORT, null); 99 public final JCPrimitiveType intType = new JCPrimitiveType(INT, null); 100 public final JCPrimitiveType longType = new JCPrimitiveType(LONG, null); 101 public final JCPrimitiveType floatType = new JCPrimitiveType(FLOAT, null); 102 public final JCPrimitiveType doubleType = new JCPrimitiveType(DOUBLE, null); 103 public final JCPrimitiveType booleanType = new JCPrimitiveType(BOOLEAN, null); 104 public final Type botType = new BottomType(); 105 public final JCVoidType voidType = new JCVoidType(); 106 107 private final Names names; 108 private final JavacMessages messages; 109 private final Completer initialCompleter; 110 private final Completer moduleCompleter; 111 112 /** A symbol for the unnamed module. 113 */ 114 public final ModuleSymbol unnamedModule; 115 116 /** The error module. 117 */ 118 public final ModuleSymbol errModule; 119 120 /** A symbol for no module, for use with -source 8 or less 121 */ 122 public final ModuleSymbol noModule; 123 124 /** A symbol for the root package. 125 */ 126 public final PackageSymbol rootPackage; 127 128 /** A symbol that stands for a missing symbol. 129 */ 130 public final TypeSymbol noSymbol; 131 132 /** The error symbol. 133 */ 134 public final ClassSymbol errSymbol; 135 136 /** The unknown symbol. 137 */ 138 public final ClassSymbol unknownSymbol; 139 140 /** A value for the errType, with a originalType of noType */ 141 public final Type errType; 142 143 /** A value for the unknown type. */ 144 public final Type unknownType; 145 146 /** The builtin type of all arrays. */ 147 public final ClassSymbol arrayClass; 148 public final MethodSymbol arrayCloneMethod; 149 150 /** VGJ: The (singleton) type of all bound types. */ 151 public final ClassSymbol boundClass; 152 153 /** The builtin type of all methods. */ 154 public final ClassSymbol methodClass; 155 156 /** A symbol for the java.base module. 157 */ 158 public final ModuleSymbol java_base; 159 160 /** Predefined types. 161 */ 162 public final Type objectType; 163 public final Type objectsType; 164 public final Type classType; 165 public final Type classLoaderType; 166 public final Type stringType; 167 public final Type stringBufferType; 168 public final Type stringBuilderType; 169 public final Type cloneableType; 170 public final Type serializableType; 171 public final Type serializedLambdaType; 172 public final Type varHandleType; 173 public final Type methodHandleType; 174 public final Type methodHandleLookupType; 175 public final Type methodTypeType; 176 public final Type nativeHeaderType; 177 public final Type throwableType; 178 public final Type errorType; 179 public final Type interruptedExceptionType; 180 public final Type illegalArgumentExceptionType; 181 public final Type exceptionType; 182 public final Type runtimeExceptionType; 183 public final Type classNotFoundExceptionType; 184 public final Type noClassDefFoundErrorType; 185 public final Type noSuchFieldErrorType; 186 public final Type assertionErrorType; 187 public final Type cloneNotSupportedExceptionType; 188 public final Type annotationType; 189 public final TypeSymbol enumSym; 190 public final Type listType; 191 public final Type collectionsType; 192 public final Type comparableType; 193 public final Type comparatorType; 194 public final Type arraysType; 195 public final Type iterableType; 196 public final Type iteratorType; 197 public final Type annotationTargetType; 198 public final Type overrideType; 199 public final Type retentionType; 200 public final Type deprecatedType; 201 public final Type suppressWarningsType; 202 public final Type supplierType; 203 public final Type inheritedType; 204 public final Type profileType; 205 public final Type proprietaryType; 206 public final Type systemType; 207 public final Type autoCloseableType; 208 public final Type trustMeType; 209 public final Type lambdaMetafactory; 210 public final Type stringConcatFactory; 211 public final Type repeatableType; 212 public final Type documentedType; 213 public final Type elementTypeType; 214 public final Type functionalInterfaceType; 215 216 /** The symbol representing the length field of an array. 217 */ 218 public final VarSymbol lengthVar; 219 220 /** The symbol representing the final finalize method on enums */ 221 public final MethodSymbol enumFinalFinalize; 222 223 /** The symbol representing the close method on TWR AutoCloseable type */ 224 public final MethodSymbol autoCloseableClose; 225 226 /** The predefined type that belongs to a tag. 227 */ 228 public final Type[] typeOfTag = new Type[TypeTag.getTypeTagCount()]; 229 230 /** The name of the class that belongs to a basic type tag. 231 */ 232 public final Name[] boxedName = new Name[TypeTag.getTypeTagCount()]; 233 234 /** A hashtable containing the encountered top-level and member classes, 235 * indexed by flat names. The table does not contain local classes. 236 * It should be updated from the outside to reflect classes defined 237 * by compiled source files. 238 */ 239 private final Map<Name, Map<ModuleSymbol,ClassSymbol>> classes = new HashMap<>(); 240 241 /** A hashtable containing the encountered packages. 242 * the table should be updated from outside to reflect packages defined 243 * by compiled source files. 244 */ 245 private final Map<Name, Map<ModuleSymbol,PackageSymbol>> packages = new HashMap<>(); 246 247 /** A hashtable giving the encountered modules. 248 */ 249 private final Map<Name, ModuleSymbol> modules = new LinkedHashMap<>(); 250 251 private final Map<Types.UniqueType, VarSymbol> classFields = new HashMap<>(); 252 253 public VarSymbol getClassField(Type type, Types types) { 254 return classFields.computeIfAbsent( 255 new UniqueType(type, types), k -> { 256 Type arg = null; 257 if (type.getTag() == ARRAY || type.getTag() == CLASS) 258 arg = types.erasure(type); 259 else if (type.isPrimitiveOrVoid()) 260 arg = types.boxedClass(type).type; 261 else 262 throw new AssertionError(type); 263 264 Type t = new ClassType( 265 classType.getEnclosingType(), List.of(arg), classType.tsym); 266 return new VarSymbol( 267 STATIC | PUBLIC | FINAL, names._class, t, type.tsym); 268 }); 269 } 270 271 public void initType(Type type, ClassSymbol c) { 272 type.tsym = c; 273 typeOfTag[type.getTag().ordinal()] = type; 274 } 275 276 public void initType(Type type, String name) { 277 initType( 278 type, 279 new ClassSymbol( 280 PUBLIC, names.fromString(name), type, rootPackage)); 281 } 282 283 public void initType(Type type, String name, String bname) { 284 initType(type, name); 285 boxedName[type.getTag().ordinal()] = names.fromString("java.lang." + bname); 286 } 287 288 /** The class symbol that owns all predefined symbols. 289 */ 290 public final ClassSymbol predefClass; 291 292 /** Enter a class into symbol table. 293 * @param s The name of the class. 294 */ 295 private Type enterClass(String s) { 296 return enterClass(java_base, names.fromString(s)).type; 297 } 298 299 public void synthesizeEmptyInterfaceIfMissing(final Type type) { 300 final Completer completer = type.tsym.completer; 301 type.tsym.completer = new Completer() { 302 @Override 303 public void complete(Symbol sym) throws CompletionFailure { 304 try { 305 completer.complete(sym); 306 } catch (CompletionFailure e) { 307 sym.flags_field |= (PUBLIC | INTERFACE); 308 ((ClassType) sym.type).supertype_field = objectType; 309 } 310 } 311 312 @Override 313 public boolean isTerminal() { 314 return completer.isTerminal(); 315 } 316 }; 317 } 318 319 public void synthesizeBoxTypeIfMissing(final Type type) { 320 ClassSymbol sym = enterClass(java_base, boxedName[type.getTag().ordinal()]); 321 final Completer completer = sym.completer; 322 sym.completer = new Completer() { 323 @Override 324 public void complete(Symbol sym) throws CompletionFailure { 325 try { 326 completer.complete(sym); 327 } catch (CompletionFailure e) { 328 sym.flags_field |= PUBLIC; 329 ((ClassType) sym.type).supertype_field = objectType; 330 MethodSymbol boxMethod = 331 new MethodSymbol(PUBLIC | STATIC, names.valueOf, 332 new MethodType(List.of(type), sym.type, 333 List.nil(), methodClass), 334 sym); 335 sym.members().enter(boxMethod); 336 MethodSymbol unboxMethod = 337 new MethodSymbol(PUBLIC, 338 type.tsym.name.append(names.Value), // x.intValue() 339 new MethodType(List.nil(), type, 340 List.nil(), methodClass), 341 sym); 342 sym.members().enter(unboxMethod); 343 } 344 } 345 346 @Override 347 public boolean isTerminal() { 348 return completer.isTerminal(); 349 } 350 }; 351 } 352 353 // Enter a synthetic class that is used to mark classes in ct.sym. 354 // This class does not have a class file. 355 private Type enterSyntheticAnnotation(String name) { 356 // for now, leave the module null, to prevent problems from synthesizing the 357 // existence of a class in any specific module, including noModule 358 ClassType type = (ClassType)enterClass(java_base, names.fromString(name)).type; 359 ClassSymbol sym = (ClassSymbol)type.tsym; 360 sym.completer = Completer.NULL_COMPLETER; 361 sym.flags_field = PUBLIC|ACYCLIC|ANNOTATION|INTERFACE; 362 sym.erasure_field = type; 363 sym.members_field = WriteableScope.create(sym); 364 type.typarams_field = List.nil(); 365 type.allparams_field = List.nil(); 366 type.supertype_field = annotationType; 367 type.interfaces_field = List.nil(); 368 return type; 369 } 370 371 /** Constructor; enters all predefined identifiers and operators 372 * into symbol table. 373 */ 374 protected Symtab(Context context) throws CompletionFailure { 375 context.put(symtabKey, this); 376 377 names = Names.instance(context); 378 379 // Create the unknown type 380 unknownType = new UnknownType(); 381 382 messages = JavacMessages.instance(context); 383 384 rootPackage = new PackageSymbol(names.empty, null); 385 386 // create the basic builtin symbols 387 unnamedModule = new ModuleSymbol(names.empty, null) { 388 { 389 directives = List.nil(); 390 exports = List.nil(); 391 provides = List.nil(); 392 uses = List.nil(); 393 ModuleSymbol java_base = enterModule(names.java_base); 394 com.sun.tools.javac.code.Directive.RequiresDirective d = 395 new com.sun.tools.javac.code.Directive.RequiresDirective(java_base, 396 EnumSet.of(com.sun.tools.javac.code.Directive.RequiresFlag.MANDATED)); 397 requires = List.of(d); 398 } 399 @Override 400 public String toString() { 401 return messages.getLocalizedString("compiler.misc.unnamed.module"); 402 } 403 }; 404 addRootPackageFor(unnamedModule); 405 unnamedModule.enclosedPackages = unnamedModule.enclosedPackages.prepend(unnamedModule.unnamedPackage); 406 407 errModule = new ModuleSymbol(names.empty, null) { 408 { 409 directives = List.nil(); 410 exports = List.nil(); 411 provides = List.nil(); 412 uses = List.nil(); 413 ModuleSymbol java_base = enterModule(names.java_base); 414 com.sun.tools.javac.code.Directive.RequiresDirective d = 415 new com.sun.tools.javac.code.Directive.RequiresDirective(java_base, 416 EnumSet.of(com.sun.tools.javac.code.Directive.RequiresFlag.MANDATED)); 417 requires = List.of(d); 418 } 419 }; 420 addRootPackageFor(errModule); 421 422 noModule = new ModuleSymbol(names.empty, null) { 423 @Override public boolean isNoModule() { 424 return true; 425 } 426 }; 427 addRootPackageFor(noModule); 428 429 noSymbol = new TypeSymbol(NIL, 0, names.empty, Type.noType, rootPackage) { 430 @Override @DefinedBy(Api.LANGUAGE_MODEL) 431 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 432 return v.visitUnknown(this, p); 433 } 434 }; 435 436 // create the error symbols 437 errSymbol = new ClassSymbol(PUBLIC|STATIC|ACYCLIC, names.any, null, rootPackage); 438 errType = new ErrorType(errSymbol, Type.noType); 439 440 unknownSymbol = new ClassSymbol(PUBLIC|STATIC|ACYCLIC, names.fromString("<any?>"), null, rootPackage); 441 unknownSymbol.members_field = new Scope.ErrorScope(unknownSymbol); 442 unknownSymbol.type = unknownType; 443 444 // initialize builtin types 445 initType(byteType, "byte", "Byte"); 446 initType(shortType, "short", "Short"); 447 initType(charType, "char", "Character"); 448 initType(intType, "int", "Integer"); 449 initType(longType, "long", "Long"); 450 initType(floatType, "float", "Float"); 451 initType(doubleType, "double", "Double"); 452 initType(booleanType, "boolean", "Boolean"); 453 initType(voidType, "void", "Void"); 454 initType(botType, "<nulltype>"); 455 initType(errType, errSymbol); 456 initType(unknownType, unknownSymbol); 457 458 // the builtin class of all arrays 459 arrayClass = new ClassSymbol(PUBLIC|ACYCLIC, names.Array, noSymbol); 460 461 // VGJ 462 boundClass = new ClassSymbol(PUBLIC|ACYCLIC, names.Bound, noSymbol); 463 boundClass.members_field = new Scope.ErrorScope(boundClass); 464 465 // the builtin class of all methods 466 methodClass = new ClassSymbol(PUBLIC|ACYCLIC, names.Method, noSymbol); 467 methodClass.members_field = new Scope.ErrorScope(boundClass); 468 469 // Create class to hold all predefined constants and operations. 470 predefClass = new ClassSymbol(PUBLIC|ACYCLIC, names.empty, rootPackage); 471 WriteableScope scope = WriteableScope.create(predefClass); 472 predefClass.members_field = scope; 473 474 // Get the initial completer for Symbols from the ClassFinder 475 initialCompleter = ClassFinder.instance(context).getCompleter(); 476 rootPackage.members_field = WriteableScope.create(rootPackage); 477 478 // Enter symbols for basic types. 479 scope.enter(byteType.tsym); 480 scope.enter(shortType.tsym); 481 scope.enter(charType.tsym); 482 scope.enter(intType.tsym); 483 scope.enter(longType.tsym); 484 scope.enter(floatType.tsym); 485 scope.enter(doubleType.tsym); 486 scope.enter(booleanType.tsym); 487 scope.enter(errType.tsym); 488 489 // Enter symbol for the errSymbol 490 scope.enter(errSymbol); 491 492 Source source = Source.instance(context); 493 if (Feature.MODULES.allowedInSource(source)) { 494 java_base = enterModule(names.java_base); 495 //avoid completing java.base during the Symtab initialization 496 java_base.completer = Completer.NULL_COMPLETER; 497 java_base.visiblePackages = Collections.emptyMap(); 498 } else { 499 java_base = noModule; 500 } 501 502 // Get the initial completer for ModuleSymbols from Modules 503 moduleCompleter = Modules.instance(context).getCompleter(); 504 505 // Enter predefined classes. All are assumed to be in the java.base module. 506 objectType = enterClass("java.lang.Object"); 507 objectsType = enterClass("java.util.Objects"); 508 classType = enterClass("java.lang.Class"); 509 stringType = enterClass("java.lang.String"); 510 stringBufferType = enterClass("java.lang.StringBuffer"); 511 stringBuilderType = enterClass("java.lang.StringBuilder"); 512 cloneableType = enterClass("java.lang.Cloneable"); 513 throwableType = enterClass("java.lang.Throwable"); 514 serializableType = enterClass("java.io.Serializable"); 515 serializedLambdaType = enterClass("java.lang.invoke.SerializedLambda"); 516 varHandleType = enterClass("java.lang.invoke.VarHandle"); 517 methodHandleType = enterClass("java.lang.invoke.MethodHandle"); 518 methodHandleLookupType = enterClass("java.lang.invoke.MethodHandles$Lookup"); 519 methodTypeType = enterClass("java.lang.invoke.MethodType"); 520 errorType = enterClass("java.lang.Error"); 521 illegalArgumentExceptionType = enterClass("java.lang.IllegalArgumentException"); 522 interruptedExceptionType = enterClass("java.lang.InterruptedException"); 523 exceptionType = enterClass("java.lang.Exception"); 524 runtimeExceptionType = enterClass("java.lang.RuntimeException"); 525 classNotFoundExceptionType = enterClass("java.lang.ClassNotFoundException"); 526 noClassDefFoundErrorType = enterClass("java.lang.NoClassDefFoundError"); 527 noSuchFieldErrorType = enterClass("java.lang.NoSuchFieldError"); 528 assertionErrorType = enterClass("java.lang.AssertionError"); 529 cloneNotSupportedExceptionType = enterClass("java.lang.CloneNotSupportedException"); 530 annotationType = enterClass("java.lang.annotation.Annotation"); 531 classLoaderType = enterClass("java.lang.ClassLoader"); 532 enumSym = enterClass(java_base, names.java_lang_Enum); 533 enumFinalFinalize = 534 new MethodSymbol(PROTECTED|FINAL|HYPOTHETICAL, 535 names.finalize, 536 new MethodType(List.nil(), voidType, 537 List.nil(), methodClass), 538 enumSym); 539 listType = enterClass("java.util.List"); 540 collectionsType = enterClass("java.util.Collections"); 541 comparableType = enterClass("java.lang.Comparable"); 542 comparatorType = enterClass("java.util.Comparator"); 543 arraysType = enterClass("java.util.Arrays"); 544 iterableType = enterClass("java.lang.Iterable"); 545 iteratorType = enterClass("java.util.Iterator"); 546 annotationTargetType = enterClass("java.lang.annotation.Target"); 547 overrideType = enterClass("java.lang.Override"); 548 retentionType = enterClass("java.lang.annotation.Retention"); 549 deprecatedType = enterClass("java.lang.Deprecated"); 550 suppressWarningsType = enterClass("java.lang.SuppressWarnings"); 551 supplierType = enterClass("java.util.function.Supplier"); 552 inheritedType = enterClass("java.lang.annotation.Inherited"); 553 repeatableType = enterClass("java.lang.annotation.Repeatable"); 554 documentedType = enterClass("java.lang.annotation.Documented"); 555 elementTypeType = enterClass("java.lang.annotation.ElementType"); 556 systemType = enterClass("java.lang.System"); 557 autoCloseableType = enterClass("java.lang.AutoCloseable"); 558 autoCloseableClose = new MethodSymbol(PUBLIC, 559 names.close, 560 new MethodType(List.nil(), voidType, 561 List.of(exceptionType), methodClass), 562 autoCloseableType.tsym); 563 trustMeType = enterClass("java.lang.SafeVarargs"); 564 nativeHeaderType = enterClass("java.lang.annotation.Native"); 565 lambdaMetafactory = enterClass("java.lang.invoke.LambdaMetafactory"); 566 stringConcatFactory = enterClass("java.lang.invoke.StringConcatFactory"); 567 functionalInterfaceType = enterClass("java.lang.FunctionalInterface"); 568 569 synthesizeEmptyInterfaceIfMissing(autoCloseableType); 570 synthesizeEmptyInterfaceIfMissing(cloneableType); 571 synthesizeEmptyInterfaceIfMissing(serializableType); 572 synthesizeEmptyInterfaceIfMissing(lambdaMetafactory); 573 synthesizeEmptyInterfaceIfMissing(serializedLambdaType); 574 synthesizeEmptyInterfaceIfMissing(stringConcatFactory); 575 synthesizeBoxTypeIfMissing(doubleType); 576 synthesizeBoxTypeIfMissing(floatType); 577 synthesizeBoxTypeIfMissing(voidType); 578 579 // Enter a synthetic class that is used to mark internal 580 // proprietary classes in ct.sym. This class does not have a 581 // class file. 582 proprietaryType = enterSyntheticAnnotation("sun.Proprietary+Annotation"); 583 584 // Enter a synthetic class that is used to provide profile info for 585 // classes in ct.sym. This class does not have a class file. 586 profileType = enterSyntheticAnnotation("jdk.Profile+Annotation"); 587 MethodSymbol m = new MethodSymbol(PUBLIC | ABSTRACT, names.value, intType, profileType.tsym); 588 profileType.tsym.members().enter(m); 589 590 // Enter a class for arrays. 591 // The class implements java.lang.Cloneable and java.io.Serializable. 592 // It has a final length field and a clone method. 593 ClassType arrayClassType = (ClassType)arrayClass.type; 594 arrayClassType.supertype_field = objectType; 595 arrayClassType.interfaces_field = List.of(cloneableType, serializableType); 596 arrayClass.members_field = WriteableScope.create(arrayClass); 597 lengthVar = new VarSymbol( 598 PUBLIC | FINAL, 599 names.length, 600 intType, 601 arrayClass); 602 arrayClass.members().enter(lengthVar); 603 arrayCloneMethod = new MethodSymbol( 604 PUBLIC, 605 names.clone, 606 new MethodType(List.nil(), objectType, 607 List.nil(), methodClass), 608 arrayClass); 609 arrayClass.members().enter(arrayCloneMethod); 610 611 if (java_base != noModule) 612 java_base.completer = moduleCompleter::complete; //bootstrap issues 613 614 } 615 616 /** Define a new class given its name and owner. 617 */ 618 public ClassSymbol defineClass(Name name, Symbol owner) { 619 ClassSymbol c = new ClassSymbol(0, name, owner); 620 c.completer = initialCompleter; 621 return c; 622 } 623 624 /** Create a new toplevel or member class symbol with given name 625 * and owner and enter in `classes' unless already there. 626 */ 627 public ClassSymbol enterClass(ModuleSymbol msym, Name name, TypeSymbol owner) { 628 Assert.checkNonNull(msym); 629 Name flatname = TypeSymbol.formFlatName(name, owner); 630 ClassSymbol c = getClass(msym, flatname); 631 if (c == null) { 632 c = defineClass(name, owner); 633 doEnterClass(msym, c); 634 } else if ((c.name != name || c.owner != owner) && owner.kind == TYP && c.owner.kind == PCK) { 635 // reassign fields of classes that might have been loaded with 636 // their flat names. 637 c.owner.members().remove(c); 638 c.name = name; 639 c.owner = owner; 640 c.fullname = ClassSymbol.formFullName(name, owner); 641 } 642 return c; 643 } 644 645 public ClassSymbol getClass(ModuleSymbol msym, Name flatName) { 646 Assert.checkNonNull(msym, flatName::toString); 647 return classes.getOrDefault(flatName, Collections.emptyMap()).get(msym); 648 } 649 650 public PackageSymbol lookupPackage(ModuleSymbol msym, Name flatName) { 651 Assert.checkNonNull(msym); 652 653 if (flatName.isEmpty()) { 654 //unnamed packages only from the current module - visiblePackages contains *root* package, not unnamed package! 655 return msym.unnamedPackage; 656 } 657 658 if (msym == noModule) { 659 return enterPackage(msym, flatName); 660 } 661 662 msym.complete(); 663 664 PackageSymbol pack; 665 666 pack = msym.visiblePackages.get(flatName); 667 668 if (pack != null) 669 return pack; 670 671 pack = getPackage(msym, flatName); 672 673 if (pack != null && pack.exists()) 674 return pack; 675 676 boolean dependsOnUnnamed = msym.requires != null && 677 msym.requires.stream() 678 .map(rd -> rd.module) 679 .anyMatch(mod -> mod == unnamedModule); 680 681 if (dependsOnUnnamed) { 682 //msyms depends on the unnamed module, for which we generally don't know 683 //the list of packages it "exports" ahead of time. So try to lookup the package in the 684 //current module, and in the unnamed module and see if it exists in one of them 685 PackageSymbol unnamedPack = getPackage(unnamedModule, flatName); 686 687 if (unnamedPack != null && unnamedPack.exists()) { 688 msym.visiblePackages.put(unnamedPack.fullname, unnamedPack); 689 return unnamedPack; 690 } 691 692 pack = enterPackage(msym, flatName); 693 pack.complete(); 694 if (pack.exists()) 695 return pack; 696 697 unnamedPack = enterPackage(unnamedModule, flatName); 698 unnamedPack.complete(); 699 if (unnamedPack.exists()) { 700 msym.visiblePackages.put(unnamedPack.fullname, unnamedPack); 701 return unnamedPack; 702 } 703 704 return pack; 705 } 706 707 return enterPackage(msym, flatName); 708 } 709 710 private static final Map<ModuleSymbol, ClassSymbol> EMPTY = new HashMap<>(); 711 712 public void removeClass(ModuleSymbol msym, Name flatName) { 713 classes.getOrDefault(flatName, EMPTY).remove(msym); 714 } 715 716 public Iterable<ClassSymbol> getAllClasses() { 717 return () -> Iterators.createCompoundIterator(classes.values(), v -> v.values().iterator()); 718 } 719 720 private void doEnterClass(ModuleSymbol msym, ClassSymbol cs) { 721 classes.computeIfAbsent(cs.flatname, n -> new HashMap<>()).put(msym, cs); 722 } 723 724 /** Create a new member or toplevel class symbol with given flat name 725 * and enter in `classes' unless already there. 726 */ 727 public ClassSymbol enterClass(ModuleSymbol msym, Name flatname) { 728 Assert.checkNonNull(msym); 729 PackageSymbol ps = lookupPackage(msym, Convert.packagePart(flatname)); 730 Assert.checkNonNull(ps); 731 Assert.checkNonNull(ps.modle); 732 ClassSymbol c = getClass(ps.modle, flatname); 733 if (c == null) { 734 c = defineClass(Convert.shortName(flatname), ps); 735 doEnterClass(ps.modle, c); 736 return c; 737 } else 738 return c; 739 } 740 741 /** Check to see if a package exists, given its fully qualified name. 742 */ 743 public boolean packageExists(ModuleSymbol msym, Name fullname) { 744 Assert.checkNonNull(msym); 745 return lookupPackage(msym, fullname).exists(); 746 } 747 748 /** Make a package, given its fully qualified name. 749 */ 750 public PackageSymbol enterPackage(ModuleSymbol currModule, Name fullname) { 751 Assert.checkNonNull(currModule); 752 PackageSymbol p = getPackage(currModule, fullname); 753 if (p == null) { 754 Assert.check(!fullname.isEmpty(), () -> "rootPackage missing!; currModule: " + currModule); 755 p = new PackageSymbol( 756 Convert.shortName(fullname), 757 enterPackage(currModule, Convert.packagePart(fullname))); 758 p.completer = initialCompleter; 759 p.modle = currModule; 760 doEnterPackage(currModule, p); 761 } 762 return p; 763 } 764 765 private void doEnterPackage(ModuleSymbol msym, PackageSymbol pack) { 766 packages.computeIfAbsent(pack.fullname, n -> new HashMap<>()).put(msym, pack); 767 msym.enclosedPackages = msym.enclosedPackages.prepend(pack); 768 } 769 770 private void addRootPackageFor(ModuleSymbol module) { 771 doEnterPackage(module, rootPackage); 772 PackageSymbol unnamedPackage = new PackageSymbol(names.empty, rootPackage) { 773 @Override 774 public String toString() { 775 return messages.getLocalizedString("compiler.misc.unnamed.package"); 776 } 777 }; 778 unnamedPackage.modle = module; 779 //we cannot use a method reference below, as initialCompleter might be null now 780 unnamedPackage.completer = s -> initialCompleter.complete(s); 781 module.unnamedPackage = unnamedPackage; 782 } 783 784 public PackageSymbol getPackage(ModuleSymbol module, Name fullname) { 785 return packages.getOrDefault(fullname, Collections.emptyMap()).get(module); 786 } 787 788 public ModuleSymbol enterModule(Name name) { 789 ModuleSymbol msym = modules.get(name); 790 if (msym == null) { 791 msym = ModuleSymbol.create(name, names.module_info); 792 addRootPackageFor(msym); 793 msym.completer = s -> moduleCompleter.complete(s); //bootstrap issues 794 modules.put(name, msym); 795 } 796 return msym; 797 } 798 799 public ModuleSymbol getModule(Name name) { 800 return modules.get(name); 801 } 802 803 //temporary: 804 public ModuleSymbol inferModule(Name packageName) { 805 if (packageName.isEmpty()) 806 return java_base == noModule ? noModule : unnamedModule;//! 807 808 ModuleSymbol msym = null; 809 Map<ModuleSymbol,PackageSymbol> map = packages.get(packageName); 810 if (map == null) 811 return null; 812 for (Map.Entry<ModuleSymbol,PackageSymbol> e: map.entrySet()) { 813 if (!e.getValue().members().isEmpty()) { 814 if (msym == null) { 815 msym = e.getKey(); 816 } else { 817 return null; 818 } 819 } 820 } 821 return msym; 822 } 823 824 public List<ModuleSymbol> listPackageModules(Name packageName) { 825 if (packageName.isEmpty()) 826 return List.nil(); 827 828 List<ModuleSymbol> result = List.nil(); 829 Map<ModuleSymbol,PackageSymbol> map = packages.get(packageName); 830 if (map != null) { 831 for (Map.Entry<ModuleSymbol, PackageSymbol> e: map.entrySet()) { 832 if (!e.getValue().members().isEmpty()) { 833 result = result.prepend(e.getKey()); 834 } 835 } 836 } 837 return result; 838 } 839 840 public Collection<ModuleSymbol> getAllModules() { 841 return modules.values(); 842 } 843 844 public Iterable<ClassSymbol> getClassesForName(Name candidate) { 845 return classes.getOrDefault(candidate, Collections.emptyMap()).values(); 846 } 847 848 public Iterable<PackageSymbol> getPackagesForName(Name candidate) { 849 return packages.getOrDefault(candidate, Collections.emptyMap()).values(); 850 } 851 }