--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Operators.java Fri Jul 29 12:27:08 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Operators.java Mon Aug 01 08:36:02 2016 -0700
@@ -95,6 +95,7 @@
names = Names.instance(context);
log = Log.instance(context);
types = Types.instance(context);
+ noOpSymbol = new OperatorSymbol(names.empty, Type.noType, -1, syms.noSymbol);
initOperatorNames();
initUnaryOperators();
initBinaryOperators();
@@ -145,7 +146,7 @@
/**
* Entry point for resolving a unary operator given an operator tag and an argument type.
*/
- Symbol resolveUnary(DiagnosticPosition pos, JCTree.Tag tag, Type op) {
+ OperatorSymbol resolveUnary(DiagnosticPosition pos, JCTree.Tag tag, Type op) {
return resolve(tag,
unaryOperators,
unop -> unop.test(op),
@@ -156,7 +157,7 @@
/**
* Entry point for resolving a binary operator given an operator tag and a pair of argument types.
*/
- Symbol resolveBinary(DiagnosticPosition pos, JCTree.Tag tag, Type op1, Type op2) {
+ OperatorSymbol resolveBinary(DiagnosticPosition pos, JCTree.Tag tag, Type op1, Type op2) {
return resolve(tag,
binaryOperators,
binop -> binop.test(op1, op2),
@@ -169,8 +170,8 @@
* map. If there's a matching operator, its resolve routine is called and the result is returned;
* otherwise the result of a fallback function is returned.
*/
- private <O> Symbol resolve(Tag tag, Map<Name, List<O>> opMap, Predicate<O> opTestFunc,
- Function<O, Symbol> resolveFunc, Supplier<Symbol> noResultFunc) {
+ private <O> OperatorSymbol resolve(Tag tag, Map<Name, List<O>> opMap, Predicate<O> opTestFunc,
+ Function<O, OperatorSymbol> resolveFunc, Supplier<OperatorSymbol> noResultFunc) {
return opMap.get(operatorName(tag)).stream()
.filter(opTestFunc)
.map(resolveFunc)
@@ -181,7 +182,7 @@
/**
* Creates an operator symbol.
*/
- private Symbol makeOperator(Name name, List<OperatorType> formals, OperatorType res, int... opcodes) {
+ private OperatorSymbol makeOperator(Name name, List<OperatorType> formals, OperatorType res, int... opcodes) {
MethodType opType = new MethodType(
formals.stream()
.map(o -> o.asType(syms))
@@ -201,10 +202,14 @@
((opcodes[0] << ByteCodes.preShift) | opcodes[1]);
}
+ /** A symbol that stands for a missing operator.
+ */
+ public final OperatorSymbol noOpSymbol;
+
/**
* Report an operator lookup error.
*/
- private Symbol reportErrorIfNeeded(DiagnosticPosition pos, Tag tag, Type... args) {
+ private OperatorSymbol reportErrorIfNeeded(DiagnosticPosition pos, Tag tag, Type... args) {
if (Stream.of(args).noneMatch(Type::isErroneous)) {
Name opName = operatorName(tag);
JCDiagnostic.Error opError = (args.length) == 1 ?
@@ -212,7 +217,7 @@
Errors.OperatorCantBeApplied1(opName, args[0], args[1]);
log.error(pos, opError);
}
- return syms.noSymbol;
+ return noOpSymbol;
}
/**
@@ -263,10 +268,10 @@
final Name name;
/** The list of symbols associated with this operator (lazily populated). */
- Optional<Symbol[]> alternatives = Optional.empty();
+ Optional<OperatorSymbol[]> alternatives = Optional.empty();
/** An array of operator symbol suppliers (used to lazily populate the symbol list). */
- List<Supplier<Symbol>> operatorSuppliers = List.nil();
+ List<Supplier<OperatorSymbol>> operatorSuppliers = List.nil();
@SuppressWarnings("varargs")
OperatorHelper(Tag tag) {
@@ -278,21 +283,21 @@
* using an applicability predicate; if the test suceeds that same operator is returned,
* otherwise a dummy symbol is returned.
*/
- final Symbol doLookup(Predicate<Symbol> applicabilityTest) {
+ final OperatorSymbol doLookup(Predicate<OperatorSymbol> applicabilityTest) {
return Stream.of(alternatives.orElseGet(this::initOperators))
.filter(applicabilityTest)
.findFirst()
- .orElse(syms.noSymbol);
+ .orElse(noOpSymbol);
}
/**
* This routine performs lazy instantiation of the operator symbols supported by this helper.
* After initialization is done, the suppliers are cleared, to free up memory.
*/
- private Symbol[] initOperators() {
- Symbol[] operators = operatorSuppliers.stream()
+ private OperatorSymbol[] initOperators() {
+ OperatorSymbol[] operators = operatorSuppliers.stream()
.map(op -> op.get())
- .toArray(Symbol[]::new);
+ .toArray(OperatorSymbol[]::new);
alternatives = Optional.of(operators);
operatorSuppliers = null; //let GC do its work
return operators;
@@ -311,10 +316,10 @@
/**
* This routine implements the unary operator lookup process. It customizes the behavior
* of the shared lookup routine in {@link OperatorHelper}, by using an unary applicability test
- * (see {@link UnaryOperatorHelper#isUnaryOperatorApplicable(OperatorSymbol, Type)}
+ * (see {@link UnaryOperatorHelper#isUnaryOperatorApplicable(OperatorOperatorSymbol, Type)}
*/
- final Symbol doLookup(Type t) {
- return doLookup(op -> isUnaryOperatorApplicable((OperatorSymbol)op, t));
+ final OperatorSymbol doLookup(Type t) {
+ return doLookup(op -> isUnaryOperatorApplicable(op, t));
}
/**
@@ -336,7 +341,7 @@
* This method will be overridden by unary operator helpers to provide custom resolution
* logic.
*/
- abstract Symbol resolve(Type t);
+ abstract OperatorSymbol resolve(Type t);
}
abstract class BinaryOperatorHelper extends OperatorHelper implements BiPredicate<Type, Type> {
@@ -350,8 +355,8 @@
* of the shared lookup routine in {@link OperatorHelper}, by using an unary applicability test
* (see {@link BinaryOperatorHelper#isBinaryOperatorApplicable(OperatorSymbol, Type, Type)}
*/
- final Symbol doLookup(Type t1, Type t2) {
- return doLookup(op -> isBinaryOperatorApplicable((OperatorSymbol)op, t1, t2));
+ final OperatorSymbol doLookup(Type t1, Type t2) {
+ return doLookup(op -> isBinaryOperatorApplicable(op, t1, t2));
}
/**
@@ -375,7 +380,7 @@
* This method will be overridden by binary operator helpers to provide custom resolution
* logic.
*/
- abstract Symbol resolve(Type t1, Type t2);
+ abstract OperatorSymbol resolve(Type t1, Type t2);
}
/**
@@ -393,7 +398,7 @@
}
@Override
- public Symbol resolve(Type arg) {
+ public OperatorSymbol resolve(Type arg) {
return doLookup(syms.objectType);
}
}
@@ -421,7 +426,7 @@
}
@Override
- public Symbol resolve(Type arg) {
+ public OperatorSymbol resolve(Type arg) {
return doLookup(unaryPromotion(arg));
}
}
@@ -442,7 +447,7 @@
}
@Override
- public Symbol resolve(Type arg) {
+ public OperatorSymbol resolve(Type arg) {
return doLookup(syms.booleanType);
}
}
@@ -458,7 +463,7 @@
}
@Override
- public Symbol resolve(Type arg) {
+ public OperatorSymbol resolve(Type arg) {
return doLookup(types.unboxedTypeOrType(arg));
}
}
@@ -481,7 +486,7 @@
}
@Override
- public Symbol resolve(Type arg1, Type arg2) {
+ public OperatorSymbol resolve(Type arg1, Type arg2) {
Type t = binaryPromotion(arg1, arg2);
return doLookup(t, t);
}
@@ -504,7 +509,7 @@
}
@Override
- public Symbol resolve(Type arg1, Type arg2) {
+ public OperatorSymbol resolve(Type arg1, Type arg2) {
return doLookup(syms.booleanType, syms.booleanType);
}
@@ -527,7 +532,7 @@
}
@Override
- public Symbol resolve(Type arg1, Type arg2) {
+ public OperatorSymbol resolve(Type arg1, Type arg2) {
return doLookup(stringPromotion(arg1), stringPromotion(arg2));
}
@@ -570,7 +575,7 @@
}
@Override
- public Symbol resolve(Type arg1, Type arg2) {
+ public OperatorSymbol resolve(Type arg1, Type arg2) {
return doLookup(unaryPromotion(arg1), unaryPromotion(arg2));
}
@@ -613,7 +618,7 @@
}
@Override
- public Symbol resolve(Type t1, Type t2) {
+ public OperatorSymbol resolve(Type t1, Type t2) {
ComparisonKind kind = getKind(t1, t2);
Type t = (kind == ComparisonKind.NUMERIC_OR_BOOLEAN) ?
binaryPromotion(t1, t2) :
@@ -798,12 +803,12 @@
.addBinaryOperator(BOOLEAN, BOOLEAN, BOOLEAN, bool_or));
}
- Symbol lookupBinaryOp(Predicate<Symbol> applicabilityTest) {
+ OperatorSymbol lookupBinaryOp(Predicate<OperatorSymbol> applicabilityTest) {
return binaryOperators.values().stream()
.flatMap(List::stream)
.map(helper -> helper.doLookup(applicabilityTest))
.distinct()
- .filter(sym -> sym != syms.noSymbol)
+ .filter(sym -> sym != noOpSymbol)
.findFirst().get();
}