提交 f5d3720d 编写于 作者: M mcimadamore

8071241: Investigate alternate strategy for type-checking operators

Summary: Separat operator lookup logic from overload resolution.
Reviewed-by: jjg, jlahoda, sadayapalam
上级 1c2c3c4b
......@@ -200,9 +200,6 @@ public class Symtab {
*/
public final VarSymbol lengthVar;
/** The null check operator. */
public final OperatorSymbol nullcheck;
/** The symbol representing the final finalize method on enums */
public final MethodSymbol enumFinalFinalize;
......@@ -217,10 +214,6 @@ public class Symtab {
*/
public final Name[] boxedName = new Name[TypeTag.getTypeTagCount()];
/** A set containing all operator names.
*/
public final Set<Name> operatorNames = new HashSet<>();
/** A hashtable containing the encountered top-level and member classes,
* indexed by flat names. The table does not contain local classes.
* It should be updated from the outside to reflect classes defined
......@@ -255,85 +248,6 @@ public class Symtab {
*/
public final ClassSymbol predefClass;
/** Enter a constant into symbol table.
* @param name The constant's name.
* @param type The constant's type.
*/
private VarSymbol enterConstant(String name, Type type) {
VarSymbol c = new VarSymbol(
PUBLIC | STATIC | FINAL,
names.fromString(name),
type,
predefClass);
c.setData(type.constValue());
predefClass.members().enter(c);
return c;
}
/** Enter a binary operation into symbol table.
* @param name The name of the operator.
* @param left The type of the left operand.
* @param right The type of the left operand.
* @param res The operation's result type.
* @param opcode The operation's bytecode instruction.
*/
private void enterBinop(String name,
Type left, Type right, Type res,
int opcode) {
predefClass.members().enter(
new OperatorSymbol(
makeOperatorName(name),
new MethodType(List.of(left, right), res,
List.<Type>nil(), methodClass),
opcode,
predefClass));
}
/** Enter a binary operation, as above but with two opcodes,
* which get encoded as
* {@code (opcode1 << ByteCodeTags.preShift) + opcode2 }.
* @param opcode1 First opcode.
* @param opcode2 Second opcode.
*/
private void enterBinop(String name,
Type left, Type right, Type res,
int opcode1, int opcode2) {
enterBinop(
name, left, right, res, (opcode1 << ByteCodes.preShift) | opcode2);
}
/** Enter a unary operation into symbol table.
* @param name The name of the operator.
* @param arg The type of the operand.
* @param res The operation's result type.
* @param opcode The operation's bytecode instruction.
*/
private OperatorSymbol enterUnop(String name,
Type arg,
Type res,
int opcode) {
OperatorSymbol sym =
new OperatorSymbol(makeOperatorName(name),
new MethodType(List.of(arg),
res,
List.<Type>nil(),
methodClass),
opcode,
predefClass);
predefClass.members().enter(sym);
return sym;
}
/**
* Create a new operator name from corresponding String representation
* and add the name to the set of known operator names.
*/
private Name makeOperatorName(String name) {
Name opName = names.fromString(name);
operatorNames.add(opName);
return opName;
}
/** Enter a class into symbol table.
* @param s The name of the class.
*/
......@@ -591,163 +505,6 @@ public class Symtab {
List.<Type>nil(), methodClass),
arrayClass);
arrayClass.members().enter(arrayCloneMethod);
// Enter operators.
/* Internally we use +++, --- for unary +, - to reduce +, - operators
* overloading
*/
enterUnop("+++", doubleType, doubleType, nop);
enterUnop("+++", floatType, floatType, nop);
enterUnop("+++", longType, longType, nop);
enterUnop("+++", intType, intType, nop);
enterUnop("---", doubleType, doubleType, dneg);
enterUnop("---", floatType, floatType, fneg);
enterUnop("---", longType, longType, lneg);
enterUnop("---", intType, intType, ineg);
enterUnop("~", longType, longType, lxor);
enterUnop("~", intType, intType, ixor);
enterUnop("++", doubleType, doubleType, dadd);
enterUnop("++", floatType, floatType, fadd);
enterUnop("++", longType, longType, ladd);
enterUnop("++", intType, intType, iadd);
enterUnop("++", charType, charType, iadd);
enterUnop("++", shortType, shortType, iadd);
enterUnop("++", byteType, byteType, iadd);
enterUnop("--", doubleType, doubleType, dsub);
enterUnop("--", floatType, floatType, fsub);
enterUnop("--", longType, longType, lsub);
enterUnop("--", intType, intType, isub);
enterUnop("--", charType, charType, isub);
enterUnop("--", shortType, shortType, isub);
enterUnop("--", byteType, byteType, isub);
enterUnop("!", booleanType, booleanType, bool_not);
nullcheck = enterUnop("<*nullchk*>", objectType, objectType, nullchk);
// string concatenation
enterBinop("+", stringType, objectType, stringType, string_add);
enterBinop("+", objectType, stringType, stringType, string_add);
enterBinop("+", stringType, stringType, stringType, string_add);
enterBinop("+", stringType, intType, stringType, string_add);
enterBinop("+", stringType, longType, stringType, string_add);
enterBinop("+", stringType, floatType, stringType, string_add);
enterBinop("+", stringType, doubleType, stringType, string_add);
enterBinop("+", stringType, booleanType, stringType, string_add);
enterBinop("+", stringType, botType, stringType, string_add);
enterBinop("+", intType, stringType, stringType, string_add);
enterBinop("+", longType, stringType, stringType, string_add);
enterBinop("+", floatType, stringType, stringType, string_add);
enterBinop("+", doubleType, stringType, stringType, string_add);
enterBinop("+", booleanType, stringType, stringType, string_add);
enterBinop("+", botType, stringType, stringType, string_add);
// these errors would otherwise be matched as string concatenation
enterBinop("+", botType, botType, botType, error);
enterBinop("+", botType, intType, botType, error);
enterBinop("+", botType, longType, botType, error);
enterBinop("+", botType, floatType, botType, error);
enterBinop("+", botType, doubleType, botType, error);
enterBinop("+", botType, booleanType, botType, error);
enterBinop("+", botType, objectType, botType, error);
enterBinop("+", intType, botType, botType, error);
enterBinop("+", longType, botType, botType, error);
enterBinop("+", floatType, botType, botType, error);
enterBinop("+", doubleType, botType, botType, error);
enterBinop("+", booleanType, botType, botType, error);
enterBinop("+", objectType, botType, botType, error);
enterBinop("+", doubleType, doubleType, doubleType, dadd);
enterBinop("+", floatType, floatType, floatType, fadd);
enterBinop("+", longType, longType, longType, ladd);
enterBinop("+", intType, intType, intType, iadd);
enterBinop("-", doubleType, doubleType, doubleType, dsub);
enterBinop("-", floatType, floatType, floatType, fsub);
enterBinop("-", longType, longType, longType, lsub);
enterBinop("-", intType, intType, intType, isub);
enterBinop("*", doubleType, doubleType, doubleType, dmul);
enterBinop("*", floatType, floatType, floatType, fmul);
enterBinop("*", longType, longType, longType, lmul);
enterBinop("*", intType, intType, intType, imul);
enterBinop("/", doubleType, doubleType, doubleType, ddiv);
enterBinop("/", floatType, floatType, floatType, fdiv);
enterBinop("/", longType, longType, longType, ldiv);
enterBinop("/", intType, intType, intType, idiv);
enterBinop("%", doubleType, doubleType, doubleType, dmod);
enterBinop("%", floatType, floatType, floatType, fmod);
enterBinop("%", longType, longType, longType, lmod);
enterBinop("%", intType, intType, intType, imod);
enterBinop("&", booleanType, booleanType, booleanType, iand);
enterBinop("&", longType, longType, longType, land);
enterBinop("&", intType, intType, intType, iand);
enterBinop("|", booleanType, booleanType, booleanType, ior);
enterBinop("|", longType, longType, longType, lor);
enterBinop("|", intType, intType, intType, ior);
enterBinop("^", booleanType, booleanType, booleanType, ixor);
enterBinop("^", longType, longType, longType, lxor);
enterBinop("^", intType, intType, intType, ixor);
enterBinop("<<", longType, longType, longType, lshll);
enterBinop("<<", intType, longType, intType, ishll);
enterBinop("<<", longType, intType, longType, lshl);
enterBinop("<<", intType, intType, intType, ishl);
enterBinop(">>", longType, longType, longType, lshrl);
enterBinop(">>", intType, longType, intType, ishrl);
enterBinop(">>", longType, intType, longType, lshr);
enterBinop(">>", intType, intType, intType, ishr);
enterBinop(">>>", longType, longType, longType, lushrl);
enterBinop(">>>", intType, longType, intType, iushrl);
enterBinop(">>>", longType, intType, longType, lushr);
enterBinop(">>>", intType, intType, intType, iushr);
enterBinop("<", doubleType, doubleType, booleanType, dcmpg, iflt);
enterBinop("<", floatType, floatType, booleanType, fcmpg, iflt);
enterBinop("<", longType, longType, booleanType, lcmp, iflt);
enterBinop("<", intType, intType, booleanType, if_icmplt);
enterBinop(">", doubleType, doubleType, booleanType, dcmpl, ifgt);
enterBinop(">", floatType, floatType, booleanType, fcmpl, ifgt);
enterBinop(">", longType, longType, booleanType, lcmp, ifgt);
enterBinop(">", intType, intType, booleanType, if_icmpgt);
enterBinop("<=", doubleType, doubleType, booleanType, dcmpg, ifle);
enterBinop("<=", floatType, floatType, booleanType, fcmpg, ifle);
enterBinop("<=", longType, longType, booleanType, lcmp, ifle);
enterBinop("<=", intType, intType, booleanType, if_icmple);
enterBinop(">=", doubleType, doubleType, booleanType, dcmpl, ifge);
enterBinop(">=", floatType, floatType, booleanType, fcmpl, ifge);
enterBinop(">=", longType, longType, booleanType, lcmp, ifge);
enterBinop(">=", intType, intType, booleanType, if_icmpge);
enterBinop("==", objectType, objectType, booleanType, if_acmpeq);
enterBinop("==", booleanType, booleanType, booleanType, if_icmpeq);
enterBinop("==", doubleType, doubleType, booleanType, dcmpl, ifeq);
enterBinop("==", floatType, floatType, booleanType, fcmpl, ifeq);
enterBinop("==", longType, longType, booleanType, lcmp, ifeq);
enterBinop("==", intType, intType, booleanType, if_icmpeq);
enterBinop("!=", objectType, objectType, booleanType, if_acmpne);
enterBinop("!=", booleanType, booleanType, booleanType, if_icmpne);
enterBinop("!=", doubleType, doubleType, booleanType, dcmpl, ifne);
enterBinop("!=", floatType, floatType, booleanType, fcmpl, ifne);
enterBinop("!=", longType, longType, booleanType, lcmp, ifne);
enterBinop("!=", intType, intType, booleanType, if_icmpne);
enterBinop("&&", booleanType, booleanType, booleanType, bool_and);
enterBinop("||", booleanType, booleanType, booleanType, bool_or);
}
/** Define a new class given its name and owner.
......
......@@ -1445,26 +1445,6 @@ public class Types {
}
// </editor-fold>
/**
* Can t and s be compared for equality? Any primitive ==
* primitive or primitive == object comparisons here are an error.
* Unboxing and correct primitive == primitive comparisons are
* already dealt with in Attr.visitBinary.
*
*/
public boolean isEqualityComparable(Type s, Type t, Warner warn) {
if (t.isNumeric() && s.isNumeric())
return true;
boolean tPrimitive = t.isPrimitive();
boolean sPrimitive = s.isPrimitive();
if (!tPrimitive && !sPrimitive) {
return isCastable(s, t, warn) || isCastable(t, s, warn);
} else {
return false;
}
}
// <editor-fold defaultstate="collapsed" desc="isCastable">
public boolean isCastable(Type t, Type s) {
return isCastable(t, s, noWarnings);
......
......@@ -82,6 +82,7 @@ public class Attr extends JCTree.Visitor {
final Log log;
final Symtab syms;
final Resolve rs;
final Operators operators;
final Infer infer;
final Analyzer analyzer;
final DeferredAttr deferredAttr;
......@@ -115,6 +116,7 @@ public class Attr extends JCTree.Visitor {
log = Log.instance(context);
syms = Symtab.instance(context);
rs = Resolve.instance(context);
operators = Operators.instance(context);
chk = Check.instance(context);
flow = Flow.instance(context);
memberEnter = MemberEnter.instance(context);
......@@ -1467,7 +1469,7 @@ public class Attr extends JCTree.Visitor {
* @param thentype The type of the expression's then-part.
* @param elsetype The type of the expression's else-part.
*/
private Type condType(DiagnosticPosition pos,
Type condType(DiagnosticPosition pos,
Type thentype, Type elsetype) {
// If same type, that is the result
if (types.isSameType(thentype, elsetype))
......@@ -2142,7 +2144,7 @@ public class Attr extends JCTree.Visitor {
JCTree.Tag optag = NULLCHK;
JCUnary tree = make.at(arg.pos).Unary(optag, arg);
tree.operator = syms.nullcheck;
tree.operator = operators.resolveUnary(arg, optag, arg.type);
tree.type = arg.type;
return tree;
}
......@@ -2903,18 +2905,10 @@ public class Attr extends JCTree.Visitor {
Type owntype = attribTree(tree.lhs, env, varAssignmentInfo);
Type operand = attribExpr(tree.rhs, env);
// Find operator.
Symbol operator = tree.operator = rs.resolveBinaryOperator(
tree.pos(), tree.getTag().noAssignOp(), env,
owntype, operand);
Symbol operator = tree.operator = operators.resolveBinary(tree, tree.getTag().noAssignOp(), owntype, operand);
if (operator.kind == MTH &&
!owntype.isErroneous() &&
!operand.isErroneous()) {
chk.checkOperator(tree.pos(),
(OperatorSymbol)operator,
tree.getTag().noAssignOp(),
owntype,
operand);
chk.checkDivZero(tree.rhs.pos(), operator, operand);
chk.checkCastable(tree.rhs.pos(),
operator.type.getReturnType(),
......@@ -2930,9 +2924,7 @@ public class Attr extends JCTree.Visitor {
: chk.checkNonVoid(tree.arg.pos(), attribExpr(tree.arg, env));
// Find operator.
Symbol operator = tree.operator =
rs.resolveUnaryOperator(tree.pos(), tree.getTag(), env, argtype);
Symbol operator = tree.operator = operators.resolveUnary(tree, tree.getTag(), argtype);
Type owntype = types.createErrorType(tree.type);
if (operator.kind == MTH &&
!argtype.isErroneous()) {
......@@ -2957,22 +2949,13 @@ public class Attr extends JCTree.Visitor {
Type left = chk.checkNonVoid(tree.lhs.pos(), attribExpr(tree.lhs, env));
Type right = chk.checkNonVoid(tree.lhs.pos(), attribExpr(tree.rhs, env));
// Find operator.
Symbol operator = tree.operator =
rs.resolveBinaryOperator(tree.pos(), tree.getTag(), env, left, right);
Symbol operator = tree.operator = operators.resolveBinary(tree, tree.getTag(), left, right);
Type owntype = types.createErrorType(tree.type);
if (operator.kind == MTH &&
!left.isErroneous() &&
!right.isErroneous()) {
owntype = operator.type.getReturnType();
// This will figure out when unboxing can happen and
// choose the right comparison operator.
int opc = chk.checkOperator(tree.lhs.pos(),
(OperatorSymbol)operator,
tree.getTag(),
left,
right);
int opc = ((OperatorSymbol)operator).opcode;
// If both arguments are constants, fold them.
if (left.constValue() != null && right.constValue() != null) {
Type ctype = cfolder.fold2(opc, left, right);
......@@ -2985,8 +2968,7 @@ public class Attr extends JCTree.Visitor {
// castable to each other, (JLS 15.21). Note: unboxing
// comparisons will not have an acmp* opc at this point.
if ((opc == ByteCodes.if_acmpeq || opc == ByteCodes.if_acmpne)) {
if (!types.isEqualityComparable(left, right,
new Warner(tree.pos()))) {
if (!types.isCastable(left, right, new Warner(tree.pos()))) {
log.error(tree.pos(), "incomparable.types", left, right);
}
}
......
......@@ -83,7 +83,6 @@ public class Check {
private boolean warnOnSyntheticConflicts;
private boolean suppressAbortOnBadClassFile;
private boolean enableSunApiLintControl;
private final TreeInfo treeinfo;
private final JavaFileManager fileManager;
private final Profile profile;
private final boolean warnOnAccessToSensitiveMembers;
......@@ -121,7 +120,6 @@ public class Check {
diags = JCDiagnostic.Factory.instance(context);
Options options = Options.instance(context);
lint = Lint.instance(context);
treeinfo = TreeInfo.instance(context);
fileManager = context.get(JavaFileManager.class);
Source source = Source.instance(context);
......@@ -3264,30 +3262,6 @@ public class Check {
* Miscellaneous
**************************************************************************/
/**
* Return the opcode of the operator but emit an error if it is an
* error.
* @param pos position for error reporting.
* @param operator an operator
* @param tag a tree tag
* @param left type of left hand side
* @param right type of right hand side
*/
int checkOperator(DiagnosticPosition pos,
OperatorSymbol operator,
JCTree.Tag tag,
Type left,
Type right) {
if (operator.opcode == ByteCodes.error) {
log.error(pos,
"operator.cant.be.applied.1",
treeinfo.operatorName(tag),
left, right);
}
return operator.opcode;
}
/**
* Check for division by integer constant zero
* @param pos Position for error reporting.
......
......@@ -1386,7 +1386,7 @@ public class DeferredAttr extends JCTree.Visitor {
Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
return rec == null ?
rs.findFun(env, name, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()) :
rs.findMethod(env, site, name, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired(), false);
rs.findMethod(env, site, name, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired());
}
@Override
Symbol access(Env<AttrContext> env, DiagnosticPosition pos, Symbol location, Symbol sym) {
......
......@@ -80,6 +80,7 @@ public class LambdaToMethod extends TreeTranslator {
private Names names;
private Symtab syms;
private Resolve rs;
private Operators operators;
private TreeMaker make;
private Types types;
private TransTypes transTypes;
......@@ -130,6 +131,7 @@ public class LambdaToMethod extends TreeTranslator {
names = Names.instance(context);
syms = Symtab.instance(context);
rs = Resolve.instance(context);
operators = Operators.instance(context);
make = TreeMaker.instance(context);
types = Types.instance(context);
transTypes = TransTypes.instance(context);
......@@ -654,7 +656,7 @@ public class LambdaToMethod extends TreeTranslator {
private JCExpression eqTest(Type argType, JCExpression arg1, JCExpression arg2) {
JCBinary testExpr = make.Binary(JCTree.Tag.EQ, arg1, arg2);
testExpr.operator = rs.resolveBinaryOperator(null, JCTree.Tag.EQ, attrEnv, argType, argType);
testExpr.operator = operators.resolveBinary(testExpr, JCTree.Tag.EQ, argType, argType);
testExpr.setType(syms.booleanType);
return testExpr;
}
......@@ -668,7 +670,7 @@ public class LambdaToMethod extends TreeTranslator {
List.<JCExpression>of(make.Literal(lit)));
eqtest.setType(syms.booleanType);
JCBinary compound = make.Binary(JCTree.Tag.AND, prev, eqtest);
compound.operator = rs.resolveBinaryOperator(null, JCTree.Tag.AND, attrEnv, syms.booleanType, syms.booleanType);
compound.operator = operators.resolveBinary(compound, JCTree.Tag.AND, syms.booleanType, syms.booleanType);
compound.setType(syms.booleanType);
return compound;
}
......
......@@ -74,6 +74,7 @@ public class Lower extends TreeTranslator {
private final Log log;
private final Symtab syms;
private final Resolve rs;
private final Operators operators;
private final Check chk;
private final Attr attr;
private TreeMaker make;
......@@ -95,6 +96,7 @@ public class Lower extends TreeTranslator {
log = Log.instance(context);
syms = Symtab.instance(context);
rs = Resolve.instance(context);
operators = Operators.instance(context);
chk = Check.instance(context);
attr = Attr.instance(context);
make = TreeMaker.instance(context);
......@@ -575,8 +577,7 @@ public class Lower extends TreeTranslator {
*/
JCUnary makeUnary(JCTree.Tag optag, JCExpression arg) {
JCUnary tree = make.Unary(optag, arg);
tree.operator = rs.resolveUnaryOperator(
make_pos, optag, attrEnv, arg.type);
tree.operator = operators.resolveUnary(tree, optag, arg.type);
tree.type = tree.operator.type.getReturnType();
return tree;
}
......@@ -588,8 +589,7 @@ public class Lower extends TreeTranslator {
*/
JCBinary makeBinary(JCTree.Tag optag, JCExpression lhs, JCExpression rhs) {
JCBinary tree = make.Binary(optag, lhs, rhs);
tree.operator = rs.resolveBinaryOperator(
make_pos, optag, attrEnv, lhs.type, rhs.type);
tree.operator = operators.resolveBinary(tree, optag, lhs.type, rhs.type);
tree.type = tree.operator.type.getReturnType();
return tree;
}
......@@ -601,8 +601,7 @@ public class Lower extends TreeTranslator {
*/
JCAssignOp makeAssignop(JCTree.Tag optag, JCTree lhs, JCTree rhs) {
JCAssignOp tree = make.Assignop(optag, lhs, rhs);
tree.operator = rs.resolveBinaryOperator(
make_pos, tree.getTag().noAssignOp(), attrEnv, lhs.type, rhs.type);
tree.operator = operators.resolveBinary(tree, tree.getTag().noAssignOp(), lhs.type, rhs.type);
tree.type = lhs.type;
return tree;
}
......@@ -3193,9 +3192,8 @@ public class Lower extends TreeTranslator {
// tree.lhs. However, we can still get the
// unerased type of tree.lhs as it is stored
// in tree.type in Attr.
Symbol newOperator = rs.resolveBinaryOperator(tree.pos(),
Symbol newOperator = operators.resolveBinary(tree,
newTag,
attrEnv,
tree.type,
tree.rhs.type);
JCExpression expr = (JCExpression)lhs;
......
......@@ -828,7 +828,7 @@ compiler.err.not.stmt=\
compiler.err.not.encl.class=\
not an enclosing class: {0}
# 0: name, 1: type, 2: unused
# 0: name, 1: type
compiler.err.operator.cant.be.applied=\
bad operand type {1} for unary operator ''{0}''
......
......@@ -51,62 +51,6 @@ import static com.sun.tools.javac.tree.JCTree.Tag.SYNCHRONIZED;
* deletion without notice.</b>
*/
public class TreeInfo {
protected static final Context.Key<TreeInfo> treeInfoKey = new Context.Key<>();
public static TreeInfo instance(Context context) {
TreeInfo instance = context.get(treeInfoKey);
if (instance == null)
instance = new TreeInfo(context);
return instance;
}
/** The names of all operators.
*/
private Name[] opname = new Name[Tag.getNumberOfOperators()];
private void setOpname(Tag tag, String name, Names names) {
setOpname(tag, names.fromString(name));
}
private void setOpname(Tag tag, Name name) {
opname[tag.operatorIndex()] = name;
}
private TreeInfo(Context context) {
context.put(treeInfoKey, this);
Names names = Names.instance(context);
/* Internally we use +++, --- for unary +, - to reduce +, - operators
* overloading
*/
setOpname(POS, "+++", names);
setOpname(NEG, "---", names);
setOpname(NOT, "!", names);
setOpname(COMPL, "~", names);
setOpname(PREINC, "++", names);
setOpname(PREDEC, "--", names);
setOpname(POSTINC, "++", names);
setOpname(POSTDEC, "--", names);
setOpname(NULLCHK, "<*nullchk*>", names);
setOpname(OR, "||", names);
setOpname(AND, "&&", names);
setOpname(EQ, "==", names);
setOpname(NE, "!=", names);
setOpname(LT, "<", names);
setOpname(GT, ">", names);
setOpname(LE, "<=", names);
setOpname(GE, ">=", names);
setOpname(BITOR, "|", names);
setOpname(BITXOR, "^", names);
setOpname(BITAND, "&", names);
setOpname(SL, "<<", names);
setOpname(SR, ">>", names);
setOpname(USR, ">>>", names);
setOpname(PLUS, "+", names);
setOpname(MINUS, names.hyphen);
setOpname(MUL, names.asterisk);
setOpname(DIV, names.slash);
setOpname(MOD, "%", names);
}
public static List<JCExpression> args(JCTree t) {
switch (t.getTag()) {
......@@ -119,12 +63,6 @@ public class TreeInfo {
}
}
/** Return name of operator with given tree tag.
*/
public Name operatorName(JCTree.Tag tag) {
return opname[tag.operatorIndex()];
}
/** Is tree a constructor declaration?
*/
public static boolean isConstructor(JCTree tree) {
......
T7102515.java:9:41: compiler.err.operator.cant.be.applied.1: +, T7102515, T7102515
T7102515.java:10:32: compiler.err.operator.cant.be.applied: ++, T7102515, null
T7102515.java:10:32: compiler.err.operator.cant.be.applied: ++, T7102515
2 errors
......@@ -24,5 +24,5 @@
// key: compiler.err.incomparable.types
class X {
boolean b = (this == 1);
boolean b = (this == "");
}
NullAppend.java:11:16: compiler.err.operator.cant.be.applied.1: +, compiler.misc.type.null, compiler.misc.type.null
NullAppend.java:11:21: compiler.err.operator.cant.be.applied.1: +, compiler.misc.type.null, compiler.misc.type.null
1 error
NullAppend2.java:10:16: compiler.err.operator.cant.be.applied.1: +, compiler.misc.type.null, int
NullAppend2.java:10:21: compiler.err.operator.cant.be.applied.1: +, compiler.misc.type.null, int
1 error
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
@TraceResolve
class PrimitiveBinopOverload {
@Candidate(applicable=Phase.BASIC, mostSpecific=true)
int _plus(int x, int y) { return -1; }
@Candidate(applicable=Phase.BASIC)
long _plus(long x, long y) { return -1; }
@Candidate(applicable=Phase.BASIC)
float _plus(float x, float y) { return -1; }
@Candidate(applicable=Phase.BASIC)
double _plus(double x, double y) { return -1; }
//not a candidate
Object _plus(Object x, Object y) { return -1; }
@Candidate(applicable= { Phase.BASIC, Phase.BOX }, mostSpecific=true)
int _minus(int x, int y) { return -1; }
@Candidate(applicable= { Phase.BASIC, Phase.BOX })
long _minus(long x, long y) { return -1; }
@Candidate(applicable= { Phase.BASIC, Phase.BOX })
float _minus(float x, float y) { return -1; }
@Candidate(applicable= { Phase.BASIC, Phase.BOX })
double _minus(double x, double y) { return -1; }
@Candidate(applicable= { Phase.BASIC, Phase.BOX }, mostSpecific=true)
int _mul(int x, int y) { return -1; }
@Candidate(applicable= { Phase.BASIC, Phase.BOX })
long _mul(long x, long y) { return -1; }
@Candidate(applicable= { Phase.BASIC, Phase.BOX })
float _mul(float x, float y) { return -1; }
@Candidate(applicable= { Phase.BASIC, Phase.BOX })
double _mul(double x, double y) { return -1; }
@Candidate(applicable= { Phase.BASIC, Phase.BOX }, mostSpecific=true)
int _div(int x, int y) { return -1; }
@Candidate(applicable= { Phase.BASIC, Phase.BOX })
long _div(long x, long y) { return -1; }
@Candidate(applicable= { Phase.BASIC, Phase.BOX })
float _div(float x, float y) { return -1; }
@Candidate(applicable= { Phase.BASIC, Phase.BOX })
double _div(double x, double y) { return -1; }
{
int i1 = 1 + 1;
int i2 = 5 - new Integer(3);
int i3 = new Integer(5) * 3;
int i4 = new Integer(6) / new Integer(2);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册