📄 check.java
字号:
/**
* @(#)Check.java 1.70 03/02/26
*
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package com.sun.tools.javac.v8.comp;
import com.sun.tools.javac.v8.util.*;
import com.sun.tools.javac.v8.code.*;
import com.sun.tools.javac.v8.tree.*;
import com.sun.tools.javac.v8.tree.Tree.*;
import com.sun.tools.javac.v8.code.Type.*;
import com.sun.tools.javac.v8.code.Symbol.*;
/**
* Type checking helper class for the attribution phase.
*/
public class Check implements Kinds, Flags, TypeTags {
private static final Context.Key checkKey = new Context.Key();
private Name.Table names;
private Log log;
private Symtab syms;
private Infer infer;
public static Check instance(Context context) {
Check instance = (Check) context.get(checkKey);
if (instance == null)
instance = new Check(context);
return instance;
}
private Check(Context context) {
super();
context.put(checkKey, this);
this.names = Name.Table.instance(context);
this.log = Log.instance(context);
this.syms = Symtab.instance(context);
this.infer = Infer.instance(context);
Options options = Options.instance(context);
warnunchecked = options.get("-warnunchecked") != null;
deprecation = options.get("-deprecation") != null;
}
/**
* Switch: -warnunchecked option set?
*/
boolean warnunchecked;
/**
* Switch: -deprecation option set?
*/
boolean deprecation;
/**
* A table mapping flat names of all compiled classes in this run to their
* symbols; maintained from outside.
*/
public Hashtable compiled = Hashtable.make();
/**
* Output variable: the source file where deprecated symbols were
* encountered. If deprecated symbols were encountered in more than one
* input file, the variable is set to "*".
*/
public Name deprecatedSource;
/**
* Output variable: the source file where deprecated symbols were
* encountered. If deprecated symbols were encountered in more than one
* input file, the variable is set to "*".
*/
public Name uncheckedSource;
/**
* Warn about deprecated symbol.
* @param pos Position to be used for error reporting.
* @param sym The deprecated symbol.
*/
void warnDeprecated(int pos, Symbol sym) {
if (deprecatedSource == null)
deprecatedSource = log.currentSource();
else if (deprecatedSource != log.currentSource())
deprecatedSource = names.asterisk;
if (deprecation)
log.warning(pos, "has.been.deprecated", sym.toJava(), sym.javaLocation());
}
/**
* Warn about unchecked operation.
* @param pos Position to be used for error reporting.
* @param msg A string describing the problem.
*/
void warnUnchecked(int pos, String msg) {
warnUnchecked(pos, msg, null, null, null, null);
}
void warnUnchecked(int pos, String msg, String arg0) {
warnUnchecked(pos, msg, arg0, null, null, null);
}
void warnUnchecked(int pos, String msg, String arg0, String arg1) {
warnUnchecked(pos, msg, arg0, arg1, null, null);
}
void warnUnchecked(int pos, String msg, String arg0, String arg1, String arg2) {
warnUnchecked(pos, msg, arg0, arg1, arg2, null);
}
void warnUnchecked(int pos, String msg, String arg0, String arg1,
String arg2, String arg3) {
if (uncheckedSource == null)
uncheckedSource = log.currentSource();
else if (uncheckedSource != log.currentSource())
uncheckedSource = names.asterisk;
if (warnunchecked)
log.warning(pos, msg, arg0, arg1, arg2, arg3);
}
/**
* Report a failure to complete a class.
* @param pos Position to be used for error reporting.
* @param ex The failure to report.
*/
public Type completionError(int pos, CompletionFailure ex) {
log.error(pos, "cant.access", ex.sym.toJava(), ex.errmsg);
if (ex instanceof ClassReader.BadClassFile)
throw new Abort();
else
return syms.errType;
}
/**
* Report a type error.
* @param pos Position to be used for error reporting.
* @param problem A string describing the error.
* @param found The type that was found.
* @param req The type that was required.
*/
Type typeError(int pos, String problem, Type found, Type req) {
log.error(pos, "prob.found.req", problem, found.toJava(), req.toJava());
return syms.errType;
}
/**
* Report an error that wrong type tag was found.
* @param pos Position to be used for error reporting.
* @param required An internationalized string describing the type tag
* required.
* @param found The type that was found.
*/
Type typeTagError(int pos, String required, Type found) {
log.error(pos, "type.found.req", found.toJava(), required);
return syms.errType;
}
/**
* Report an error that symbol cannot be referenced before super
* has been called.
* @param pos Position to be used for error reporting.
* @param sym The referenced symbol.
*/
void earlyRefError(int pos, Symbol sym) {
log.error(pos, "cant.ref.before.ctor.called", sym.toJava());
}
/**
* Report an error that type parameter is not within its bound.
* @param pos Position to be used for error reporting.
* @param t The type parameter.
* @param bound Its bound.
* @param explanation An internationalized string giving an
* additional explanation.
*/
void boundError(int pos, Type t, Type bound, String explanation) {
if (explanation.equals(""))
log.error(pos, "not.within.bounds", t.toJava());
else
log.error(pos, "not.within.bounds.explain", t.toJava(), explanation);
}
/**
* Return name of local class.
* This is of the form <topname> $ n $ <classname>
* where
* topname is the fully qualified name of the enclosing toplevel class,
* classname is the simple name of the local class
*/
Name localClassName(ClassSymbol c) {
ClassSymbol topClass = c.outermostClass();
for (int i = 1; ; i++) {
Name flatname = names.fromString(topClass.flatname + "$" + i + c.name);
if (compiled.get(flatname) == null)
return flatname;
}
}
/**
* Check that a given type is assignable to a given proto-type.
* If it is, return the type, otherwise return errType.
* @param pos Position to be used for error reporting.
* @param found The type that was found.
* @param req The type that was required.
*/
Type checkType(int pos, Type found, Type req) {
if (req.tag == ERROR) {
return req;
} else if (req.tag == NONE) {
return found;
} else if (found.isAssignable(req)) {
return found;
} else {
String problem;
if (found.tag <= DOUBLE && req.tag <= DOUBLE)
problem = log.getLocalizedString("possible.loss.of.precision");
else
problem = log.getLocalizedString("incompatible.types");
return typeError(pos, problem, found, req);
}
}
/**
* Check that a given type can be cast to a given target type.
* Return the result of the cast.
* @param pos Position to be used for error reporting.
* @param found The type that is being cast.
* @param req The target type of the cast.
*/
Type checkCastable(int pos, Type found, Type req) {
if (found.isCastable(req)) {
checkCompatible(pos, found, req);
return req;
} else {
return typeError(pos, log.getLocalizedString("inconvertible.types"),
found, req);
}
}
/**
* Check that type is different from 'void'.
* @param pos Position to be used for error reporting.
* @param t The type to be checked.
*/
Type checkNonVoid(int pos, Type t) {
if (t.tag == VOID) {
log.error(pos, "void.not.allowed.here");
return syms.errType;
} else {
return t;
}
}
/**
* Check that type is a class or interface type.
* @param pos Position to be used for error reporting.
* @param t The type to be checked.
*/
Type checkClassType(int pos, Type t) {
if (t.tag != CLASS && t.tag != ERROR)
return typeTagError(pos, log.getLocalizedString("type.req.class"), t);
else
return t;
}
/**
* Check that type is a class, interface or array type.
* @param pos Position to be used for error reporting.
* @param t The type to be checked.
*/
Type checkClassOrArrayType(int pos, Type t) {
if (t.tag != CLASS && t.tag != ARRAY && t.tag != ERROR)
return typeTagError(pos,
log.getLocalizedString("type.req.class.array"), t);
else
return t;
}
/**
* Check that type is a reference type, i.e. a class, interface or array type
* or a type variable.
* @param pos Position to be used for error reporting.
* @param t The type to be checked.
*/
Type checkRefType(int pos, Type t) {
if (t.tag != CLASS && t.tag != ARRAY && t.tag != ERROR)
return typeTagError(pos, log.getLocalizedString("type.req.ref"), t);
else
return t;
}
/**
* Check that flag set does not contain elements of two conflicting sets. s
* Return true if it doesn't.
* @param pos Position to be used for error reporting.
* @param flags The set of flags to be checked.
* @param set1 Conflicting flags set #1.
* @param set2 Conflicting flags set #2.
*/
boolean checkDisjoint(int pos, long flags, long set1, long set2) {
if ((flags & set1) != 0 && (flags & set2) != 0) {
log.error(pos, "illegal.combination.of.modifiers",
TreeInfo.flagNames(TreeInfo.firstFlag(flags & set1)),
TreeInfo.flagNames(TreeInfo.firstFlag(flags & set2)));
return false;
} else
return true;
}
/**
* Check that given modifiers are legal for given symbol and
* return modifiers together with any implicit modififiers for that symbol.
* Warning: we can't use flags() here since this method
* is called during class enter, when flags() would cause a premature
* completion.
* @param pos Position to be used for error reporting.
* @param flags The set of modifiers given in a definition.
* @param sym The defined symbol.
*/
long checkFlags(int pos, long flags, Symbol sym) {
long mask;
long implicit = 0;
switch (sym.kind) {
case VAR:
if (sym.owner.kind != TYP)
mask = LocalVarFlags;
else if ((sym.owner.flags_field & INTERFACE) != 0)
mask = implicit = InterfaceVarFlags;
else
mask = VarFlags;
break;
case MTH:
if (sym.name == names.init)
mask = ConstructorFlags;
else if ((sym.owner.flags_field & INTERFACE) != 0)
mask = implicit = InterfaceMethodFlags;
else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -