📄 resolve.java
字号:
return syms.errSymbol;
}
/**
* Resolve an appropriate implicit this instance for t's container.
* JLS2 8.8.5.1 and 15.9.2
*/
Type resolveImplicitThis(int pos, Env env, Type t) {
Type thisType = (((t.tsym.owner.kind & (MTH | VAR)) != 0) ?
resolveSelf(pos, env, t.outer().tsym, names._this) :
resolveSelfContaining(pos, env, t.tsym)).type;
if (((AttrContext) env.info).isSelfCall && thisType.tsym == env.enclClass.sym)
log.error(pos, "cant.ref.before.ctor.called", "this");
return thisType;
}
/**
* A localized string describing a given kind.
*/
static String kindName(int kind) {
switch (kind) {
case PCK:
return Log.getLocalizedString("kindname.package");
case TYP:
return Log.getLocalizedString("kindname.class");
case VAR:
return Log.getLocalizedString("kindname.variable");
case VAL:
return Log.getLocalizedString("kindname.value");
case MTH:
return Log.getLocalizedString("kindname.method");
default:
return Log.getLocalizedString("kindname.default", Integer.toString(kind));
}
}
/**
* A localized string describing a given set of kinds.
*/
static String kindNames(int kind) {
String[] s = new String[4];
int i = 0;
if ((kind & VAL) != 0)
s[i++] = ((kind & VAL) == VAR) ?
Log.getLocalizedString("kindname.variable") :
Log.getLocalizedString("kindname.value");
if ((kind & MTH) != 0)
s[i++] = Log.getLocalizedString("kindname.method");
if ((kind & TYP) != 0)
s[i++] = Log.getLocalizedString("kindname.class");
if ((kind & PCK) != 0)
s[i++] = Log.getLocalizedString("kindname.package");
String names = "";
for (int j = 0; j < i - 1; j++)
names = names + s[j] + ", ";
if (i >= 1)
names = names + s[i - 1];
else
names = Log.getLocalizedString("kindname.default",
Integer.toString(kind));
return names;
}
/**
* A localized string describing the kind -- either class or interface --
* of a given type.
*/
static String typeKindName(Type t) {
if (t.tag == CLASS && (t.tsym.flags() & COMPOUND) != 0)
return Log.getLocalizedString("kindname.type.variable");
else if (t.tag == PACKAGE)
return Log.getLocalizedString("kindname.package");
else if ((t.tsym.flags_field & INTERFACE) != 0)
return Log.getLocalizedString("kindname.interface");
else
return Log.getLocalizedString("kindname.class");
}
/**
* A localized string describing the kind of a missing symbol, given an
* error kind.
*/
static String absentKindName(int kind) {
switch (kind) {
case ABSENT_VAR:
return Log.getLocalizedString("kindname.variable");
case WRONG_MTHS:
case WRONG_MTH:
case ABSENT_MTH:
return Log.getLocalizedString("kindname.method");
case ABSENT_TYP:
return Log.getLocalizedString("kindname.class");
default:
return Log.getLocalizedString("kindname.identifier");
}
}
/**
* Root class for resolve errors.
* Instances of this class indicate "Symbol not found".
* Instances of subclass indicate other errors.
*/
private static class ResolveError extends Symbol implements TypeTags {
ResolveError(int kind, Symbol sym, String debugName) {
super(kind, 0, null, null, null);
this.debugName = debugName;
this.sym = sym;
}
/**
* The name of the kind of error, for debugging only.
*/
final String debugName;
/**
* The symbol that was determined by resolution, or errSymbol if none
* was found.
*/
final Symbol sym;
/**
* The symbol that was a close mismatch, or null if none was found.
* wrongSym is currently set if a simgle method with the correct name, but
* the wrong parameters was found.
*/
Symbol wrongSym;
/**
* Print the (debug only) name of the kind of error.
*/
public String toString() {
return debugName + " wrongSym=" + wrongSym;
}
/**
* Update wrongSym and return this
*/
ResolveError setWrongSym(Symbol sym) {
this.wrongSym = sym;
return this;
}
/**
* Report error.
* @param log The error log to be used for error reporting.
* @param pos The position to be used for error reporting.
* @param site The original type from where the selection took place.
* @param name The name of the symbol to be resolved.
* @param argtypes The invocation's value parameters,
* if we looked for a method.
*/
void report(Log log, int pos, Type site, Name name, List argtypes) {
if (name != name.table.error) {
String kindname = absentKindName(kind);
String idname = name.toJava();
String args = "";
if (kind >= WRONG_MTHS && kind <= ABSENT_MTH) {
if (isOperator(name)) {
log.error(pos, "operator.cant.be.applied", name.toJava(),
Type.toJavaList(argtypes));
return;
}
if (name == name.table.init) {
kindname = log.getLocalizedString("kindname.constructor");
idname = site.tsym.name.toJava();
}
args = "(" + Type.toJavaList(argtypes) + ")";
}
if (kind == WRONG_MTH) {
log.error(pos, "cant.apply.symbol",
wrongSym.asMemberOf(site).toJava(),
wrongSym.javaLocation(site), Type.toJavaList(argtypes));
} else if (site.tsym.name.len != 0) {
if (site.tsym.kind == PCK && !site.tsym.exists())
log.error(pos, "doesnt.exist", site.tsym.toJava());
else if (idname.indexOf('$') != -1)
log.error(pos, "cant.resolve.location.perchance",
kindname, idname, args, typeKindName(site),
site.toJava(), idname.replace('$', '.'));
else
log.error(pos, "cant.resolve.location", kindname, idname,
args, typeKindName(site), site.toJava());
} else
log.error(pos, "cant.resolve", kindname, idname, args);
}
}
/**
* A name designates an operator if it consists
* of a non-empty sequence of operator symbols +-~!/*%&|^<>=
*/
boolean isOperator(Name name) {
int i = 0;
while (i < name.len && "+-~!*/%&|^<>=".indexOf(name.byteAt(i)) >= 0)
i++;
return i > 0 && i == name.len;
}
}
/**
* Resolve error class indicating that a symbol is not accessible.
*/
static class AccessError extends ResolveError {
AccessError(Symbol sym) {
super(HIDDEN, sym, "access error");
}
/**
* Report error.
* @param log The error log to be used for error reporting.
* @param pos The position to be used for error reporting.
* @param site The original type from where the selection took place.
* @param name The name of the symbol to be resolved.
* @param argtypes The invocation's value parameters,
* if we looked for a method.
*/
void report(Log log, int pos, Type site, Name name, List argtypes) {
if (sym.owner.type.tag != ERROR) {
if (sym.name == sym.name.table.init && sym.owner != site.tsym)
new ResolveError(ABSENT_MTH, sym.owner,
"absent method " + sym).report(log, pos, site, name,
argtypes);
if ((sym.flags() & PUBLIC) != 0)
log.error(pos, "not.def.public.class.intf.cant.access",
sym.toJava(), sym.javaLocation());
else if ((sym.flags() & (PRIVATE | PROTECTED)) != 0)
log.error(pos, "report.access", sym.toJava(),
TreeInfo.flagNames(sym.flags() &
(PRIVATE | PROTECTED)), sym.javaLocation());
else
log.error(pos, "not.def.public.cant.access", sym.toJava(),
sym.javaLocation());
}
}
}
/**
* Resolve error class indicating that an instance member was accessed
* from a static context.
*/
static class StaticError extends ResolveError {
StaticError(Symbol sym) {
super(HIDDEN, sym, "static error");
}
/**
* Report error.
* @param log The error log to be used for error reporting.
* @param pos The position to be used for error reporting.
* @param site The original type from where the selection took place.
* @param name The name of the symbol to be resolved.
* @param argtypes The invocation's value parameters,
* if we looked for a method.
*/
void report(Log log, int pos, Type site, Name name, List argtypes) {
String symstr = sym.kind == TYP & sym.type.tag == CLASS ?
sym.type.toJava() : sym.toJava();
log.error(pos, "non-static.cant.be.ref", kindName(sym.kind), symstr);
}
}
/**
* Resolve error class indicating an ambiguous reference.
*/
static class AmbiguityError extends ResolveError {
Symbol sym1;
Symbol sym2;
AmbiguityError(Symbol sym1, Symbol sym2) {
super(AMBIGUOUS, sym1, "ambiguity error");
this.sym1 = sym1;
this.sym2 = sym2;
}
/**
* Report error.
* @param log The error log to be used for error reporting.
* @param pos The position to be used for error reporting.
* @param site The original type from where the selection took place.
* @param name The name of the symbol to be resolved.
* @param argtypes The invocation's value parameters,
* if we looked for a method.
*/
void report(Log log, int pos, Type site, Name name, List argtypes) {
AmbiguityError pair = this;
while (true) {
if (pair.sym1.kind == AMBIGUOUS)
pair = (AmbiguityError) pair.sym1;
else if (pair.sym2.kind == AMBIGUOUS)
pair = (AmbiguityError) pair.sym2;
else
break;
}
Name sname = pair.sym1.name;
if (sname == sname.table.init)
sname = pair.sym1.owner.name;
log.error(pos, "ref.ambiguous", sname.toJava(),
kindName(pair.sym1.kind), pair.sym1.toJava(),
pair.sym1.javaLocation(site), kindName(pair.sym2.kind),
pair.sym2.toJava(), pair.sym2.javaLocation(site));
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -