Mon, 17 Dec 2012 07:47:05 -0800
8004832: Add new doclint package
Reviewed-by: mcimadamore
duke@1 | 1 | /* |
jjg@1230 | 2 | * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. |
duke@1 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
duke@1 | 4 | * |
duke@1 | 5 | * This code is free software; you can redistribute it and/or modify it |
duke@1 | 6 | * under the terms of the GNU General Public License version 2 only, as |
ohair@554 | 7 | * published by the Free Software Foundation. Oracle designates this |
duke@1 | 8 | * particular file as subject to the "Classpath" exception as provided |
ohair@554 | 9 | * by Oracle in the LICENSE file that accompanied this code. |
duke@1 | 10 | * |
duke@1 | 11 | * This code is distributed in the hope that it will be useful, but WITHOUT |
duke@1 | 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
duke@1 | 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
duke@1 | 14 | * version 2 for more details (a copy is included in the LICENSE file that |
duke@1 | 15 | * accompanied this code). |
duke@1 | 16 | * |
duke@1 | 17 | * You should have received a copy of the GNU General Public License version |
duke@1 | 18 | * 2 along with this work; if not, write to the Free Software Foundation, |
duke@1 | 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
duke@1 | 20 | * |
ohair@554 | 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
ohair@554 | 22 | * or visit www.oracle.com if you need additional information or have any |
ohair@554 | 23 | * questions. |
duke@1 | 24 | */ |
duke@1 | 25 | |
duke@1 | 26 | package com.sun.tools.javac.code; |
duke@1 | 27 | |
duke@1 | 28 | import java.util.*; |
jjg@1357 | 29 | |
jjg@1357 | 30 | import javax.lang.model.element.ElementVisitor; |
jjg@900 | 31 | import javax.lang.model.type.TypeVisitor; |
duke@1 | 32 | |
duke@1 | 33 | import com.sun.tools.javac.code.Symbol.*; |
duke@1 | 34 | import com.sun.tools.javac.code.Type.*; |
duke@1 | 35 | import com.sun.tools.javac.jvm.*; |
jjg@1357 | 36 | import com.sun.tools.javac.util.*; |
jjg@1357 | 37 | import com.sun.tools.javac.util.List; |
jjg@1357 | 38 | import static com.sun.tools.javac.code.Flags.*; |
duke@1 | 39 | import static com.sun.tools.javac.jvm.ByteCodes.*; |
jjg@1374 | 40 | import static com.sun.tools.javac.code.TypeTag.*; |
duke@1 | 41 | |
duke@1 | 42 | /** A class that defines all predefined constants and operators |
duke@1 | 43 | * as well as special classes such as java.lang.Object, which need |
duke@1 | 44 | * to be known to the compiler. All symbols are held in instance |
duke@1 | 45 | * fields. This makes it possible to work in multiple concurrent |
duke@1 | 46 | * projects, which might use different class files for library classes. |
duke@1 | 47 | * |
jjg@581 | 48 | * <p><b>This is NOT part of any supported API. |
jjg@581 | 49 | * If you write code that depends on this, you do so at your own risk. |
duke@1 | 50 | * This code and its internal interfaces are subject to change or |
duke@1 | 51 | * deletion without notice.</b> |
duke@1 | 52 | */ |
duke@1 | 53 | public class Symtab { |
duke@1 | 54 | /** The context key for the symbol table. */ |
duke@1 | 55 | protected static final Context.Key<Symtab> symtabKey = |
duke@1 | 56 | new Context.Key<Symtab>(); |
duke@1 | 57 | |
duke@1 | 58 | /** Get the symbol table instance. */ |
duke@1 | 59 | public static Symtab instance(Context context) { |
duke@1 | 60 | Symtab instance = context.get(symtabKey); |
duke@1 | 61 | if (instance == null) |
duke@1 | 62 | instance = new Symtab(context); |
duke@1 | 63 | return instance; |
duke@1 | 64 | } |
duke@1 | 65 | |
duke@1 | 66 | /** Builtin types. |
duke@1 | 67 | */ |
jjg@1374 | 68 | public final Type byteType = new Type(BYTE, null); |
jjg@1374 | 69 | public final Type charType = new Type(CHAR, null); |
jjg@1374 | 70 | public final Type shortType = new Type(SHORT, null); |
jjg@1374 | 71 | public final Type intType = new Type(INT, null); |
jjg@1374 | 72 | public final Type longType = new Type(LONG, null); |
jjg@1374 | 73 | public final Type floatType = new Type(FLOAT, null); |
jjg@1374 | 74 | public final Type doubleType = new Type(DOUBLE, null); |
jjg@1374 | 75 | public final Type booleanType = new Type(BOOLEAN, null); |
duke@1 | 76 | public final Type botType = new BottomType(); |
jjg@1374 | 77 | public final JCNoType voidType = new JCNoType(VOID); |
duke@1 | 78 | |
jjg@113 | 79 | private final Names names; |
duke@1 | 80 | private final ClassReader reader; |
jjg@86 | 81 | private final Target target; |
duke@1 | 82 | |
duke@1 | 83 | /** A symbol for the root package. |
duke@1 | 84 | */ |
duke@1 | 85 | public final PackageSymbol rootPackage; |
duke@1 | 86 | |
duke@1 | 87 | /** A symbol for the unnamed package. |
duke@1 | 88 | */ |
duke@1 | 89 | public final PackageSymbol unnamedPackage; |
duke@1 | 90 | |
duke@1 | 91 | /** A symbol that stands for a missing symbol. |
duke@1 | 92 | */ |
duke@1 | 93 | public final TypeSymbol noSymbol; |
duke@1 | 94 | |
duke@1 | 95 | /** The error symbol. |
duke@1 | 96 | */ |
duke@1 | 97 | public final ClassSymbol errSymbol; |
duke@1 | 98 | |
mcimadamore@676 | 99 | /** The unknown symbol. |
mcimadamore@676 | 100 | */ |
mcimadamore@676 | 101 | public final ClassSymbol unknownSymbol; |
mcimadamore@676 | 102 | |
jjg@110 | 103 | /** A value for the errType, with a originalType of noType */ |
duke@1 | 104 | public final Type errType; |
duke@1 | 105 | |
duke@1 | 106 | /** A value for the unknown type. */ |
duke@1 | 107 | public final Type unknownType; |
duke@1 | 108 | |
duke@1 | 109 | /** The builtin type of all arrays. */ |
duke@1 | 110 | public final ClassSymbol arrayClass; |
duke@1 | 111 | public final MethodSymbol arrayCloneMethod; |
duke@1 | 112 | |
duke@1 | 113 | /** VGJ: The (singleton) type of all bound types. */ |
duke@1 | 114 | public final ClassSymbol boundClass; |
duke@1 | 115 | |
duke@1 | 116 | /** The builtin type of all methods. */ |
duke@1 | 117 | public final ClassSymbol methodClass; |
duke@1 | 118 | |
duke@1 | 119 | /** Predefined types. |
duke@1 | 120 | */ |
duke@1 | 121 | public final Type objectType; |
duke@1 | 122 | public final Type classType; |
duke@1 | 123 | public final Type classLoaderType; |
duke@1 | 124 | public final Type stringType; |
duke@1 | 125 | public final Type stringBufferType; |
duke@1 | 126 | public final Type stringBuilderType; |
duke@1 | 127 | public final Type cloneableType; |
duke@1 | 128 | public final Type serializableType; |
jrose@267 | 129 | public final Type methodHandleType; |
rfield@1380 | 130 | public final Type methodHandleLookupType; |
mcimadamore@1336 | 131 | public final Type methodTypeType; |
jjg@1230 | 132 | public final Type nativeHeaderType; |
jjg@1407 | 133 | public final Type nativeHeaderType_old; |
duke@1 | 134 | public final Type throwableType; |
duke@1 | 135 | public final Type errorType; |
mcimadamore@951 | 136 | public final Type interruptedExceptionType; |
duke@1 | 137 | public final Type illegalArgumentExceptionType; |
duke@1 | 138 | public final Type exceptionType; |
duke@1 | 139 | public final Type runtimeExceptionType; |
duke@1 | 140 | public final Type classNotFoundExceptionType; |
duke@1 | 141 | public final Type noClassDefFoundErrorType; |
duke@1 | 142 | public final Type noSuchFieldErrorType; |
duke@1 | 143 | public final Type assertionErrorType; |
duke@1 | 144 | public final Type cloneNotSupportedExceptionType; |
duke@1 | 145 | public final Type annotationType; |
duke@1 | 146 | public final TypeSymbol enumSym; |
duke@1 | 147 | public final Type listType; |
duke@1 | 148 | public final Type collectionsType; |
duke@1 | 149 | public final Type comparableType; |
duke@1 | 150 | public final Type arraysType; |
duke@1 | 151 | public final Type iterableType; |
duke@1 | 152 | public final Type iteratorType; |
duke@1 | 153 | public final Type annotationTargetType; |
duke@1 | 154 | public final Type overrideType; |
duke@1 | 155 | public final Type retentionType; |
duke@1 | 156 | public final Type deprecatedType; |
duke@1 | 157 | public final Type suppressWarningsType; |
duke@1 | 158 | public final Type inheritedType; |
duke@1 | 159 | public final Type proprietaryType; |
jjg@86 | 160 | public final Type systemType; |
darcy@609 | 161 | public final Type autoCloseableType; |
mcimadamore@795 | 162 | public final Type trustMeType; |
rfield@1380 | 163 | public final Type lambdaMetafactory; |
jfranck@1313 | 164 | public final Type containedByType; |
jfranck@1313 | 165 | public final Type containerForType; |
jfranck@1313 | 166 | public final Type documentedType; |
jfranck@1313 | 167 | public final Type elementTypeType; |
duke@1 | 168 | |
duke@1 | 169 | /** The symbol representing the length field of an array. |
duke@1 | 170 | */ |
duke@1 | 171 | public final VarSymbol lengthVar; |
duke@1 | 172 | |
duke@1 | 173 | /** The null check operator. */ |
duke@1 | 174 | public final OperatorSymbol nullcheck; |
duke@1 | 175 | |
duke@1 | 176 | /** The symbol representing the final finalize method on enums */ |
duke@1 | 177 | public final MethodSymbol enumFinalFinalize; |
duke@1 | 178 | |
darcy@609 | 179 | /** The symbol representing the close method on TWR AutoCloseable type */ |
darcy@609 | 180 | public final MethodSymbol autoCloseableClose; |
darcy@609 | 181 | |
duke@1 | 182 | /** The predefined type that belongs to a tag. |
duke@1 | 183 | */ |
jjg@1374 | 184 | public final Type[] typeOfTag = new Type[TypeTag.getTypeTagCount()]; |
duke@1 | 185 | |
duke@1 | 186 | /** The name of the class that belongs to a basix type tag. |
duke@1 | 187 | */ |
jjg@1374 | 188 | public final Name[] boxedName = new Name[TypeTag.getTypeTagCount()]; |
duke@1 | 189 | |
mcimadamore@1347 | 190 | /** A set containing all operator names. |
mcimadamore@1347 | 191 | */ |
mcimadamore@1347 | 192 | public final Set<Name> operatorNames = new HashSet<Name>(); |
mcimadamore@1347 | 193 | |
duke@1 | 194 | /** A hashtable containing the encountered top-level and member classes, |
duke@1 | 195 | * indexed by flat names. The table does not contain local classes. |
duke@1 | 196 | * It should be updated from the outside to reflect classes defined |
duke@1 | 197 | * by compiled source files. |
duke@1 | 198 | */ |
duke@1 | 199 | public final Map<Name, ClassSymbol> classes = new HashMap<Name, ClassSymbol>(); |
duke@1 | 200 | |
duke@1 | 201 | /** A hashtable containing the encountered packages. |
duke@1 | 202 | * the table should be updated from outside to reflect packages defined |
duke@1 | 203 | * by compiled source files. |
duke@1 | 204 | */ |
duke@1 | 205 | public final Map<Name, PackageSymbol> packages = new HashMap<Name, PackageSymbol>(); |
duke@1 | 206 | |
duke@1 | 207 | public void initType(Type type, ClassSymbol c) { |
duke@1 | 208 | type.tsym = c; |
jjg@1374 | 209 | typeOfTag[type.tag.ordinal()] = type; |
duke@1 | 210 | } |
duke@1 | 211 | |
duke@1 | 212 | public void initType(Type type, String name) { |
duke@1 | 213 | initType( |
duke@1 | 214 | type, |
duke@1 | 215 | new ClassSymbol( |
duke@1 | 216 | PUBLIC, names.fromString(name), type, rootPackage)); |
duke@1 | 217 | } |
duke@1 | 218 | |
duke@1 | 219 | public void initType(Type type, String name, String bname) { |
duke@1 | 220 | initType(type, name); |
jjg@1374 | 221 | boxedName[type.tag.ordinal()] = names.fromString("java.lang." + bname); |
duke@1 | 222 | } |
duke@1 | 223 | |
duke@1 | 224 | /** The class symbol that owns all predefined symbols. |
duke@1 | 225 | */ |
duke@1 | 226 | public final ClassSymbol predefClass; |
duke@1 | 227 | |
duke@1 | 228 | /** Enter a constant into symbol table. |
duke@1 | 229 | * @param name The constant's name. |
duke@1 | 230 | * @param type The constant's type. |
duke@1 | 231 | */ |
duke@1 | 232 | private VarSymbol enterConstant(String name, Type type) { |
duke@1 | 233 | VarSymbol c = new VarSymbol( |
duke@1 | 234 | PUBLIC | STATIC | FINAL, |
duke@1 | 235 | names.fromString(name), |
duke@1 | 236 | type, |
duke@1 | 237 | predefClass); |
duke@1 | 238 | c.setData(type.constValue()); |
duke@1 | 239 | predefClass.members().enter(c); |
duke@1 | 240 | return c; |
duke@1 | 241 | } |
duke@1 | 242 | |
duke@1 | 243 | /** Enter a binary operation into symbol table. |
duke@1 | 244 | * @param name The name of the operator. |
duke@1 | 245 | * @param left The type of the left operand. |
duke@1 | 246 | * @param right The type of the left operand. |
duke@1 | 247 | * @param res The operation's result type. |
duke@1 | 248 | * @param opcode The operation's bytecode instruction. |
duke@1 | 249 | */ |
duke@1 | 250 | private void enterBinop(String name, |
duke@1 | 251 | Type left, Type right, Type res, |
duke@1 | 252 | int opcode) { |
duke@1 | 253 | predefClass.members().enter( |
duke@1 | 254 | new OperatorSymbol( |
mcimadamore@1347 | 255 | makeOperatorName(name), |
duke@1 | 256 | new MethodType(List.of(left, right), res, |
duke@1 | 257 | List.<Type>nil(), methodClass), |
duke@1 | 258 | opcode, |
duke@1 | 259 | predefClass)); |
duke@1 | 260 | } |
duke@1 | 261 | |
duke@1 | 262 | /** Enter a binary operation, as above but with two opcodes, |
jjg@1326 | 263 | * which get encoded as |
jjg@1326 | 264 | * {@code (opcode1 << ByteCodeTags.preShift) + opcode2 }. |
duke@1 | 265 | * @param opcode1 First opcode. |
duke@1 | 266 | * @param opcode2 Second opcode. |
duke@1 | 267 | */ |
duke@1 | 268 | private void enterBinop(String name, |
duke@1 | 269 | Type left, Type right, Type res, |
duke@1 | 270 | int opcode1, int opcode2) { |
duke@1 | 271 | enterBinop( |
duke@1 | 272 | name, left, right, res, (opcode1 << ByteCodes.preShift) | opcode2); |
duke@1 | 273 | } |
duke@1 | 274 | |
duke@1 | 275 | /** Enter a unary operation into symbol table. |
duke@1 | 276 | * @param name The name of the operator. |
duke@1 | 277 | * @param arg The type of the operand. |
duke@1 | 278 | * @param res The operation's result type. |
duke@1 | 279 | * @param opcode The operation's bytecode instruction. |
duke@1 | 280 | */ |
duke@1 | 281 | private OperatorSymbol enterUnop(String name, |
duke@1 | 282 | Type arg, |
duke@1 | 283 | Type res, |
duke@1 | 284 | int opcode) { |
duke@1 | 285 | OperatorSymbol sym = |
mcimadamore@1347 | 286 | new OperatorSymbol(makeOperatorName(name), |
duke@1 | 287 | new MethodType(List.of(arg), |
duke@1 | 288 | res, |
duke@1 | 289 | List.<Type>nil(), |
duke@1 | 290 | methodClass), |
duke@1 | 291 | opcode, |
duke@1 | 292 | predefClass); |
duke@1 | 293 | predefClass.members().enter(sym); |
duke@1 | 294 | return sym; |
duke@1 | 295 | } |
duke@1 | 296 | |
mcimadamore@1347 | 297 | /** |
mcimadamore@1347 | 298 | * Create a new operator name from corresponding String representation |
mcimadamore@1347 | 299 | * and add the name to the set of known operator names. |
mcimadamore@1347 | 300 | */ |
mcimadamore@1347 | 301 | private Name makeOperatorName(String name) { |
mcimadamore@1347 | 302 | Name opName = names.fromString(name); |
mcimadamore@1347 | 303 | operatorNames.add(opName); |
mcimadamore@1347 | 304 | return opName; |
mcimadamore@1347 | 305 | } |
mcimadamore@1347 | 306 | |
duke@1 | 307 | /** Enter a class into symbol table. |
jjg@1358 | 308 | * @param s The name of the class. |
duke@1 | 309 | */ |
duke@1 | 310 | private Type enterClass(String s) { |
duke@1 | 311 | return reader.enterClass(names.fromString(s)).type; |
duke@1 | 312 | } |
duke@1 | 313 | |
jjg@86 | 314 | public void synthesizeEmptyInterfaceIfMissing(final Type type) { |
jjg@86 | 315 | final Completer completer = type.tsym.completer; |
jjg@86 | 316 | if (completer != null) { |
jjg@86 | 317 | type.tsym.completer = new Completer() { |
jjg@86 | 318 | public void complete(Symbol sym) throws CompletionFailure { |
jjg@86 | 319 | try { |
jjg@86 | 320 | completer.complete(sym); |
jjg@86 | 321 | } catch (CompletionFailure e) { |
jjg@86 | 322 | sym.flags_field |= (PUBLIC | INTERFACE); |
jjg@86 | 323 | ((ClassType) sym.type).supertype_field = objectType; |
jjg@86 | 324 | } |
jjg@86 | 325 | } |
jjg@86 | 326 | }; |
jjg@86 | 327 | } |
jjg@86 | 328 | } |
jjg@86 | 329 | |
jjg@86 | 330 | public void synthesizeBoxTypeIfMissing(final Type type) { |
jjg@1374 | 331 | ClassSymbol sym = reader.enterClass(boxedName[type.tag.ordinal()]); |
jjg@86 | 332 | final Completer completer = sym.completer; |
jjg@86 | 333 | if (completer != null) { |
jjg@86 | 334 | sym.completer = new Completer() { |
jjg@86 | 335 | public void complete(Symbol sym) throws CompletionFailure { |
jjg@86 | 336 | try { |
jjg@86 | 337 | completer.complete(sym); |
jjg@86 | 338 | } catch (CompletionFailure e) { |
jjg@86 | 339 | sym.flags_field |= PUBLIC; |
jjg@86 | 340 | ((ClassType) sym.type).supertype_field = objectType; |
jjg@86 | 341 | Name n = target.boxWithConstructors() ? names.init : names.valueOf; |
jjg@86 | 342 | MethodSymbol boxMethod = |
jjg@86 | 343 | new MethodSymbol(PUBLIC | STATIC, |
jjg@86 | 344 | n, |
jjg@86 | 345 | new MethodType(List.of(type), sym.type, |
jjg@86 | 346 | List.<Type>nil(), methodClass), |
jjg@86 | 347 | sym); |
jjg@86 | 348 | sym.members().enter(boxMethod); |
jjg@86 | 349 | MethodSymbol unboxMethod = |
jjg@86 | 350 | new MethodSymbol(PUBLIC, |
jjg@86 | 351 | type.tsym.name.append(names.Value), // x.intValue() |
jjg@86 | 352 | new MethodType(List.<Type>nil(), type, |
jjg@86 | 353 | List.<Type>nil(), methodClass), |
jjg@86 | 354 | sym); |
jjg@86 | 355 | sym.members().enter(unboxMethod); |
jjg@86 | 356 | } |
jjg@86 | 357 | } |
jjg@86 | 358 | }; |
jjg@86 | 359 | } |
jjg@86 | 360 | |
jjg@86 | 361 | } |
jjg@86 | 362 | |
duke@1 | 363 | /** Constructor; enters all predefined identifiers and operators |
duke@1 | 364 | * into symbol table. |
duke@1 | 365 | */ |
duke@1 | 366 | protected Symtab(Context context) throws CompletionFailure { |
duke@1 | 367 | context.put(symtabKey, this); |
duke@1 | 368 | |
jjg@113 | 369 | names = Names.instance(context); |
jjg@86 | 370 | target = Target.instance(context); |
duke@1 | 371 | |
duke@1 | 372 | // Create the unknown type |
jjg@1374 | 373 | unknownType = new Type(UNKNOWN, null) { |
jjg@900 | 374 | @Override |
jjg@900 | 375 | public <R, P> R accept(TypeVisitor<R, P> v, P p) { |
jjg@900 | 376 | return v.visitUnknown(this, p); |
jjg@900 | 377 | } |
jjg@900 | 378 | }; |
duke@1 | 379 | |
duke@1 | 380 | // create the basic builtin symbols |
duke@1 | 381 | rootPackage = new PackageSymbol(names.empty, null); |
mcimadamore@136 | 382 | final JavacMessages messages = JavacMessages.instance(context); |
duke@1 | 383 | unnamedPackage = new PackageSymbol(names.empty, rootPackage) { |
duke@1 | 384 | public String toString() { |
duke@1 | 385 | return messages.getLocalizedString("compiler.misc.unnamed.package"); |
duke@1 | 386 | } |
duke@1 | 387 | }; |
jjg@900 | 388 | noSymbol = new TypeSymbol(0, names.empty, Type.noType, rootPackage) { |
jjg@900 | 389 | public <R, P> R accept(ElementVisitor<R, P> v, P p) { |
jjg@900 | 390 | return v.visitUnknown(this, p); |
jjg@900 | 391 | } |
jjg@900 | 392 | }; |
duke@1 | 393 | noSymbol.kind = Kinds.NIL; |
duke@1 | 394 | |
duke@1 | 395 | // create the error symbols |
duke@1 | 396 | errSymbol = new ClassSymbol(PUBLIC|STATIC|ACYCLIC, names.any, null, rootPackage); |
jjg@900 | 397 | errType = new ErrorType(errSymbol, Type.noType); |
jjg@900 | 398 | |
mcimadamore@676 | 399 | unknownSymbol = new ClassSymbol(PUBLIC|STATIC|ACYCLIC, names.fromString("<any?>"), null, rootPackage); |
jjg@900 | 400 | unknownSymbol.members_field = new Scope.ErrorScope(unknownSymbol); |
jjg@900 | 401 | unknownSymbol.type = unknownType; |
duke@1 | 402 | |
duke@1 | 403 | // initialize builtin types |
duke@1 | 404 | initType(byteType, "byte", "Byte"); |
duke@1 | 405 | initType(shortType, "short", "Short"); |
duke@1 | 406 | initType(charType, "char", "Character"); |
duke@1 | 407 | initType(intType, "int", "Integer"); |
duke@1 | 408 | initType(longType, "long", "Long"); |
duke@1 | 409 | initType(floatType, "float", "Float"); |
duke@1 | 410 | initType(doubleType, "double", "Double"); |
duke@1 | 411 | initType(booleanType, "boolean", "Boolean"); |
duke@1 | 412 | initType(voidType, "void", "Void"); |
duke@1 | 413 | initType(botType, "<nulltype>"); |
duke@1 | 414 | initType(errType, errSymbol); |
mcimadamore@676 | 415 | initType(unknownType, unknownSymbol); |
duke@1 | 416 | |
duke@1 | 417 | // the builtin class of all arrays |
duke@1 | 418 | arrayClass = new ClassSymbol(PUBLIC|ACYCLIC, names.Array, noSymbol); |
duke@1 | 419 | |
duke@1 | 420 | // VGJ |
duke@1 | 421 | boundClass = new ClassSymbol(PUBLIC|ACYCLIC, names.Bound, noSymbol); |
jjg@900 | 422 | boundClass.members_field = new Scope.ErrorScope(boundClass); |
duke@1 | 423 | |
duke@1 | 424 | // the builtin class of all methods |
duke@1 | 425 | methodClass = new ClassSymbol(PUBLIC|ACYCLIC, names.Method, noSymbol); |
jjg@900 | 426 | methodClass.members_field = new Scope.ErrorScope(boundClass); |
duke@1 | 427 | |
duke@1 | 428 | // Create class to hold all predefined constants and operations. |
duke@1 | 429 | predefClass = new ClassSymbol(PUBLIC|ACYCLIC, names.empty, rootPackage); |
mcimadamore@858 | 430 | Scope scope = new Scope(predefClass); |
duke@1 | 431 | predefClass.members_field = scope; |
duke@1 | 432 | |
duke@1 | 433 | // Enter symbols for basic types. |
duke@1 | 434 | scope.enter(byteType.tsym); |
duke@1 | 435 | scope.enter(shortType.tsym); |
duke@1 | 436 | scope.enter(charType.tsym); |
duke@1 | 437 | scope.enter(intType.tsym); |
duke@1 | 438 | scope.enter(longType.tsym); |
duke@1 | 439 | scope.enter(floatType.tsym); |
duke@1 | 440 | scope.enter(doubleType.tsym); |
duke@1 | 441 | scope.enter(booleanType.tsym); |
duke@1 | 442 | scope.enter(errType.tsym); |
duke@1 | 443 | |
jjg@110 | 444 | // Enter symbol for the errSymbol |
jjg@110 | 445 | scope.enter(errSymbol); |
jjg@110 | 446 | |
duke@1 | 447 | classes.put(predefClass.fullname, predefClass); |
duke@1 | 448 | |
duke@1 | 449 | reader = ClassReader.instance(context); |
duke@1 | 450 | reader.init(this); |
duke@1 | 451 | |
duke@1 | 452 | // Enter predefined classes. |
duke@1 | 453 | objectType = enterClass("java.lang.Object"); |
duke@1 | 454 | classType = enterClass("java.lang.Class"); |
duke@1 | 455 | stringType = enterClass("java.lang.String"); |
duke@1 | 456 | stringBufferType = enterClass("java.lang.StringBuffer"); |
duke@1 | 457 | stringBuilderType = enterClass("java.lang.StringBuilder"); |
duke@1 | 458 | cloneableType = enterClass("java.lang.Cloneable"); |
duke@1 | 459 | throwableType = enterClass("java.lang.Throwable"); |
duke@1 | 460 | serializableType = enterClass("java.io.Serializable"); |
mcimadamore@857 | 461 | methodHandleType = enterClass("java.lang.invoke.MethodHandle"); |
rfield@1380 | 462 | methodHandleLookupType = enterClass("java.lang.invoke.MethodHandles$Lookup"); |
mcimadamore@1336 | 463 | methodTypeType = enterClass("java.lang.invoke.MethodType"); |
duke@1 | 464 | errorType = enterClass("java.lang.Error"); |
duke@1 | 465 | illegalArgumentExceptionType = enterClass("java.lang.IllegalArgumentException"); |
mcimadamore@951 | 466 | interruptedExceptionType = enterClass("java.lang.InterruptedException"); |
duke@1 | 467 | exceptionType = enterClass("java.lang.Exception"); |
duke@1 | 468 | runtimeExceptionType = enterClass("java.lang.RuntimeException"); |
duke@1 | 469 | classNotFoundExceptionType = enterClass("java.lang.ClassNotFoundException"); |
duke@1 | 470 | noClassDefFoundErrorType = enterClass("java.lang.NoClassDefFoundError"); |
duke@1 | 471 | noSuchFieldErrorType = enterClass("java.lang.NoSuchFieldError"); |
duke@1 | 472 | assertionErrorType = enterClass("java.lang.AssertionError"); |
duke@1 | 473 | cloneNotSupportedExceptionType = enterClass("java.lang.CloneNotSupportedException"); |
duke@1 | 474 | annotationType = enterClass("java.lang.annotation.Annotation"); |
duke@1 | 475 | classLoaderType = enterClass("java.lang.ClassLoader"); |
duke@1 | 476 | enumSym = reader.enterClass(names.java_lang_Enum); |
duke@1 | 477 | enumFinalFinalize = |
duke@1 | 478 | new MethodSymbol(PROTECTED|FINAL|HYPOTHETICAL, |
duke@1 | 479 | names.finalize, |
duke@1 | 480 | new MethodType(List.<Type>nil(), voidType, |
duke@1 | 481 | List.<Type>nil(), methodClass), |
duke@1 | 482 | enumSym); |
duke@1 | 483 | listType = enterClass("java.util.List"); |
duke@1 | 484 | collectionsType = enterClass("java.util.Collections"); |
duke@1 | 485 | comparableType = enterClass("java.lang.Comparable"); |
duke@1 | 486 | arraysType = enterClass("java.util.Arrays"); |
jjg@86 | 487 | iterableType = target.hasIterable() |
duke@1 | 488 | ? enterClass("java.lang.Iterable") |
duke@1 | 489 | : enterClass("java.util.Collection"); |
duke@1 | 490 | iteratorType = enterClass("java.util.Iterator"); |
duke@1 | 491 | annotationTargetType = enterClass("java.lang.annotation.Target"); |
duke@1 | 492 | overrideType = enterClass("java.lang.Override"); |
duke@1 | 493 | retentionType = enterClass("java.lang.annotation.Retention"); |
duke@1 | 494 | deprecatedType = enterClass("java.lang.Deprecated"); |
duke@1 | 495 | suppressWarningsType = enterClass("java.lang.SuppressWarnings"); |
duke@1 | 496 | inheritedType = enterClass("java.lang.annotation.Inherited"); |
jfranck@1313 | 497 | containedByType = enterClass("java.lang.annotation.ContainedBy"); |
jfranck@1313 | 498 | containerForType = enterClass("java.lang.annotation.ContainerFor"); |
jfranck@1313 | 499 | documentedType = enterClass("java.lang.annotation.Documented"); |
jfranck@1313 | 500 | elementTypeType = enterClass("java.lang.annotation.ElementType"); |
jjg@86 | 501 | systemType = enterClass("java.lang.System"); |
darcy@609 | 502 | autoCloseableType = enterClass("java.lang.AutoCloseable"); |
darcy@609 | 503 | autoCloseableClose = new MethodSymbol(PUBLIC, |
darcy@609 | 504 | names.close, |
darcy@609 | 505 | new MethodType(List.<Type>nil(), voidType, |
darcy@609 | 506 | List.of(exceptionType), methodClass), |
darcy@609 | 507 | autoCloseableType.tsym); |
mcimadamore@795 | 508 | trustMeType = enterClass("java.lang.SafeVarargs"); |
jjg@1407 | 509 | nativeHeaderType = enterClass("java.lang.annotation.Native"); |
jjg@1407 | 510 | nativeHeaderType_old = enterClass("javax.tools.annotation.GenerateNativeHeader"); |
rfield@1380 | 511 | lambdaMetafactory = enterClass("java.lang.invoke.LambdaMetafactory"); |
jjg@86 | 512 | |
mcimadamore@951 | 513 | synthesizeEmptyInterfaceIfMissing(autoCloseableType); |
jjg@86 | 514 | synthesizeEmptyInterfaceIfMissing(cloneableType); |
jjg@86 | 515 | synthesizeEmptyInterfaceIfMissing(serializableType); |
rfield@1380 | 516 | synthesizeEmptyInterfaceIfMissing(lambdaMetafactory); |
jjg@86 | 517 | synthesizeBoxTypeIfMissing(doubleType); |
jjg@86 | 518 | synthesizeBoxTypeIfMissing(floatType); |
mcimadamore@357 | 519 | synthesizeBoxTypeIfMissing(voidType); |
duke@1 | 520 | |
jjg@582 | 521 | // Enter a synthetic class that is used to mark internal |
duke@1 | 522 | // proprietary classes in ct.sym. This class does not have a |
duke@1 | 523 | // class file. |
duke@1 | 524 | ClassType proprietaryType = (ClassType)enterClass("sun.Proprietary+Annotation"); |
duke@1 | 525 | this.proprietaryType = proprietaryType; |
duke@1 | 526 | ClassSymbol proprietarySymbol = (ClassSymbol)proprietaryType.tsym; |
duke@1 | 527 | proprietarySymbol.completer = null; |
duke@1 | 528 | proprietarySymbol.flags_field = PUBLIC|ACYCLIC|ANNOTATION|INTERFACE; |
duke@1 | 529 | proprietarySymbol.erasure_field = proprietaryType; |
mcimadamore@858 | 530 | proprietarySymbol.members_field = new Scope(proprietarySymbol); |
duke@1 | 531 | proprietaryType.typarams_field = List.nil(); |
duke@1 | 532 | proprietaryType.allparams_field = List.nil(); |
duke@1 | 533 | proprietaryType.supertype_field = annotationType; |
duke@1 | 534 | proprietaryType.interfaces_field = List.nil(); |
duke@1 | 535 | |
duke@1 | 536 | // Enter a class for arrays. |
duke@1 | 537 | // The class implements java.lang.Cloneable and java.io.Serializable. |
duke@1 | 538 | // It has a final length field and a clone method. |
duke@1 | 539 | ClassType arrayClassType = (ClassType)arrayClass.type; |
duke@1 | 540 | arrayClassType.supertype_field = objectType; |
duke@1 | 541 | arrayClassType.interfaces_field = List.of(cloneableType, serializableType); |
mcimadamore@858 | 542 | arrayClass.members_field = new Scope(arrayClass); |
duke@1 | 543 | lengthVar = new VarSymbol( |
duke@1 | 544 | PUBLIC | FINAL, |
duke@1 | 545 | names.length, |
duke@1 | 546 | intType, |
duke@1 | 547 | arrayClass); |
duke@1 | 548 | arrayClass.members().enter(lengthVar); |
duke@1 | 549 | arrayCloneMethod = new MethodSymbol( |
duke@1 | 550 | PUBLIC, |
duke@1 | 551 | names.clone, |
duke@1 | 552 | new MethodType(List.<Type>nil(), objectType, |
duke@1 | 553 | List.<Type>nil(), methodClass), |
duke@1 | 554 | arrayClass); |
duke@1 | 555 | arrayClass.members().enter(arrayCloneMethod); |
duke@1 | 556 | |
duke@1 | 557 | // Enter operators. |
duke@1 | 558 | enterUnop("+", doubleType, doubleType, nop); |
duke@1 | 559 | enterUnop("+", floatType, floatType, nop); |
duke@1 | 560 | enterUnop("+", longType, longType, nop); |
duke@1 | 561 | enterUnop("+", intType, intType, nop); |
duke@1 | 562 | |
duke@1 | 563 | enterUnop("-", doubleType, doubleType, dneg); |
duke@1 | 564 | enterUnop("-", floatType, floatType, fneg); |
duke@1 | 565 | enterUnop("-", longType, longType, lneg); |
duke@1 | 566 | enterUnop("-", intType, intType, ineg); |
duke@1 | 567 | |
duke@1 | 568 | enterUnop("~", longType, longType, lxor); |
duke@1 | 569 | enterUnop("~", intType, intType, ixor); |
duke@1 | 570 | |
duke@1 | 571 | enterUnop("++", doubleType, doubleType, dadd); |
duke@1 | 572 | enterUnop("++", floatType, floatType, fadd); |
duke@1 | 573 | enterUnop("++", longType, longType, ladd); |
duke@1 | 574 | enterUnop("++", intType, intType, iadd); |
duke@1 | 575 | enterUnop("++", charType, charType, iadd); |
duke@1 | 576 | enterUnop("++", shortType, shortType, iadd); |
duke@1 | 577 | enterUnop("++", byteType, byteType, iadd); |
duke@1 | 578 | |
duke@1 | 579 | enterUnop("--", doubleType, doubleType, dsub); |
duke@1 | 580 | enterUnop("--", floatType, floatType, fsub); |
duke@1 | 581 | enterUnop("--", longType, longType, lsub); |
duke@1 | 582 | enterUnop("--", intType, intType, isub); |
duke@1 | 583 | enterUnop("--", charType, charType, isub); |
duke@1 | 584 | enterUnop("--", shortType, shortType, isub); |
duke@1 | 585 | enterUnop("--", byteType, byteType, isub); |
duke@1 | 586 | |
duke@1 | 587 | enterUnop("!", booleanType, booleanType, bool_not); |
duke@1 | 588 | nullcheck = enterUnop("<*nullchk*>", objectType, objectType, nullchk); |
duke@1 | 589 | |
duke@1 | 590 | // string concatenation |
duke@1 | 591 | enterBinop("+", stringType, objectType, stringType, string_add); |
duke@1 | 592 | enterBinop("+", objectType, stringType, stringType, string_add); |
duke@1 | 593 | enterBinop("+", stringType, stringType, stringType, string_add); |
duke@1 | 594 | enterBinop("+", stringType, intType, stringType, string_add); |
duke@1 | 595 | enterBinop("+", stringType, longType, stringType, string_add); |
duke@1 | 596 | enterBinop("+", stringType, floatType, stringType, string_add); |
duke@1 | 597 | enterBinop("+", stringType, doubleType, stringType, string_add); |
duke@1 | 598 | enterBinop("+", stringType, booleanType, stringType, string_add); |
duke@1 | 599 | enterBinop("+", stringType, botType, stringType, string_add); |
duke@1 | 600 | enterBinop("+", intType, stringType, stringType, string_add); |
duke@1 | 601 | enterBinop("+", longType, stringType, stringType, string_add); |
duke@1 | 602 | enterBinop("+", floatType, stringType, stringType, string_add); |
duke@1 | 603 | enterBinop("+", doubleType, stringType, stringType, string_add); |
duke@1 | 604 | enterBinop("+", booleanType, stringType, stringType, string_add); |
duke@1 | 605 | enterBinop("+", botType, stringType, stringType, string_add); |
duke@1 | 606 | |
duke@1 | 607 | // these errors would otherwise be matched as string concatenation |
duke@1 | 608 | enterBinop("+", botType, botType, botType, error); |
duke@1 | 609 | enterBinop("+", botType, intType, botType, error); |
duke@1 | 610 | enterBinop("+", botType, longType, botType, error); |
duke@1 | 611 | enterBinop("+", botType, floatType, botType, error); |
duke@1 | 612 | enterBinop("+", botType, doubleType, botType, error); |
duke@1 | 613 | enterBinop("+", botType, booleanType, botType, error); |
duke@1 | 614 | enterBinop("+", botType, objectType, botType, error); |
duke@1 | 615 | enterBinop("+", intType, botType, botType, error); |
duke@1 | 616 | enterBinop("+", longType, botType, botType, error); |
duke@1 | 617 | enterBinop("+", floatType, botType, botType, error); |
duke@1 | 618 | enterBinop("+", doubleType, botType, botType, error); |
duke@1 | 619 | enterBinop("+", booleanType, botType, botType, error); |
duke@1 | 620 | enterBinop("+", objectType, botType, botType, error); |
duke@1 | 621 | |
duke@1 | 622 | enterBinop("+", doubleType, doubleType, doubleType, dadd); |
duke@1 | 623 | enterBinop("+", floatType, floatType, floatType, fadd); |
duke@1 | 624 | enterBinop("+", longType, longType, longType, ladd); |
duke@1 | 625 | enterBinop("+", intType, intType, intType, iadd); |
duke@1 | 626 | |
duke@1 | 627 | enterBinop("-", doubleType, doubleType, doubleType, dsub); |
duke@1 | 628 | enterBinop("-", floatType, floatType, floatType, fsub); |
duke@1 | 629 | enterBinop("-", longType, longType, longType, lsub); |
duke@1 | 630 | enterBinop("-", intType, intType, intType, isub); |
duke@1 | 631 | |
duke@1 | 632 | enterBinop("*", doubleType, doubleType, doubleType, dmul); |
duke@1 | 633 | enterBinop("*", floatType, floatType, floatType, fmul); |
duke@1 | 634 | enterBinop("*", longType, longType, longType, lmul); |
duke@1 | 635 | enterBinop("*", intType, intType, intType, imul); |
duke@1 | 636 | |
duke@1 | 637 | enterBinop("/", doubleType, doubleType, doubleType, ddiv); |
duke@1 | 638 | enterBinop("/", floatType, floatType, floatType, fdiv); |
duke@1 | 639 | enterBinop("/", longType, longType, longType, ldiv); |
duke@1 | 640 | enterBinop("/", intType, intType, intType, idiv); |
duke@1 | 641 | |
duke@1 | 642 | enterBinop("%", doubleType, doubleType, doubleType, dmod); |
duke@1 | 643 | enterBinop("%", floatType, floatType, floatType, fmod); |
duke@1 | 644 | enterBinop("%", longType, longType, longType, lmod); |
duke@1 | 645 | enterBinop("%", intType, intType, intType, imod); |
duke@1 | 646 | |
duke@1 | 647 | enterBinop("&", booleanType, booleanType, booleanType, iand); |
duke@1 | 648 | enterBinop("&", longType, longType, longType, land); |
duke@1 | 649 | enterBinop("&", intType, intType, intType, iand); |
duke@1 | 650 | |
duke@1 | 651 | enterBinop("|", booleanType, booleanType, booleanType, ior); |
duke@1 | 652 | enterBinop("|", longType, longType, longType, lor); |
duke@1 | 653 | enterBinop("|", intType, intType, intType, ior); |
duke@1 | 654 | |
duke@1 | 655 | enterBinop("^", booleanType, booleanType, booleanType, ixor); |
duke@1 | 656 | enterBinop("^", longType, longType, longType, lxor); |
duke@1 | 657 | enterBinop("^", intType, intType, intType, ixor); |
duke@1 | 658 | |
duke@1 | 659 | enterBinop("<<", longType, longType, longType, lshll); |
duke@1 | 660 | enterBinop("<<", intType, longType, intType, ishll); |
duke@1 | 661 | enterBinop("<<", longType, intType, longType, lshl); |
duke@1 | 662 | enterBinop("<<", intType, intType, intType, ishl); |
duke@1 | 663 | |
duke@1 | 664 | enterBinop(">>", longType, longType, longType, lshrl); |
duke@1 | 665 | enterBinop(">>", intType, longType, intType, ishrl); |
duke@1 | 666 | enterBinop(">>", longType, intType, longType, lshr); |
duke@1 | 667 | enterBinop(">>", intType, intType, intType, ishr); |
duke@1 | 668 | |
duke@1 | 669 | enterBinop(">>>", longType, longType, longType, lushrl); |
duke@1 | 670 | enterBinop(">>>", intType, longType, intType, iushrl); |
duke@1 | 671 | enterBinop(">>>", longType, intType, longType, lushr); |
duke@1 | 672 | enterBinop(">>>", intType, intType, intType, iushr); |
duke@1 | 673 | |
duke@1 | 674 | enterBinop("<", doubleType, doubleType, booleanType, dcmpg, iflt); |
duke@1 | 675 | enterBinop("<", floatType, floatType, booleanType, fcmpg, iflt); |
duke@1 | 676 | enterBinop("<", longType, longType, booleanType, lcmp, iflt); |
duke@1 | 677 | enterBinop("<", intType, intType, booleanType, if_icmplt); |
duke@1 | 678 | |
duke@1 | 679 | enterBinop(">", doubleType, doubleType, booleanType, dcmpl, ifgt); |
duke@1 | 680 | enterBinop(">", floatType, floatType, booleanType, fcmpl, ifgt); |
duke@1 | 681 | enterBinop(">", longType, longType, booleanType, lcmp, ifgt); |
duke@1 | 682 | enterBinop(">", intType, intType, booleanType, if_icmpgt); |
duke@1 | 683 | |
duke@1 | 684 | enterBinop("<=", doubleType, doubleType, booleanType, dcmpg, ifle); |
duke@1 | 685 | enterBinop("<=", floatType, floatType, booleanType, fcmpg, ifle); |
duke@1 | 686 | enterBinop("<=", longType, longType, booleanType, lcmp, ifle); |
duke@1 | 687 | enterBinop("<=", intType, intType, booleanType, if_icmple); |
duke@1 | 688 | |
duke@1 | 689 | enterBinop(">=", doubleType, doubleType, booleanType, dcmpl, ifge); |
duke@1 | 690 | enterBinop(">=", floatType, floatType, booleanType, fcmpl, ifge); |
duke@1 | 691 | enterBinop(">=", longType, longType, booleanType, lcmp, ifge); |
duke@1 | 692 | enterBinop(">=", intType, intType, booleanType, if_icmpge); |
duke@1 | 693 | |
duke@1 | 694 | enterBinop("==", objectType, objectType, booleanType, if_acmpeq); |
duke@1 | 695 | enterBinop("==", booleanType, booleanType, booleanType, if_icmpeq); |
duke@1 | 696 | enterBinop("==", doubleType, doubleType, booleanType, dcmpl, ifeq); |
duke@1 | 697 | enterBinop("==", floatType, floatType, booleanType, fcmpl, ifeq); |
duke@1 | 698 | enterBinop("==", longType, longType, booleanType, lcmp, ifeq); |
duke@1 | 699 | enterBinop("==", intType, intType, booleanType, if_icmpeq); |
duke@1 | 700 | |
duke@1 | 701 | enterBinop("!=", objectType, objectType, booleanType, if_acmpne); |
duke@1 | 702 | enterBinop("!=", booleanType, booleanType, booleanType, if_icmpne); |
duke@1 | 703 | enterBinop("!=", doubleType, doubleType, booleanType, dcmpl, ifne); |
duke@1 | 704 | enterBinop("!=", floatType, floatType, booleanType, fcmpl, ifne); |
duke@1 | 705 | enterBinop("!=", longType, longType, booleanType, lcmp, ifne); |
duke@1 | 706 | enterBinop("!=", intType, intType, booleanType, if_icmpne); |
duke@1 | 707 | |
duke@1 | 708 | enterBinop("&&", booleanType, booleanType, booleanType, bool_and); |
duke@1 | 709 | enterBinop("||", booleanType, booleanType, booleanType, bool_or); |
duke@1 | 710 | } |
duke@1 | 711 | } |