Symtab.java revision 2673:bf8500822576
1/* 2 * Copyright (c) 1999, 2014, 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 26package com.sun.tools.javac.code; 27 28import java.util.HashMap; 29import java.util.HashSet; 30import java.util.Map; 31import java.util.Set; 32 33import javax.lang.model.element.ElementVisitor; 34import javax.tools.JavaFileObject; 35 36 37import com.sun.tools.javac.code.Scope.WriteableScope; 38import com.sun.tools.javac.code.Symbol.ClassSymbol; 39import com.sun.tools.javac.code.Symbol.Completer; 40import com.sun.tools.javac.code.Symbol.CompletionFailure; 41import com.sun.tools.javac.code.Symbol.MethodSymbol; 42import com.sun.tools.javac.code.Symbol.OperatorSymbol; 43import com.sun.tools.javac.code.Symbol.PackageSymbol; 44import com.sun.tools.javac.code.Symbol.TypeSymbol; 45import com.sun.tools.javac.code.Symbol.VarSymbol; 46import com.sun.tools.javac.code.Type.BottomType; 47import com.sun.tools.javac.code.Type.ClassType; 48import com.sun.tools.javac.code.Type.ErrorType; 49import com.sun.tools.javac.code.Type.JCPrimitiveType; 50import com.sun.tools.javac.code.Type.JCVoidType; 51import com.sun.tools.javac.code.Type.MethodType; 52import com.sun.tools.javac.code.Type.UnknownType; 53import com.sun.tools.javac.jvm.ByteCodes; 54import com.sun.tools.javac.jvm.Target; 55import com.sun.tools.javac.util.Assert; 56import com.sun.tools.javac.util.Context; 57import com.sun.tools.javac.util.Convert; 58import com.sun.tools.javac.util.DefinedBy; 59import com.sun.tools.javac.util.DefinedBy.Api; 60import com.sun.tools.javac.util.JavacMessages; 61import com.sun.tools.javac.util.List; 62import com.sun.tools.javac.util.Log; 63import com.sun.tools.javac.util.Name; 64import com.sun.tools.javac.util.Names; 65 66import static com.sun.tools.javac.code.Flags.*; 67import static com.sun.tools.javac.code.Kinds.Kind.*; 68import static com.sun.tools.javac.jvm.ByteCodes.*; 69import 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 */ 82public 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 Completer initialCompleter; 109 private final Target target; 110 111 /** A symbol for the root package. 112 */ 113 public final PackageSymbol rootPackage; 114 115 /** A symbol for the unnamed package. 116 */ 117 public final PackageSymbol unnamedPackage; 118 119 /** A symbol that stands for a missing symbol. 120 */ 121 public final TypeSymbol noSymbol; 122 123 /** The error symbol. 124 */ 125 public final ClassSymbol errSymbol; 126 127 /** The unknown symbol. 128 */ 129 public final ClassSymbol unknownSymbol; 130 131 /** A value for the errType, with a originalType of noType */ 132 public final Type errType; 133 134 /** A value for the unknown type. */ 135 public final Type unknownType; 136 137 /** The builtin type of all arrays. */ 138 public final ClassSymbol arrayClass; 139 public final MethodSymbol arrayCloneMethod; 140 141 /** VGJ: The (singleton) type of all bound types. */ 142 public final ClassSymbol boundClass; 143 144 /** The builtin type of all methods. */ 145 public final ClassSymbol methodClass; 146 147 /** Predefined types. 148 */ 149 public final Type objectType; 150 public final Type classType; 151 public final Type classLoaderType; 152 public final Type stringType; 153 public final Type stringBufferType; 154 public final Type stringBuilderType; 155 public final Type cloneableType; 156 public final Type serializableType; 157 public final Type serializedLambdaType; 158 public final Type methodHandleType; 159 public final Type methodHandleLookupType; 160 public final Type methodTypeType; 161 public final Type nativeHeaderType; 162 public final Type throwableType; 163 public final Type errorType; 164 public final Type interruptedExceptionType; 165 public final Type illegalArgumentExceptionType; 166 public final Type exceptionType; 167 public final Type runtimeExceptionType; 168 public final Type classNotFoundExceptionType; 169 public final Type noClassDefFoundErrorType; 170 public final Type noSuchFieldErrorType; 171 public final Type assertionErrorType; 172 public final Type cloneNotSupportedExceptionType; 173 public final Type annotationType; 174 public final TypeSymbol enumSym; 175 public final Type listType; 176 public final Type collectionsType; 177 public final Type comparableType; 178 public final Type comparatorType; 179 public final Type arraysType; 180 public final Type iterableType; 181 public final Type iteratorType; 182 public final Type annotationTargetType; 183 public final Type overrideType; 184 public final Type retentionType; 185 public final Type deprecatedType; 186 public final Type suppressWarningsType; 187 public final Type inheritedType; 188 public final Type profileType; 189 public final Type proprietaryType; 190 public final Type systemType; 191 public final Type autoCloseableType; 192 public final Type trustMeType; 193 public final Type lambdaMetafactory; 194 public final Type repeatableType; 195 public final Type documentedType; 196 public final Type elementTypeType; 197 public final Type functionalInterfaceType; 198 199 /** The symbol representing the length field of an array. 200 */ 201 public final VarSymbol lengthVar; 202 203 /** The null check operator. */ 204 public final OperatorSymbol nullcheck; 205 206 /** The symbol representing the final finalize method on enums */ 207 public final MethodSymbol enumFinalFinalize; 208 209 /** The symbol representing the close method on TWR AutoCloseable type */ 210 public final MethodSymbol autoCloseableClose; 211 212 /** The predefined type that belongs to a tag. 213 */ 214 public final Type[] typeOfTag = new Type[TypeTag.getTypeTagCount()]; 215 216 /** The name of the class that belongs to a basix type tag. 217 */ 218 public final Name[] boxedName = new Name[TypeTag.getTypeTagCount()]; 219 220 /** A set containing all operator names. 221 */ 222 public final Set<Name> operatorNames = new HashSet<>(); 223 224 /** A hashtable containing the encountered top-level and member classes, 225 * indexed by flat names. The table does not contain local classes. 226 * It should be updated from the outside to reflect classes defined 227 * by compiled source files. 228 */ 229 public final Map<Name, ClassSymbol> classes = new HashMap<>(); 230 231 /** A hashtable containing the encountered packages. 232 * the table should be updated from outside to reflect packages defined 233 * by compiled source files. 234 */ 235 public final Map<Name, PackageSymbol> packages = new HashMap<>(); 236 237 public void initType(Type type, ClassSymbol c) { 238 type.tsym = c; 239 typeOfTag[type.getTag().ordinal()] = type; 240 } 241 242 public void initType(Type type, String name) { 243 initType( 244 type, 245 new ClassSymbol( 246 PUBLIC, names.fromString(name), type, rootPackage)); 247 } 248 249 public void initType(Type type, String name, String bname) { 250 initType(type, name); 251 boxedName[type.getTag().ordinal()] = names.fromString("java.lang." + bname); 252 } 253 254 /** The class symbol that owns all predefined symbols. 255 */ 256 public final ClassSymbol predefClass; 257 258 /** Enter a constant into symbol table. 259 * @param name The constant's name. 260 * @param type The constant's type. 261 */ 262 private VarSymbol enterConstant(String name, Type type) { 263 VarSymbol c = new VarSymbol( 264 PUBLIC | STATIC | FINAL, 265 names.fromString(name), 266 type, 267 predefClass); 268 c.setData(type.constValue()); 269 predefClass.members().enter(c); 270 return c; 271 } 272 273 /** Enter a binary operation into symbol table. 274 * @param name The name of the operator. 275 * @param left The type of the left operand. 276 * @param right The type of the left operand. 277 * @param res The operation's result type. 278 * @param opcode The operation's bytecode instruction. 279 */ 280 private void enterBinop(String name, 281 Type left, Type right, Type res, 282 int opcode) { 283 predefClass.members().enter( 284 new OperatorSymbol( 285 makeOperatorName(name), 286 new MethodType(List.of(left, right), res, 287 List.<Type>nil(), methodClass), 288 opcode, 289 predefClass)); 290 } 291 292 /** Enter a binary operation, as above but with two opcodes, 293 * which get encoded as 294 * {@code (opcode1 << ByteCodeTags.preShift) + opcode2 }. 295 * @param opcode1 First opcode. 296 * @param opcode2 Second opcode. 297 */ 298 private void enterBinop(String name, 299 Type left, Type right, Type res, 300 int opcode1, int opcode2) { 301 enterBinop( 302 name, left, right, res, (opcode1 << ByteCodes.preShift) | opcode2); 303 } 304 305 /** Enter a unary operation into symbol table. 306 * @param name The name of the operator. 307 * @param arg The type of the operand. 308 * @param res The operation's result type. 309 * @param opcode The operation's bytecode instruction. 310 */ 311 private OperatorSymbol enterUnop(String name, 312 Type arg, 313 Type res, 314 int opcode) { 315 OperatorSymbol sym = 316 new OperatorSymbol(makeOperatorName(name), 317 new MethodType(List.of(arg), 318 res, 319 List.<Type>nil(), 320 methodClass), 321 opcode, 322 predefClass); 323 predefClass.members().enter(sym); 324 return sym; 325 } 326 327 /** 328 * Create a new operator name from corresponding String representation 329 * and add the name to the set of known operator names. 330 */ 331 private Name makeOperatorName(String name) { 332 Name opName = names.fromString(name); 333 operatorNames.add(opName); 334 return opName; 335 } 336 337 /** Enter a class into symbol table. 338 * @param s The name of the class. 339 */ 340 private Type enterClass(String s) { 341 return enterClass(names.fromString(s)).type; 342 } 343 344 public void synthesizeEmptyInterfaceIfMissing(final Type type) { 345 final Completer completer = type.tsym.completer; 346 if (completer != null) { 347 type.tsym.completer = new Completer() { 348 public void complete(Symbol sym) throws CompletionFailure { 349 try { 350 completer.complete(sym); 351 } catch (CompletionFailure e) { 352 sym.flags_field |= (PUBLIC | INTERFACE); 353 ((ClassType) sym.type).supertype_field = objectType; 354 } 355 } 356 }; 357 } 358 } 359 360 public void synthesizeBoxTypeIfMissing(final Type type) { 361 ClassSymbol sym = enterClass(boxedName[type.getTag().ordinal()]); 362 final Completer completer = sym.completer; 363 if (completer != null) { 364 sym.completer = new Completer() { 365 public void complete(Symbol sym) throws CompletionFailure { 366 try { 367 completer.complete(sym); 368 } catch (CompletionFailure e) { 369 sym.flags_field |= PUBLIC; 370 ((ClassType) sym.type).supertype_field = objectType; 371 MethodSymbol boxMethod = 372 new MethodSymbol(PUBLIC | STATIC, names.valueOf, 373 new MethodType(List.of(type), sym.type, 374 List.<Type>nil(), methodClass), 375 sym); 376 sym.members().enter(boxMethod); 377 MethodSymbol unboxMethod = 378 new MethodSymbol(PUBLIC, 379 type.tsym.name.append(names.Value), // x.intValue() 380 new MethodType(List.<Type>nil(), type, 381 List.<Type>nil(), methodClass), 382 sym); 383 sym.members().enter(unboxMethod); 384 } 385 } 386 }; 387 } 388 389 } 390 391 // Enter a synthetic class that is used to mark classes in ct.sym. 392 // This class does not have a class file. 393 private Type enterSyntheticAnnotation(String name) { 394 ClassType type = (ClassType)enterClass(name); 395 ClassSymbol sym = (ClassSymbol)type.tsym; 396 sym.completer = null; 397 sym.flags_field = PUBLIC|ACYCLIC|ANNOTATION|INTERFACE; 398 sym.erasure_field = type; 399 sym.members_field = WriteableScope.create(sym); 400 type.typarams_field = List.nil(); 401 type.allparams_field = List.nil(); 402 type.supertype_field = annotationType; 403 type.interfaces_field = List.nil(); 404 return type; 405 } 406 407 /** Constructor; enters all predefined identifiers and operators 408 * into symbol table. 409 */ 410 protected Symtab(Context context) throws CompletionFailure { 411 context.put(symtabKey, this); 412 413 names = Names.instance(context); 414 target = Target.instance(context); 415 416 // Create the unknown type 417 unknownType = new UnknownType(); 418 419 // create the basic builtin symbols 420 rootPackage = new PackageSymbol(names.empty, null); 421 packages.put(names.empty, rootPackage); 422 final JavacMessages messages = JavacMessages.instance(context); 423 unnamedPackage = new PackageSymbol(names.empty, rootPackage) { 424 public String toString() { 425 return messages.getLocalizedString("compiler.misc.unnamed.package"); 426 } 427 }; 428 noSymbol = new TypeSymbol(NIL, 0, names.empty, Type.noType, rootPackage) { 429 @DefinedBy(Api.LANGUAGE_MODEL) 430 public <R, P> R accept(ElementVisitor<R, P> v, P p) { 431 return v.visitUnknown(this, p); 432 } 433 }; 434 435 // create the error symbols 436 errSymbol = new ClassSymbol(PUBLIC|STATIC|ACYCLIC, names.any, null, rootPackage); 437 errType = new ErrorType(errSymbol, Type.noType); 438 439 unknownSymbol = new ClassSymbol(PUBLIC|STATIC|ACYCLIC, names.fromString("<any?>"), null, rootPackage); 440 unknownSymbol.members_field = new Scope.ErrorScope(unknownSymbol); 441 unknownSymbol.type = unknownType; 442 443 // initialize builtin types 444 initType(byteType, "byte", "Byte"); 445 initType(shortType, "short", "Short"); 446 initType(charType, "char", "Character"); 447 initType(intType, "int", "Integer"); 448 initType(longType, "long", "Long"); 449 initType(floatType, "float", "Float"); 450 initType(doubleType, "double", "Double"); 451 initType(booleanType, "boolean", "Boolean"); 452 initType(voidType, "void", "Void"); 453 initType(botType, "<nulltype>"); 454 initType(errType, errSymbol); 455 initType(unknownType, unknownSymbol); 456 457 // the builtin class of all arrays 458 arrayClass = new ClassSymbol(PUBLIC|ACYCLIC, names.Array, noSymbol); 459 460 // VGJ 461 boundClass = new ClassSymbol(PUBLIC|ACYCLIC, names.Bound, noSymbol); 462 boundClass.members_field = new Scope.ErrorScope(boundClass); 463 464 // the builtin class of all methods 465 methodClass = new ClassSymbol(PUBLIC|ACYCLIC, names.Method, noSymbol); 466 methodClass.members_field = new Scope.ErrorScope(boundClass); 467 468 // Create class to hold all predefined constants and operations. 469 predefClass = new ClassSymbol(PUBLIC|ACYCLIC, names.empty, rootPackage); 470 WriteableScope scope = WriteableScope.create(predefClass); 471 predefClass.members_field = scope; 472 473 // Get the initial completer for Symbols from the ClassFinder 474 initialCompleter = ClassFinder.instance(context).getCompleter(); 475 rootPackage.completer = initialCompleter; 476 unnamedPackage.completer = initialCompleter; 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 classes.put(predefClass.fullname, predefClass); 493 494 // Enter predefined classes. 495 objectType = enterClass("java.lang.Object"); 496 classType = enterClass("java.lang.Class"); 497 stringType = enterClass("java.lang.String"); 498 stringBufferType = enterClass("java.lang.StringBuffer"); 499 stringBuilderType = enterClass("java.lang.StringBuilder"); 500 cloneableType = enterClass("java.lang.Cloneable"); 501 throwableType = enterClass("java.lang.Throwable"); 502 serializableType = enterClass("java.io.Serializable"); 503 serializedLambdaType = enterClass("java.lang.invoke.SerializedLambda"); 504 methodHandleType = enterClass("java.lang.invoke.MethodHandle"); 505 methodHandleLookupType = enterClass("java.lang.invoke.MethodHandles$Lookup"); 506 methodTypeType = enterClass("java.lang.invoke.MethodType"); 507 errorType = enterClass("java.lang.Error"); 508 illegalArgumentExceptionType = enterClass("java.lang.IllegalArgumentException"); 509 interruptedExceptionType = enterClass("java.lang.InterruptedException"); 510 exceptionType = enterClass("java.lang.Exception"); 511 runtimeExceptionType = enterClass("java.lang.RuntimeException"); 512 classNotFoundExceptionType = enterClass("java.lang.ClassNotFoundException"); 513 noClassDefFoundErrorType = enterClass("java.lang.NoClassDefFoundError"); 514 noSuchFieldErrorType = enterClass("java.lang.NoSuchFieldError"); 515 assertionErrorType = enterClass("java.lang.AssertionError"); 516 cloneNotSupportedExceptionType = enterClass("java.lang.CloneNotSupportedException"); 517 annotationType = enterClass("java.lang.annotation.Annotation"); 518 classLoaderType = enterClass("java.lang.ClassLoader"); 519 enumSym = enterClass(names.java_lang_Enum); 520 enumFinalFinalize = 521 new MethodSymbol(PROTECTED|FINAL|HYPOTHETICAL, 522 names.finalize, 523 new MethodType(List.<Type>nil(), voidType, 524 List.<Type>nil(), methodClass), 525 enumSym); 526 listType = enterClass("java.util.List"); 527 collectionsType = enterClass("java.util.Collections"); 528 comparableType = enterClass("java.lang.Comparable"); 529 comparatorType = enterClass("java.util.Comparator"); 530 arraysType = enterClass("java.util.Arrays"); 531 iterableType = enterClass("java.lang.Iterable"); 532 iteratorType = enterClass("java.util.Iterator"); 533 annotationTargetType = enterClass("java.lang.annotation.Target"); 534 overrideType = enterClass("java.lang.Override"); 535 retentionType = enterClass("java.lang.annotation.Retention"); 536 deprecatedType = enterClass("java.lang.Deprecated"); 537 suppressWarningsType = enterClass("java.lang.SuppressWarnings"); 538 inheritedType = enterClass("java.lang.annotation.Inherited"); 539 repeatableType = enterClass("java.lang.annotation.Repeatable"); 540 documentedType = enterClass("java.lang.annotation.Documented"); 541 elementTypeType = enterClass("java.lang.annotation.ElementType"); 542 systemType = enterClass("java.lang.System"); 543 autoCloseableType = enterClass("java.lang.AutoCloseable"); 544 autoCloseableClose = new MethodSymbol(PUBLIC, 545 names.close, 546 new MethodType(List.<Type>nil(), voidType, 547 List.of(exceptionType), methodClass), 548 autoCloseableType.tsym); 549 trustMeType = enterClass("java.lang.SafeVarargs"); 550 nativeHeaderType = enterClass("java.lang.annotation.Native"); 551 lambdaMetafactory = enterClass("java.lang.invoke.LambdaMetafactory"); 552 functionalInterfaceType = enterClass("java.lang.FunctionalInterface"); 553 554 synthesizeEmptyInterfaceIfMissing(autoCloseableType); 555 synthesizeEmptyInterfaceIfMissing(cloneableType); 556 synthesizeEmptyInterfaceIfMissing(serializableType); 557 synthesizeEmptyInterfaceIfMissing(lambdaMetafactory); 558 synthesizeEmptyInterfaceIfMissing(serializedLambdaType); 559 synthesizeBoxTypeIfMissing(doubleType); 560 synthesizeBoxTypeIfMissing(floatType); 561 synthesizeBoxTypeIfMissing(voidType); 562 563 // Enter a synthetic class that is used to mark internal 564 // proprietary classes in ct.sym. This class does not have a 565 // class file. 566 proprietaryType = enterSyntheticAnnotation("sun.Proprietary+Annotation"); 567 568 // Enter a synthetic class that is used to provide profile info for 569 // classes in ct.sym. This class does not have a class file. 570 profileType = enterSyntheticAnnotation("jdk.Profile+Annotation"); 571 MethodSymbol m = new MethodSymbol(PUBLIC | ABSTRACT, names.value, intType, profileType.tsym); 572 profileType.tsym.members().enter(m); 573 574 // Enter a class for arrays. 575 // The class implements java.lang.Cloneable and java.io.Serializable. 576 // It has a final length field and a clone method. 577 ClassType arrayClassType = (ClassType)arrayClass.type; 578 arrayClassType.supertype_field = objectType; 579 arrayClassType.interfaces_field = List.of(cloneableType, serializableType); 580 arrayClass.members_field = WriteableScope.create(arrayClass); 581 lengthVar = new VarSymbol( 582 PUBLIC | FINAL, 583 names.length, 584 intType, 585 arrayClass); 586 arrayClass.members().enter(lengthVar); 587 arrayCloneMethod = new MethodSymbol( 588 PUBLIC, 589 names.clone, 590 new MethodType(List.<Type>nil(), objectType, 591 List.<Type>nil(), methodClass), 592 arrayClass); 593 arrayClass.members().enter(arrayCloneMethod); 594 595 // Enter operators. 596 /* Internally we use +++, --- for unary +, - to reduce +, - operators 597 * overloading 598 */ 599 enterUnop("+++", doubleType, doubleType, nop); 600 enterUnop("+++", floatType, floatType, nop); 601 enterUnop("+++", longType, longType, nop); 602 enterUnop("+++", intType, intType, nop); 603 604 enterUnop("---", doubleType, doubleType, dneg); 605 enterUnop("---", floatType, floatType, fneg); 606 enterUnop("---", longType, longType, lneg); 607 enterUnop("---", intType, intType, ineg); 608 609 enterUnop("~", longType, longType, lxor); 610 enterUnop("~", intType, intType, ixor); 611 612 enterUnop("++", doubleType, doubleType, dadd); 613 enterUnop("++", floatType, floatType, fadd); 614 enterUnop("++", longType, longType, ladd); 615 enterUnop("++", intType, intType, iadd); 616 enterUnop("++", charType, charType, iadd); 617 enterUnop("++", shortType, shortType, iadd); 618 enterUnop("++", byteType, byteType, iadd); 619 620 enterUnop("--", doubleType, doubleType, dsub); 621 enterUnop("--", floatType, floatType, fsub); 622 enterUnop("--", longType, longType, lsub); 623 enterUnop("--", intType, intType, isub); 624 enterUnop("--", charType, charType, isub); 625 enterUnop("--", shortType, shortType, isub); 626 enterUnop("--", byteType, byteType, isub); 627 628 enterUnop("!", booleanType, booleanType, bool_not); 629 nullcheck = enterUnop("<*nullchk*>", objectType, objectType, nullchk); 630 631 // string concatenation 632 enterBinop("+", stringType, objectType, stringType, string_add); 633 enterBinop("+", objectType, stringType, stringType, string_add); 634 enterBinop("+", stringType, stringType, stringType, string_add); 635 enterBinop("+", stringType, intType, stringType, string_add); 636 enterBinop("+", stringType, longType, stringType, string_add); 637 enterBinop("+", stringType, floatType, stringType, string_add); 638 enterBinop("+", stringType, doubleType, stringType, string_add); 639 enterBinop("+", stringType, booleanType, stringType, string_add); 640 enterBinop("+", stringType, botType, stringType, string_add); 641 enterBinop("+", intType, stringType, stringType, string_add); 642 enterBinop("+", longType, stringType, stringType, string_add); 643 enterBinop("+", floatType, stringType, stringType, string_add); 644 enterBinop("+", doubleType, stringType, stringType, string_add); 645 enterBinop("+", booleanType, stringType, stringType, string_add); 646 enterBinop("+", botType, stringType, stringType, string_add); 647 648 // these errors would otherwise be matched as string concatenation 649 enterBinop("+", botType, botType, botType, error); 650 enterBinop("+", botType, intType, botType, error); 651 enterBinop("+", botType, longType, botType, error); 652 enterBinop("+", botType, floatType, botType, error); 653 enterBinop("+", botType, doubleType, botType, error); 654 enterBinop("+", botType, booleanType, botType, error); 655 enterBinop("+", botType, objectType, botType, error); 656 enterBinop("+", intType, botType, botType, error); 657 enterBinop("+", longType, botType, botType, error); 658 enterBinop("+", floatType, botType, botType, error); 659 enterBinop("+", doubleType, botType, botType, error); 660 enterBinop("+", booleanType, botType, botType, error); 661 enterBinop("+", objectType, botType, botType, error); 662 663 enterBinop("+", doubleType, doubleType, doubleType, dadd); 664 enterBinop("+", floatType, floatType, floatType, fadd); 665 enterBinop("+", longType, longType, longType, ladd); 666 enterBinop("+", intType, intType, intType, iadd); 667 668 enterBinop("-", doubleType, doubleType, doubleType, dsub); 669 enterBinop("-", floatType, floatType, floatType, fsub); 670 enterBinop("-", longType, longType, longType, lsub); 671 enterBinop("-", intType, intType, intType, isub); 672 673 enterBinop("*", doubleType, doubleType, doubleType, dmul); 674 enterBinop("*", floatType, floatType, floatType, fmul); 675 enterBinop("*", longType, longType, longType, lmul); 676 enterBinop("*", intType, intType, intType, imul); 677 678 enterBinop("/", doubleType, doubleType, doubleType, ddiv); 679 enterBinop("/", floatType, floatType, floatType, fdiv); 680 enterBinop("/", longType, longType, longType, ldiv); 681 enterBinop("/", intType, intType, intType, idiv); 682 683 enterBinop("%", doubleType, doubleType, doubleType, dmod); 684 enterBinop("%", floatType, floatType, floatType, fmod); 685 enterBinop("%", longType, longType, longType, lmod); 686 enterBinop("%", intType, intType, intType, imod); 687 688 enterBinop("&", booleanType, booleanType, booleanType, iand); 689 enterBinop("&", longType, longType, longType, land); 690 enterBinop("&", intType, intType, intType, iand); 691 692 enterBinop("|", booleanType, booleanType, booleanType, ior); 693 enterBinop("|", longType, longType, longType, lor); 694 enterBinop("|", intType, intType, intType, ior); 695 696 enterBinop("^", booleanType, booleanType, booleanType, ixor); 697 enterBinop("^", longType, longType, longType, lxor); 698 enterBinop("^", intType, intType, intType, ixor); 699 700 enterBinop("<<", longType, longType, longType, lshll); 701 enterBinop("<<", intType, longType, intType, ishll); 702 enterBinop("<<", longType, intType, longType, lshl); 703 enterBinop("<<", intType, intType, intType, ishl); 704 705 enterBinop(">>", longType, longType, longType, lshrl); 706 enterBinop(">>", intType, longType, intType, ishrl); 707 enterBinop(">>", longType, intType, longType, lshr); 708 enterBinop(">>", intType, intType, intType, ishr); 709 710 enterBinop(">>>", longType, longType, longType, lushrl); 711 enterBinop(">>>", intType, longType, intType, iushrl); 712 enterBinop(">>>", longType, intType, longType, lushr); 713 enterBinop(">>>", intType, intType, intType, iushr); 714 715 enterBinop("<", doubleType, doubleType, booleanType, dcmpg, iflt); 716 enterBinop("<", floatType, floatType, booleanType, fcmpg, iflt); 717 enterBinop("<", longType, longType, booleanType, lcmp, iflt); 718 enterBinop("<", intType, intType, booleanType, if_icmplt); 719 720 enterBinop(">", doubleType, doubleType, booleanType, dcmpl, ifgt); 721 enterBinop(">", floatType, floatType, booleanType, fcmpl, ifgt); 722 enterBinop(">", longType, longType, booleanType, lcmp, ifgt); 723 enterBinop(">", intType, intType, booleanType, if_icmpgt); 724 725 enterBinop("<=", doubleType, doubleType, booleanType, dcmpg, ifle); 726 enterBinop("<=", floatType, floatType, booleanType, fcmpg, ifle); 727 enterBinop("<=", longType, longType, booleanType, lcmp, ifle); 728 enterBinop("<=", intType, intType, booleanType, if_icmple); 729 730 enterBinop(">=", doubleType, doubleType, booleanType, dcmpl, ifge); 731 enterBinop(">=", floatType, floatType, booleanType, fcmpl, ifge); 732 enterBinop(">=", longType, longType, booleanType, lcmp, ifge); 733 enterBinop(">=", intType, intType, booleanType, if_icmpge); 734 735 enterBinop("==", objectType, objectType, booleanType, if_acmpeq); 736 enterBinop("==", booleanType, booleanType, booleanType, if_icmpeq); 737 enterBinop("==", doubleType, doubleType, booleanType, dcmpl, ifeq); 738 enterBinop("==", floatType, floatType, booleanType, fcmpl, ifeq); 739 enterBinop("==", longType, longType, booleanType, lcmp, ifeq); 740 enterBinop("==", intType, intType, booleanType, if_icmpeq); 741 742 enterBinop("!=", objectType, objectType, booleanType, if_acmpne); 743 enterBinop("!=", booleanType, booleanType, booleanType, if_icmpne); 744 enterBinop("!=", doubleType, doubleType, booleanType, dcmpl, ifne); 745 enterBinop("!=", floatType, floatType, booleanType, fcmpl, ifne); 746 enterBinop("!=", longType, longType, booleanType, lcmp, ifne); 747 enterBinop("!=", intType, intType, booleanType, if_icmpne); 748 749 enterBinop("&&", booleanType, booleanType, booleanType, bool_and); 750 enterBinop("||", booleanType, booleanType, booleanType, bool_or); 751 } 752 753 /** Define a new class given its name and owner. 754 */ 755 public ClassSymbol defineClass(Name name, Symbol owner) { 756 ClassSymbol c = new ClassSymbol(0, name, owner); 757 if (owner.kind == PCK) 758 Assert.checkNull(classes.get(c.flatname), c); 759 c.completer = initialCompleter; 760 return c; 761 } 762 763 /** Create a new toplevel or member class symbol with given name 764 * and owner and enter in `classes' unless already there. 765 */ 766 public ClassSymbol enterClass(Name name, TypeSymbol owner) { 767 Name flatname = TypeSymbol.formFlatName(name, owner); 768 ClassSymbol c = classes.get(flatname); 769 if (c == null) { 770 c = defineClass(name, owner); 771 classes.put(flatname, c); 772 } else if ((c.name != name || c.owner != owner) && owner.kind == TYP && c.owner.kind == PCK) { 773 // reassign fields of classes that might have been loaded with 774 // their flat names. 775 c.owner.members().remove(c); 776 c.name = name; 777 c.owner = owner; 778 c.fullname = ClassSymbol.formFullName(name, owner); 779 } 780 return c; 781 } 782 783 /** 784 * Creates a new toplevel class symbol with given flat name and 785 * given class (or source) file. 786 * 787 * @param flatName a fully qualified binary class name 788 * @param classFile the class file or compilation unit defining 789 * the class (may be {@code null}) 790 * @return a newly created class symbol 791 * @throws AssertionError if the class symbol already exists 792 */ 793 public ClassSymbol enterClass(Name flatName, JavaFileObject classFile) { 794 ClassSymbol cs = classes.get(flatName); 795 if (cs != null) { 796 String msg = Log.format("%s: completer = %s; class file = %s; source file = %s", 797 cs.fullname, 798 cs.completer, 799 cs.classfile, 800 cs.sourcefile); 801 throw new AssertionError(msg); 802 } 803 Name packageName = Convert.packagePart(flatName); 804 PackageSymbol owner = packageName.isEmpty() 805 ? unnamedPackage 806 : enterPackage(packageName); 807 cs = defineClass(Convert.shortName(flatName), owner); 808 cs.classfile = classFile; 809 classes.put(flatName, cs); 810 return cs; 811 } 812 813 /** Create a new member or toplevel class symbol with given flat name 814 * and enter in `classes' unless already there. 815 */ 816 public ClassSymbol enterClass(Name flatname) { 817 ClassSymbol c = classes.get(flatname); 818 if (c == null) 819 return enterClass(flatname, (JavaFileObject)null); 820 else 821 return c; 822 } 823 824 /** Check to see if a package exists, given its fully qualified name. 825 */ 826 public boolean packageExists(Name fullname) { 827 return enterPackage(fullname).exists(); 828 } 829 830 /** Make a package, given its fully qualified name. 831 */ 832 public PackageSymbol enterPackage(Name fullname) { 833 PackageSymbol p = packages.get(fullname); 834 if (p == null) { 835 Assert.check(!fullname.isEmpty(), "rootPackage missing!"); 836 p = new PackageSymbol( 837 Convert.shortName(fullname), 838 enterPackage(Convert.packagePart(fullname))); 839 p.completer = initialCompleter; 840 packages.put(fullname, p); 841 } 842 return p; 843 } 844 845 /** Make a package, given its unqualified name and enclosing package. 846 */ 847 public PackageSymbol enterPackage(Name name, PackageSymbol owner) { 848 return enterPackage(TypeSymbol.formFullName(name, owner)); 849 } 850} 851