📄 symbol.java
字号:
/**
* @(#)Symbol.java 1.45 03/01/23
*
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.sun.tools.javac.v8.code;
import com.sun.tools.javac.v8.util.*;
import com.sun.tools.javac.v8.code.Type.*;
/**
* Root class for Java symbols. It contains subclasses
* for specific sorts of symbols, such as variables, methods and operators,
* types, packages. Each subclass is represented as a static inner class
* inside Symbol.
*/
public class Symbol implements Flags, Kinds, TypeTags {
/**
* The kind of this symbol.
* @see Kinds.
*/
public int kind;
/**
* The flags of this symbol.
*/
public long flags_field;
/**
* An accessor method for the flags of this symbol.
* Flags of class symbols should be accessed through the accessor
* method to make sure that the class symbol is loaded.
*/
public long flags() {
return flags_field;
}
/**
* The name of this symbol in Utf8 representation.
*/
public Name name;
/**
* The type of this symbol.
*/
public Type type;
/**
* The owner of this symbol.
*/
public Symbol owner;
/**
* The completer of this symbol.
*/
public Completer completer;
/**
* A cache for the type erasure of this symbol.
*/
public Type erasure_field;
/**
* Construct a symbol with given kind, flags, name, type and owner.
*/
public Symbol(int kind, long flags, Name name, Type type, Symbol owner) {
super();
this.kind = kind;
this.flags_field = flags;
this.type = type;
this.owner = owner;
this.completer = null;
this.erasure_field = null;
this.name = name;
}
/**
* Clone this symbol with new owner.
* Legal only for fields and methods.
*/
public Symbol clone(Symbol newOwner) {
throw new AssertionError();
}
/**
* A description of this symbol; overrides Object.
*/
public String toString() {
return name.toString();
}
/**
* The Java source which this symbol represents. Use of this method will
* result in a loss of the plain-language description for the symbol.
*/
public String toJava() {
return name.toString();
}
/**
* A description of the location of this symbol; used for
* error reporting.
*
* XXX 06/09/99 iris
* This method appears to be redundant and should probably be
* unified with javaLocation();
*/
public String location() {
if (owner.name == null || owner.name.len == 0)
return "";
else
return " in " + owner;
}
public String location(Type site) {
if (owner.name == null || owner.name.len == 0) {
return "";
}
if (owner.type.tag == CLASS) {
Type ownertype = site.asOuterSuper(owner);
if (ownertype != null)
return " in class " + ownertype;
}
return " in " + owner;
}
/**
* A Java source description of the location of this symbol; used for
* error reporting. Use of this method may result in the loss of the
* symbol's description.
*/
public String javaLocation() {
if (owner.name == null || owner.name.len == 0)
return "";
else
return owner.toJava();
}
public String javaLocation(Type site) {
if (owner.name == null || owner.name.len == 0) {
return "";
}
if (owner.type.tag == CLASS) {
Type ownertype = site.asOuterSuper(owner);
if (ownertype != null)
return ownertype.toJava();
}
return owner.toJava();
}
/**
* The symbol's erased type.
*/
public Type erasure() {
if (erasure_field == null)
erasure_field = type.erasure();
return erasure_field;
}
/**
* The external type of a symbol. This is the symbol's erased type
* except for constructors of inner classes which get the enclosing
* instance class added as first argument.
*/
public Type externalType() {
Type t = erasure();
if (name == name.table.init && owner.hasOuterInstance()) {
Type outerThisType = owner.type.outer().erasure();
return new MethodType(t.argtypes().prepend(outerThisType),
t.restype(), t.thrown(), t.tsym);
} else {
return t;
}
}
/**
* Is this symbol declared (directly or indirectly) local
* to a method or variable initializer?
* Also includes fields of inner classes which are in
* turn local to a method or variable initializer.
*/
public boolean isLocal() {
return (owner.kind & (VAR | MTH)) != 0 ||
(owner.kind == TYP && owner.isLocal());
}
/**
* Is this symbol a constructor?
*/
public boolean isConstructor() {
return name == name.table.init;
}
/**
* The fully qualified name of this symbol.
* This is the same as the symbol's name except for class symbols,
* which are handled separately.
*/
public Name fullName() {
return name;
}
/**
* The fully qualified name of this symbol after converting to flat
* representation. This is the same as the symbol's name except for
* class symbols, which are handled separately.
*/
public Name flatName() {
return fullName();
}
/**
* If this is a class or package, its members, otherwise null.
*/
public Scope members() {
return null;
}
/**
* A class is an inner class if it it has an enclosing instance class.
*/
public boolean isInner() {
return type.outer().tag == CLASS;
}
/**
* An inner class has an outer instance if it is not an interface
* it has an enclosing instance class which might be referenced from the class.
* Nested classes can see instance members of their enclosing class.
* Their constructors carry an additional this$n parameter, inserted
* implicitly by the compiler.
*
* @see isInner
*/
public boolean hasOuterInstance() {
return type.outer().tag == CLASS &&
(flags() & (INTERFACE | NOOUTERTHIS)) == 0;
}
/**
* The closest enclosing class of this symbol's declaration.
*/
public ClassSymbol enclClass() {
Symbol c = this;
while (c != null && (c.kind & TYP) == 0)
c = c.owner;
return (ClassSymbol) c;
}
/**
* The outermost class which indirectly owns this symbol.
*/
public ClassSymbol outermostClass() {
Symbol sym = this;
Symbol prev = null;
while (sym.kind != PCK) {
prev = sym;
sym = sym.owner;
}
return (ClassSymbol) prev;
}
/**
* The package which indirectly owns this symbol.
*/
public PackageSymbol packge() {
Symbol sym = this;
while (sym.kind != PCK) {
sym = sym.owner;
}
return (PackageSymbol) sym;
}
/**
* Is this symbol a subclass of `base'? Only defined for ClassSymbols.
*/
public boolean isSubClass(Symbol base) {
throw new AssertionError("isSubClass " + this);
}
/**
* Fully check membership: hierarchy, protection, and hiding.
* Does not exclude methods not inherited due to overriding.
*/
public boolean isMemberOf(TypeSymbol clazz) {
return owner == clazz || clazz.isSubClass(owner) && isInheritedIn(clazz) &&
(kind == MTH || !hiddenIn((ClassSymbol) clazz));
}
/**
* Is this symbol the same as or enclosed by the given class?
*/
public boolean isEnclosedBy(ClassSymbol clazz) {
for (Symbol sym = this; sym.kind != PCK; sym = sym.owner)
if (sym == clazz)
return true;
return false;
}
/**
* Check for hiding. Note that this doesn't handle multiple
* (interface) inheritance.
*/
private boolean hiddenIn(ClassSymbol clazz) {
while (true) {
if (owner == clazz)
return false;
Scope.Entry e = clazz.members().lookup(name);
while (e.scope != null) {
if (e.sym.kind == kind)
return e.sym != this;
e = e.next();
}
Type superType = clazz.type.supertype();
if (superType.tag != TypeTags.CLASS)
return false;
clazz = (ClassSymbol) superType.tsym;
}
}
/**
* Is this symbol inherited into a given class?
* PRE: If symbol's owner is a interface,
* it is already assumed that the interface is a superinterface
* of given class.
* @param clazz The class for which we want to establish membership.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -