< prev index next >

src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java

Print this page




  53 import com.sun.tools.javac.code.Type.*;
  54 import com.sun.tools.javac.comp.Attr;
  55 import com.sun.tools.javac.comp.AttrContext;
  56 import com.sun.tools.javac.comp.Env;
  57 import com.sun.tools.javac.jvm.*;
  58 import com.sun.tools.javac.jvm.PoolConstant;
  59 import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
  60 import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
  61 import com.sun.tools.javac.tree.JCTree.Tag;
  62 import com.sun.tools.javac.util.*;
  63 import com.sun.tools.javac.util.DefinedBy.Api;
  64 import com.sun.tools.javac.util.Name;
  65 
  66 import static com.sun.tools.javac.code.Flags.*;
  67 import static com.sun.tools.javac.code.Kinds.*;
  68 import static com.sun.tools.javac.code.Kinds.Kind.*;
  69 import com.sun.tools.javac.code.MissingInfoHandler;
  70 import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
  71 import com.sun.tools.javac.code.Scope.WriteableScope;
  72 import com.sun.tools.javac.code.Symbol;
  73 import static com.sun.tools.javac.code.Symbol.OperatorSymbol.AccessCode.FIRSTASGOP;
  74 import com.sun.tools.javac.code.Type;
  75 import static com.sun.tools.javac.code.TypeTag.CLASS;
  76 import static com.sun.tools.javac.code.TypeTag.FORALL;
  77 import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
  78 import static com.sun.tools.javac.jvm.ByteCodes.iadd;
  79 import static com.sun.tools.javac.jvm.ByteCodes.ishll;
  80 import static com.sun.tools.javac.jvm.ByteCodes.lushrl;
  81 import static com.sun.tools.javac.jvm.ByteCodes.lxor;
  82 import static com.sun.tools.javac.jvm.ByteCodes.string_add;
  83 import com.sun.tools.javac.util.Name;
  84 
  85 /** Root class for Java symbols. It contains subclasses
  86  *  for specific sorts of symbols, such as variables, methods and operators,
  87  *  types, packages. Each subclass is represented as a static inner class
  88  *  inside Symbol.
  89  *
  90  *  <p><b>This is NOT part of any supported API.
  91  *  If you write code that depends on this, you do so at your own risk.
  92  *  This code and its internal interfaces are subject to change or
  93  *  deletion without notice.</b>


 282         this.flags_field = flags;
 283         this.type = type;
 284         this.owner = owner;
 285         this.completer = Completer.NULL_COMPLETER;
 286         this.erasure_field = null;
 287         this.name = name;
 288     }
 289 
 290     @Override
 291     public int poolTag() {
 292         throw new AssertionError("Invalid pool entry");
 293     }
 294 
 295     /** Clone this symbol with new owner.
 296      *  Legal only for fields and methods.
 297      */
 298     public Symbol clone(Symbol newOwner) {
 299         throw new AssertionError();
 300     }
 301 








 302     public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
 303         return v.visitSymbol(this, p);
 304     }
 305 
 306     /** The Java source which this symbol represents.
 307      *  A description of this symbol; overrides Object.
 308      */
 309     public String toString() {
 310         return name.toString();
 311     }
 312 
 313     /** A Java source description of the location of this symbol; used for
 314      *  error reporting.
 315      *
 316      * @return null if the symbol is a package or a toplevel class defined in
 317      * the default package; otherwise, the owner symbol is returned
 318      */
 319     public Symbol location() {
 320         if (owner.name == null || (owner.name.isEmpty() &&
 321                                    (owner.flags() & BLOCK) == 0 &&


 389             default:
 390                 return true;
 391         }
 392     }
 393 
 394     public boolean isStatic() {
 395         return
 396             (flags() & STATIC) != 0 ||
 397             (owner.flags() & INTERFACE) != 0 && kind != MTH &&
 398              name != name.table.names._this;
 399     }
 400 
 401     public boolean isInterface() {
 402         return (flags() & INTERFACE) != 0;
 403     }
 404 
 405     public boolean isPrivate() {
 406         return (flags_field & Flags.AccessFlags) == PRIVATE;
 407     }
 408 




 409     public boolean isEnum() {
 410         return (flags() & ENUM) != 0;
 411     }
 412 
 413     /** Is this symbol declared (directly or indirectly) local
 414      *  to a method or variable initializer?
 415      *  Also includes fields of inner classes which are in
 416      *  turn local to a method or variable initializer.
 417      */
 418     public boolean isLocal() {
 419         return
 420             (owner.kind.matches(KindSelector.VAL_MTH) ||
 421              (owner.kind == TYP && owner.isLocal()));
 422     }
 423 
 424     /** Has this symbol an empty name? This includes anonymous
 425      *  inner classes.
 426      */
 427     public boolean isAnonymous() {
 428         return name.isEmpty();
 429     }
 430 
 431     /** Is this symbol a constructor?
 432      */
 433     public boolean isConstructor() {
 434         return name == name.table.names.init;






 435     }
 436 
 437     public boolean isDynamic() {
 438         return false;
 439     }
 440 
 441     /** The fully qualified name of this symbol.
 442      *  This is the same as the symbol's name except for class symbols,
 443      *  which are handled separately.
 444      */
 445     public Name getQualifiedName() {
 446         return name;
 447     }
 448 
 449     /** The fully qualified name of this symbol after converting to flat
 450      *  representation. This is the same as the symbol's name except for
 451      *  class symbols, which are handled separately.
 452      */
 453     public Name flatName() {
 454         return getQualifiedName();


1302         }
1303 
1304         @Override
1305         public List<Attribute.TypeCompound> getRawTypeAttributes() {
1306             complete();
1307             return super.getRawTypeAttributes();
1308         }
1309 
1310         public Type erasure(Types types) {
1311             if (erasure_field == null)
1312                 erasure_field = new ClassType(types.erasure(type.getEnclosingType()),
1313                                               List.nil(), this,
1314                                               type.getMetadata());
1315             return erasure_field;
1316         }
1317 
1318         public String className() {
1319             if (name.isEmpty())
1320                 return
1321                     Log.getLocalizedString("anonymous.class", flatname);
1322             else
1323                 return fullname.toString();

1324         }
1325 
1326         @DefinedBy(Api.LANGUAGE_MODEL)
1327         public Name getQualifiedName() {
1328             return fullname;
1329         }
1330 
1331         public Name flatName() {
1332             return flatname;
1333         }
1334 
1335         public boolean isSubClass(Symbol base, Types types) {
1336             if (this == base) {
1337                 return true;
1338             } else if ((base.flags() & INTERFACE) != 0) {
1339                 for (Type t = type; t.hasTag(CLASS); t = types.supertype(t))
1340                     for (List<Type> is = types.interfaces(t);
1341                          is.nonEmpty();
1342                          is = is.tail)
1343                         if (is.head.tsym.isSubClass(base, types)) return true;


2232         private int accessCode = Integer.MIN_VALUE;
2233 
2234         public OperatorSymbol(Name name, Type type, int opcode, Symbol owner) {
2235             super(PUBLIC | STATIC, name, type, owner);
2236             this.opcode = opcode;
2237         }
2238 
2239         @Override
2240         public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
2241             return v.visitOperatorSymbol(this, p);
2242         }
2243 
2244         public int getAccessCode(Tag tag) {
2245             if (accessCode != Integer.MIN_VALUE && !tag.isIncOrDecUnaryOp()) {
2246                 return accessCode;
2247             }
2248             accessCode = AccessCode.from(tag, opcode);
2249             return accessCode;
2250         }
2251 
2252         /** Access codes for dereferencing, assignment,
2253          *  and pre/post increment/decrement.
2254 
2255          *  All access codes for accesses to the current class are even.
2256          *  If a member of the superclass should be accessed instead (because
2257          *  access was via a qualified super), add one to the corresponding code
2258          *  for the current class, making the number odd.
2259          *  This numbering scheme is used by the backend to decide whether
2260          *  to issue an invokevirtual or invokespecial call.
2261          *
2262          *  @see Gen#visitSelect(JCFieldAccess tree)
2263          */
2264         public enum AccessCode {
2265             UNKNOWN(-1, Tag.NO_TAG),
2266             DEREF(0, Tag.NO_TAG),
2267             ASSIGN(2, Tag.ASSIGN),
2268             PREINC(4, Tag.PREINC),
2269             PREDEC(6, Tag.PREDEC),
2270             POSTINC(8, Tag.POSTINC),
2271             POSTDEC(10, Tag.POSTDEC),
2272             FIRSTASGOP(12, Tag.NO_TAG);

2273 
2274             public final int code;
2275             public final Tag tag;
2276             public static final int numberOfAccessCodes = (lushrl - ishll + lxor + 2 - iadd) * 2 + FIRSTASGOP.code + 2;
2277 
2278             AccessCode(int code, Tag tag) {
2279                 this.code = code;
2280                 this.tag = tag;
2281             }
2282 
2283             static public AccessCode getFromCode(int code) {
2284                 for (AccessCode aCodes : AccessCode.values()) {
2285                     if (aCodes.code == code) {
2286                         return aCodes;
2287                     }
2288                 }
2289                 return UNKNOWN;
2290             }
2291 
2292             static int from(Tag tag, int opcode) {
2293                 /** Map bytecode of binary operation to access code of corresponding
2294                 *  assignment operation. This is always an even number.
2295                 */
2296                 switch (tag) {
2297                     case PREINC:
2298                         return AccessCode.PREINC.code;
2299                     case PREDEC:
2300                         return AccessCode.PREDEC.code;
2301                     case POSTINC:
2302                         return AccessCode.POSTINC.code;
2303                     case POSTDEC:
2304                         return AccessCode.POSTDEC.code;


2305                 }
2306                 if (iadd <= opcode && opcode <= lxor) {
2307                     return (opcode - iadd) * 2 + FIRSTASGOP.code;
2308                 } else if (opcode == string_add) {
2309                     return (lxor + 1 - iadd) * 2 + FIRSTASGOP.code;
2310                 } else if (ishll <= opcode && opcode <= lushrl) {
2311                     return (opcode - ishll + lxor + 2 - iadd) * 2 + FIRSTASGOP.code;
2312                 }
2313                 return -1;
2314             }
2315         }
2316     }
2317 
2318     /** Symbol completer interface.
2319      */
2320     public static interface Completer {
2321 
2322         /** Dummy completer to be used when the symbol has been completed or
2323          * does not need completion.
2324          */




  53 import com.sun.tools.javac.code.Type.*;
  54 import com.sun.tools.javac.comp.Attr;
  55 import com.sun.tools.javac.comp.AttrContext;
  56 import com.sun.tools.javac.comp.Env;
  57 import com.sun.tools.javac.jvm.*;
  58 import com.sun.tools.javac.jvm.PoolConstant;
  59 import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
  60 import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
  61 import com.sun.tools.javac.tree.JCTree.Tag;
  62 import com.sun.tools.javac.util.*;
  63 import com.sun.tools.javac.util.DefinedBy.Api;
  64 import com.sun.tools.javac.util.Name;
  65 
  66 import static com.sun.tools.javac.code.Flags.*;
  67 import static com.sun.tools.javac.code.Kinds.*;
  68 import static com.sun.tools.javac.code.Kinds.Kind.*;
  69 import com.sun.tools.javac.code.MissingInfoHandler;
  70 import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
  71 import com.sun.tools.javac.code.Scope.WriteableScope;
  72 import com.sun.tools.javac.code.Symbol;

  73 import com.sun.tools.javac.code.Type;
  74 import static com.sun.tools.javac.code.TypeTag.CLASS;
  75 import static com.sun.tools.javac.code.TypeTag.FORALL;
  76 import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
  77 import static com.sun.tools.javac.jvm.ByteCodes.iadd;
  78 import static com.sun.tools.javac.jvm.ByteCodes.ishll;
  79 import static com.sun.tools.javac.jvm.ByteCodes.lushrl;
  80 import static com.sun.tools.javac.jvm.ByteCodes.lxor;
  81 import static com.sun.tools.javac.jvm.ByteCodes.string_add;
  82 import com.sun.tools.javac.util.Name;
  83 
  84 /** Root class for Java symbols. It contains subclasses
  85  *  for specific sorts of symbols, such as variables, methods and operators,
  86  *  types, packages. Each subclass is represented as a static inner class
  87  *  inside Symbol.
  88  *
  89  *  <p><b>This is NOT part of any supported API.
  90  *  If you write code that depends on this, you do so at your own risk.
  91  *  This code and its internal interfaces are subject to change or
  92  *  deletion without notice.</b>


 281         this.flags_field = flags;
 282         this.type = type;
 283         this.owner = owner;
 284         this.completer = Completer.NULL_COMPLETER;
 285         this.erasure_field = null;
 286         this.name = name;
 287     }
 288 
 289     @Override
 290     public int poolTag() {
 291         throw new AssertionError("Invalid pool entry");
 292     }
 293 
 294     /** Clone this symbol with new owner.
 295      *  Legal only for fields and methods.
 296      */
 297     public Symbol clone(Symbol newOwner) {
 298         throw new AssertionError();
 299     }
 300 
 301     public boolean isProjectedNullable() {
 302         return false;
 303     }
 304 
 305     public ClassSymbol nullFreeTypeSymbol() {
 306         return this.type.hasTag(CLASS) && ((this.flags() & VALUE) != 0) ? (ClassSymbol) this : null;
 307     }
 308 
 309     public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
 310         return v.visitSymbol(this, p);
 311     }
 312 
 313     /** The Java source which this symbol represents.
 314      *  A description of this symbol; overrides Object.
 315      */
 316     public String toString() {
 317         return name.toString();
 318     }
 319 
 320     /** A Java source description of the location of this symbol; used for
 321      *  error reporting.
 322      *
 323      * @return null if the symbol is a package or a toplevel class defined in
 324      * the default package; otherwise, the owner symbol is returned
 325      */
 326     public Symbol location() {
 327         if (owner.name == null || (owner.name.isEmpty() &&
 328                                    (owner.flags() & BLOCK) == 0 &&


 396             default:
 397                 return true;
 398         }
 399     }
 400 
 401     public boolean isStatic() {
 402         return
 403             (flags() & STATIC) != 0 ||
 404             (owner.flags() & INTERFACE) != 0 && kind != MTH &&
 405              name != name.table.names._this;
 406     }
 407 
 408     public boolean isInterface() {
 409         return (flags() & INTERFACE) != 0;
 410     }
 411 
 412     public boolean isPrivate() {
 413         return (flags_field & Flags.AccessFlags) == PRIVATE;
 414     }
 415 
 416     public boolean isValue() {
 417         return (flags() & VALUE) != 0;
 418     }
 419 
 420     public boolean isEnum() {
 421         return (flags() & ENUM) != 0;
 422     }
 423 
 424     /** Is this symbol declared (directly or indirectly) local
 425      *  to a method or variable initializer?
 426      *  Also includes fields of inner classes which are in
 427      *  turn local to a method or variable initializer.
 428      */
 429     public boolean isLocal() {
 430         return
 431             (owner.kind.matches(KindSelector.VAL_MTH) ||
 432              (owner.kind == TYP && owner.isLocal()));
 433     }
 434 
 435     /** Has this symbol an empty name? This includes anonymous
 436      *  inner classes.
 437      */
 438     public boolean isAnonymous() {
 439         return name.isEmpty();
 440     }
 441 
 442     /** Is this symbol a constructor?
 443      */
 444     public boolean isConstructor() {
 445         return name == name.table.names.init && (flags() & STATIC) == 0;
 446     }
 447 
 448     /** Is this symbol a value factory?
 449      */
 450     public boolean isValueFactory() {
 451         return ((name == name.table.names.init && this.type.getReturnType().tsym == this.owner));
 452     }
 453 
 454     public boolean isDynamic() {
 455         return false;
 456     }
 457 
 458     /** The fully qualified name of this symbol.
 459      *  This is the same as the symbol's name except for class symbols,
 460      *  which are handled separately.
 461      */
 462     public Name getQualifiedName() {
 463         return name;
 464     }
 465 
 466     /** The fully qualified name of this symbol after converting to flat
 467      *  representation. This is the same as the symbol's name except for
 468      *  class symbols, which are handled separately.
 469      */
 470     public Name flatName() {
 471         return getQualifiedName();


1319         }
1320 
1321         @Override
1322         public List<Attribute.TypeCompound> getRawTypeAttributes() {
1323             complete();
1324             return super.getRawTypeAttributes();
1325         }
1326 
1327         public Type erasure(Types types) {
1328             if (erasure_field == null)
1329                 erasure_field = new ClassType(types.erasure(type.getEnclosingType()),
1330                                               List.nil(), this,
1331                                               type.getMetadata());
1332             return erasure_field;
1333         }
1334 
1335         public String className() {
1336             if (name.isEmpty())
1337                 return
1338                     Log.getLocalizedString("anonymous.class", flatname);
1339 
1340                 String s = fullname.toString();
1341                 return isProjectedNullable() ? s + '?' : s;
1342         }
1343 
1344         @DefinedBy(Api.LANGUAGE_MODEL)
1345         public Name getQualifiedName() {
1346             return fullname;
1347         }
1348 
1349         public Name flatName() {
1350             return flatname;
1351         }
1352 
1353         public boolean isSubClass(Symbol base, Types types) {
1354             if (this == base) {
1355                 return true;
1356             } else if ((base.flags() & INTERFACE) != 0) {
1357                 for (Type t = type; t.hasTag(CLASS); t = types.supertype(t))
1358                     for (List<Type> is = types.interfaces(t);
1359                          is.nonEmpty();
1360                          is = is.tail)
1361                         if (is.head.tsym.isSubClass(base, types)) return true;


2250         private int accessCode = Integer.MIN_VALUE;
2251 
2252         public OperatorSymbol(Name name, Type type, int opcode, Symbol owner) {
2253             super(PUBLIC | STATIC, name, type, owner);
2254             this.opcode = opcode;
2255         }
2256 
2257         @Override
2258         public <R, P> R accept(Symbol.Visitor<R, P> v, P p) {
2259             return v.visitOperatorSymbol(this, p);
2260         }
2261 
2262         public int getAccessCode(Tag tag) {
2263             if (accessCode != Integer.MIN_VALUE && !tag.isIncOrDecUnaryOp()) {
2264                 return accessCode;
2265             }
2266             accessCode = AccessCode.from(tag, opcode);
2267             return accessCode;
2268         }
2269 
2270         /** Access codes for dereferencing, assignment, withfield
2271          *  and pre/post increment/decrement.
2272 
2273          *  All access codes for accesses to the current class are even.
2274          *  If a member of the superclass should be accessed instead (because
2275          *  access was via a qualified super), add one to the corresponding code
2276          *  for the current class, making the number odd.
2277          *  This numbering scheme is used by the backend to decide whether
2278          *  to issue an invokevirtual or invokespecial call.
2279          *
2280          *  @see Gen#visitSelect(JCFieldAccess tree)
2281          */
2282         public enum AccessCode {
2283             UNKNOWN(-1, Tag.NO_TAG),
2284             DEREF(0, Tag.NO_TAG),
2285             ASSIGN(2, Tag.ASSIGN),
2286             PREINC(4, Tag.PREINC),
2287             PREDEC(6, Tag.PREDEC),
2288             POSTINC(8, Tag.POSTINC),
2289             POSTDEC(10, Tag.POSTDEC),
2290             WITHFIELD(12, Tag.WITHFIELD),
2291             FIRSTASGOP(14, Tag.NO_TAG);
2292 
2293             public final int code;
2294             public final Tag tag;
2295             public static final int numberOfAccessCodes = (lushrl - ishll + lxor + 2 - iadd) * 2 + FIRSTASGOP.code + 2;
2296 
2297             AccessCode(int code, Tag tag) {
2298                 this.code = code;
2299                 this.tag = tag;
2300             }
2301 
2302             static public AccessCode getFromCode(int code) {
2303                 for (AccessCode aCodes : AccessCode.values()) {
2304                     if (aCodes.code == code) {
2305                         return aCodes;
2306                     }
2307                 }
2308                 return UNKNOWN;
2309             }
2310 
2311             static int from(Tag tag, int opcode) {
2312                 /** Map bytecode of binary operation to access code of corresponding
2313                 *  assignment operation. This is always an even number.
2314                 */
2315                 switch (tag) {
2316                     case PREINC:
2317                         return AccessCode.PREINC.code;
2318                     case PREDEC:
2319                         return AccessCode.PREDEC.code;
2320                     case POSTINC:
2321                         return AccessCode.POSTINC.code;
2322                     case POSTDEC:
2323                         return AccessCode.POSTDEC.code;
2324                     case WITHFIELD:
2325                         return AccessCode.WITHFIELD.code;
2326                 }
2327                 if (iadd <= opcode && opcode <= lxor) {
2328                     return (opcode - iadd) * 2 + FIRSTASGOP.code;
2329                 } else if (opcode == string_add) {
2330                     return (lxor + 1 - iadd) * 2 + FIRSTASGOP.code;
2331                 } else if (ishll <= opcode && opcode <= lushrl) {
2332                     return (opcode - ishll + lxor + 2 - iadd) * 2 + FIRSTASGOP.code;
2333                 }
2334                 return -1;
2335             }
2336         }
2337     }
2338 
2339     /** Symbol completer interface.
2340      */
2341     public static interface Completer {
2342 
2343         /** Dummy completer to be used when the symbol has been completed or
2344          * does not need completion.
2345          */


< prev index next >