📄 resolve.java
字号:
if ((kind & TYP) != 0) {
Symbol sym = loadClass(env, fullname);
if (sym.kind <= AMBIGUOUS) {
if (name == sym.name)
return sym;
} else if (sym.kind < bestSoFar.kind)
bestSoFar = sym;
}
return (pack != null) ? pack : bestSoFar;
}
/**
* Find an identifier among the members of a given type `site'.
* @param env The current environment.
* @param site The type containing the symbol to be found.
* @param name The identifier's name.
* @param kind Indicates the possible symbol kinds
* (a subset of VAL, TYP).
*/
Symbol findIdentInType(Env env, Type site, Name name, int kind) {
Symbol bestSoFar = typeNotFound;
Symbol sym;
if ((kind & VAR) != 0) {
sym = findField(env, site, name, site.tsym);
if (sym.kind <= AMBIGUOUS)
return sym;
else if (sym.kind < bestSoFar.kind)
bestSoFar = sym;
}
if ((kind & TYP) != 0) {
sym = findMemberType(env, site, name, site.tsym);
if (sym.kind <= AMBIGUOUS)
return sym;
else if (sym.kind < bestSoFar.kind)
bestSoFar = sym;
}
return bestSoFar;
}
/**
* If `sym' is a bad symbol: report error and return errSymbol
* else pass through unchanged,
* additional arguments duplicate what has been used in trying to find the
* symbol (--> flyweight pattern). This improves performance since we expect
* misses to happen frequently.
*
* @param sym The symbol that was found, or a ResolveError.
* @param pos The position to use for error reporting.
* @param site The original type from where the selection took place.
* @param name The symbol's name.
* @param argtypes The invocation's value parameters,
* if we looked for a method.
*/
Symbol access(Symbol sym, int pos, Type site, Name name, boolean qualified,
List argtypes) {
if (sym.kind >= AMBIGUOUS) {
if (!site.isErroneous() && !Type.isErroneous(argtypes))
((ResolveError) sym).report(log, pos, site, name, argtypes);
do {
sym = ((ResolveError) sym).sym;
} while (sym.kind >= AMBIGUOUS)
;
if (sym == syms.errSymbol)
sym = new ErrorType(name, qualified ? site.tsym : syms.noSymbol).tsym;
}
return sym;
}
/**
* Same as above, but without type parameters and arguments.
*/
Symbol access(Symbol sym, int pos, Type site, Name name, boolean qualified) {
if (sym.kind >= AMBIGUOUS)
return access(sym, pos, site, name, qualified, Type.emptyList);
else
return sym;
}
/**
* Check that sym is not an abstract method.
*/
void checkNonAbstract(int pos, Symbol sym) {
if ((sym.flags() & ABSTRACT) != 0)
log.error(pos, "abstract.cant.be.accessed.directly",
kindName(sym.kind), sym.toJava());
}
/**
* print all scopes starting with scope s and proceeding outwards.
* used for debugging.
*/
public static void printscopes(Scope s) {
while (s != null) {
if (s.owner != null)
System.err.print(s.owner + ": ");
for (Scope.Entry e = s.elems; e != null; e = e.sibling) {
if ((e.sym.flags() & ABSTRACT) != 0)
System.err.print("abstract ");
System.err.print(e.sym + " ");
}
System.err.println();
s = s.next;
}
}
static void printscopes(Env env) {
while (env.outer != null) {
System.err.println("------------------------------");
printscopes(((AttrContext) env.info).scope);
env = env.outer;
}
}
public static void printscopes(Type t) {
while (t.tag == CLASS) {
printscopes(t.tsym.members());
t = t.supertype();
}
}
/**
* Warn about an unchecked method invocation.
*/
void warnUncheckedInvocation(int pos, Symbol sym, List argtypes) {
if (sym.kind < AMBIGUOUS) {
chk.warnUnchecked(pos, "unchecked.meth.invocation.applied",
sym.toJava(), sym.javaLocation(), Type.toJavaList(argtypes));
}
}
/**
* Resolve an unqualified (non-method) identifier.
* @param pos The position to use for error reporting.
* @param env The environment current at the identifier use.
* @param name The identifier's name.
* @param kind The set of admissible symbol kinds for the identifier.
*/
Symbol resolveIdent(int pos, Env env, Name name, int kind) {
return access(findIdent(env, name, kind), pos, env.enclClass.sym.type,
name, false);
}
/**
* Resolve an unqualified method identifier.
* @param pos The position to use for error reporting.
* @param env The environment current at the method invocation.
* @param name The identifier's name.
* @param argtypes The types of the invocation's value parameters.
*/
Symbol resolveMethod(int pos, Env env, Name name, List argtypes) {
Symbol sym = findFun(env, name, argtypes);
if (sym.kind >= WRONG_MTHS && Type.isDerivedRaw(argtypes) &&
!((AttrContext) env.info).rawArgs) {
((AttrContext) env.info).rawArgs = true;
sym = findFun(env, name, argtypes);
((AttrContext) env.info).rawArgs = false;
warnUncheckedInvocation(pos, sym, argtypes);
}
if (sym.kind >= AMBIGUOUS) {
sym = access(sym, pos, env.enclClass.sym.type, name, false, argtypes);
}
return sym;
}
/**
* Resolve a qualified method identifier
* @param pos The position to use for error reporting.
* @param env The environment current at the method invocation.
* @param site The type of the qualifying expression, in which
* identifier is searched.
* @param name The identifier's name.
* @param argtypes The types of the invocation's value parameters.
*/
Symbol resolveQualifiedMethod(int pos, Env env, Type site, Name name,
List argtypes) {
Symbol sym = findMethod(env, site, name, argtypes);
if (sym.kind >= WRONG_MTHS && Type.isDerivedRaw(argtypes) &&
!((AttrContext) env.info).rawArgs) {
((AttrContext) env.info).rawArgs = true;
sym = findMethod(env, site, name, argtypes);
((AttrContext) env.info).rawArgs = false;
warnUncheckedInvocation(pos, sym, argtypes);
}
if (sym.kind >= AMBIGUOUS) {
sym = access(sym, pos, site, name, true, argtypes);
}
return sym;
}
/**
* Resolve a qualified method identifier, throw a fatal error if not
* found.
* @param pos The position to use for error reporting.
* @param env The environment current at the method invocation.
* @param site The type of the qualifying expression, in which
* identifier is searched.
* @param name The identifier's name.
* @param argtypes The types of the invocation's value parameters.
*/
Symbol resolveInternalMethod(int pos, Env env, Type site, Name name,
List argtypes) {
Symbol sym = resolveQualifiedMethod(pos, env, site, name, argtypes);
if (sym.kind == MTH)
return sym;
else
throw new FatalError( Log.getLocalizedString("fatal.err.cant.locate.meth",
name.toJava()));
}
/**
* Resolve constructor.
* @param pos The position to use for error reporting.
* @param env The environment current at the constructor invocation.
* @param site The type of class for which a constructor is searched.
* @param argtypes The types of the constructor invocation's value
* parameters.
*/
Symbol resolveConstructor(int pos, Env env, Type site, List argtypes) {
Symbol sym = resolveQualifiedMethod(pos, env, site, names.init, argtypes);
if ((sym.flags() & DEPRECATED) != 0 &&
(((AttrContext) env.info).scope.owner.flags() & DEPRECATED) ==
0 && ((AttrContext) env.info).scope.owner.outermostClass() !=
sym.outermostClass())
chk.warnDeprecated(pos, sym);
return sym;
}
/**
* Resolve operator.
* @param pos The position to use for error reporting.
* @param optag The tag of the operation tree.
* @param env The environment current at the operation.
* @param argtypes The types of the operands.
*/
Symbol resolveOperator(int pos, int optag, Env env, List argtypes) {
Name name = treeinfo.operatorName(optag);
return access(findMethod(env, syms.predefClass.type, name, argtypes),
pos, env.enclClass.sym.type, name, false, argtypes);
}
/**
* Resolve operator.
* @param pos The position to use for error reporting.
* @param optag The tag of the operation tree.
* @param env The environment current at the operation.
* @param argtypes The types of the operands.
*/
Symbol resolveUnaryOperator(int pos, int optag, Env env, Type arg) {
List argtypes = Type.emptyList.prepend(arg);
return resolveOperator(pos, optag, env, argtypes);
}
/**
* Resolve binary operator.
* @param pos The position to use for error reporting.
* @param optag The tag of the operation tree.
* @param env The environment current at the operation.
* @param left The types of the left operand.
* @param right The types of the right operand.
*/
Symbol resolveBinaryOperator(int pos, int optag, Env env, Type left, Type right) {
List argtypes = Type.emptyList.prepend(right).prepend(left);
return resolveOperator(pos, optag, env, argtypes);
}
/**
* Resolve `c.name' where name == this or name == super.
* @param pos The position to use for error reporting.
* @param env The environment current at the expression.
* @param c The qualifier.
* @param name The identifier's name.
*/
Symbol resolveSelf(int pos, Env env, TypeSymbol c, Name name) {
Env env1 = env;
boolean staticOnly = false;
while (env1.outer != null) {
if (isStatic(env1))
staticOnly = true;
if (env1.enclClass.sym == c) {
Symbol sym = ((AttrContext) env1.info).scope.lookup(name).sym;
if (sym != null) {
if (staticOnly)
sym = new StaticError(sym);
return access(sym, pos, env.enclClass.sym.type, name, true);
}
}
if ((env1.enclClass.sym.flags() & STATIC) != 0)
staticOnly = true;
env1 = env1.outer;
}
log.error(pos, "not.encl.class", c.toJava());
return syms.errSymbol;
}
/**
* Resolve `c.this' for an enclosing class c that contains
* the named member.
* @param pos The position to use for error reporting.
* @param env The environment current at the expression.
* @param member The member that must be contained in the result.
*/
Symbol resolveSelfContaining(int pos, Env env, Symbol member) {
Name name = names._this;
Env env1 = env;
boolean staticOnly = false;
while (env1.outer != null) {
if (isStatic(env1))
staticOnly = true;
if (env1.enclClass.sym.isSubClass(member.owner)) {
Symbol sym = ((AttrContext) env1.info).scope.lookup(name).sym;
if (sym != null) {
if (staticOnly)
sym = new StaticError(sym);
return access(sym, pos, env.enclClass.sym.type, name, true);
}
}
if ((env1.enclClass.sym.flags() & STATIC) != 0)
staticOnly = true;
env1 = env1.outer;
}
log.error(pos, "encl.class.required", member.toJava());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -