mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-20 11:04:34 +02:00
Merge
This commit is contained in:
commit
15cdbd1aa0
52 changed files with 2108 additions and 319 deletions
|
@ -87,16 +87,17 @@ public class Kinds {
|
|||
|
||||
/** Kinds for erroneous symbols that complement the above
|
||||
*/
|
||||
public static final int ERRONEOUS = 1 << 7;
|
||||
public static final int AMBIGUOUS = ERRONEOUS+1; // ambiguous reference
|
||||
public static final int HIDDEN = ERRONEOUS+2; // hidden method or field
|
||||
public static final int STATICERR = ERRONEOUS+3; // nonstatic member from static context
|
||||
public static final int MISSING_ENCL = ERRONEOUS+4; // missing enclosing class
|
||||
public static final int ABSENT_VAR = ERRONEOUS+5; // missing variable
|
||||
public static final int WRONG_MTHS = ERRONEOUS+6; // methods with wrong arguments
|
||||
public static final int WRONG_MTH = ERRONEOUS+7; // one method with wrong arguments
|
||||
public static final int ABSENT_MTH = ERRONEOUS+8; // missing method
|
||||
public static final int ABSENT_TYP = ERRONEOUS+9; // missing type
|
||||
public static final int ERRONEOUS = 1 << 7;
|
||||
public static final int AMBIGUOUS = ERRONEOUS + 1; // ambiguous reference
|
||||
public static final int HIDDEN = ERRONEOUS + 2; // hidden method or field
|
||||
public static final int STATICERR = ERRONEOUS + 3; // nonstatic member from static context
|
||||
public static final int MISSING_ENCL = ERRONEOUS + 4; // missing enclosing class
|
||||
public static final int ABSENT_VAR = ERRONEOUS + 5; // missing variable
|
||||
public static final int WRONG_MTHS = ERRONEOUS + 6; // methods with wrong arguments
|
||||
public static final int WRONG_MTH = ERRONEOUS + 7; // one method with wrong arguments
|
||||
public static final int ABSENT_MTH = ERRONEOUS + 8; // missing method
|
||||
public static final int ABSENT_TYP = ERRONEOUS + 9; // missing type
|
||||
public static final int WRONG_STATICNESS = ERRONEOUS + 10; // wrong staticness for method references
|
||||
|
||||
public enum KindName implements Formattable {
|
||||
ANNOTATION("kindname.annotation"),
|
||||
|
@ -231,14 +232,14 @@ public class Kinds {
|
|||
return KindName.CLASS;
|
||||
}
|
||||
|
||||
/** A KindName representing the kind of a a missing symbol, given an
|
||||
/** A KindName representing the kind of a missing symbol, given an
|
||||
* error kind.
|
||||
* */
|
||||
public static KindName absentKind(int kind) {
|
||||
switch (kind) {
|
||||
case ABSENT_VAR:
|
||||
return KindName.VAR;
|
||||
case WRONG_MTHS: case WRONG_MTH: case ABSENT_MTH:
|
||||
case WRONG_MTHS: case WRONG_MTH: case ABSENT_MTH: case WRONG_STATICNESS:
|
||||
return KindName.METHOD;
|
||||
case ABSENT_TYP:
|
||||
return KindName.CLASS;
|
||||
|
|
|
@ -244,7 +244,7 @@ public class Types {
|
|||
public Type visitClassType(ClassType t, Symbol sym) {
|
||||
if (t.tsym == sym)
|
||||
return t;
|
||||
Type base = asSuper(sym.type, t);
|
||||
Type base = asSuper(sym.type, t.tsym);
|
||||
if (base == null)
|
||||
return null;
|
||||
ListBuffer<Type> from = new ListBuffer<Type>();
|
||||
|
@ -687,7 +687,7 @@ public class Types {
|
|||
(t.flags() & SYNTHETIC) == 0;
|
||||
}
|
||||
};
|
||||
private boolean pendingBridges(ClassSymbol origin, TypeSymbol sym) {
|
||||
private boolean pendingBridges(ClassSymbol origin, TypeSymbol s) {
|
||||
//a symbol will be completed from a classfile if (a) symbol has
|
||||
//an associated file object with CLASS kind and (b) the symbol has
|
||||
//not been entered
|
||||
|
@ -696,11 +696,11 @@ public class Types {
|
|||
enter.getEnv(origin) == null) {
|
||||
return false;
|
||||
}
|
||||
if (origin == sym) {
|
||||
if (origin == s) {
|
||||
return true;
|
||||
}
|
||||
for (Type t : interfaces(origin.type)) {
|
||||
if (pendingBridges((ClassSymbol)t.tsym, sym)) {
|
||||
if (pendingBridges((ClassSymbol)t.tsym, s)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -761,7 +761,7 @@ public class Types {
|
|||
} else if (t.hasTag(TYPEVAR)) {
|
||||
return isSubtypeUnchecked(t.getUpperBound(), s, warn);
|
||||
} else if (!s.isRaw()) {
|
||||
Type t2 = asSuper(t, s);
|
||||
Type t2 = asSuper(t, s.tsym);
|
||||
if (t2 != null && t2.isRaw()) {
|
||||
if (isReifiable(s)) {
|
||||
warn.silentWarn(LintCategory.UNCHECKED);
|
||||
|
@ -914,7 +914,7 @@ public class Types {
|
|||
|
||||
@Override
|
||||
public Boolean visitClassType(ClassType t, Type s) {
|
||||
Type sup = asSuper(t, s);
|
||||
Type sup = asSuper(t, s.tsym);
|
||||
return sup != null
|
||||
&& sup.tsym == s.tsym
|
||||
// You're not allowed to write
|
||||
|
@ -1935,42 +1935,30 @@ public class Types {
|
|||
* @param t a type
|
||||
* @param sym a symbol
|
||||
*/
|
||||
public Type asSuper(Type t, Symbol s) {
|
||||
return asSuper(t, s.type);
|
||||
}
|
||||
|
||||
public Type asSuper(Type t, Type s) {
|
||||
return asSuper.visit(t, s);
|
||||
public Type asSuper(Type t, Symbol sym) {
|
||||
return asSuper.visit(t, sym);
|
||||
}
|
||||
// where
|
||||
private SimpleVisitor<Type,Type> asSuper = new SimpleVisitor<Type,Type>() {
|
||||
private SimpleVisitor<Type,Symbol> asSuper = new SimpleVisitor<Type,Symbol>() {
|
||||
|
||||
public Type visitType(Type t, Type s) {
|
||||
public Type visitType(Type t, Symbol sym) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type visitClassType(ClassType t, Type s) {
|
||||
if (t.tsym == s.tsym)
|
||||
public Type visitClassType(ClassType t, Symbol sym) {
|
||||
if (t.tsym == sym)
|
||||
return t;
|
||||
|
||||
Type st = supertype(t);
|
||||
|
||||
switch(st.getTag()) {
|
||||
default: break;
|
||||
case CLASS:
|
||||
case ARRAY:
|
||||
case TYPEVAR:
|
||||
case ERROR: {
|
||||
Type x = asSuper(st, s);
|
||||
if (st.hasTag(CLASS) || st.hasTag(TYPEVAR) || st.hasTag(ERROR)) {
|
||||
Type x = asSuper(st, sym);
|
||||
if (x != null)
|
||||
return x;
|
||||
} break;
|
||||
}
|
||||
|
||||
if ((s.tsym.flags() & INTERFACE) != 0) {
|
||||
if ((sym.flags() & INTERFACE) != 0) {
|
||||
for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) {
|
||||
Type x = asSuper(l.head, s);
|
||||
Type x = asSuper(l.head, sym);
|
||||
if (x != null)
|
||||
return x;
|
||||
}
|
||||
|
@ -1979,20 +1967,22 @@ public class Types {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Type visitArrayType(ArrayType t, Type s) {
|
||||
return isSubtype(t, s) ? s : null;
|
||||
public Type visitArrayType(ArrayType t, Symbol sym) {
|
||||
return isSubtype(t, sym.type) ? sym.type : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type visitTypeVar(TypeVar t, Type s) {
|
||||
if (t.tsym == s.tsym)
|
||||
public Type visitTypeVar(TypeVar t, Symbol sym) {
|
||||
if (t.tsym == sym)
|
||||
return t;
|
||||
else
|
||||
return asSuper(t.bound, s);
|
||||
return asSuper(t.bound, sym);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type visitErrorType(ErrorType t, Type s) { return t; }
|
||||
public Type visitErrorType(ErrorType t, Symbol sym) {
|
||||
return t;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -3573,9 +3563,9 @@ public class Types {
|
|||
//step 3 - for each element G in MEC, compute lci(Inv(G))
|
||||
List<Type> candidates = List.nil();
|
||||
for (Type erasedSupertype : mec) {
|
||||
List<Type> lci = List.of(asSuper(ts.head, erasedSupertype));
|
||||
List<Type> lci = List.of(asSuper(ts.head, erasedSupertype.tsym));
|
||||
for (Type t : ts) {
|
||||
lci = intersect(lci, List.of(asSuper(t, erasedSupertype)));
|
||||
lci = intersect(lci, List.of(asSuper(t, erasedSupertype.tsym)));
|
||||
}
|
||||
candidates = candidates.appendList(lci);
|
||||
}
|
||||
|
@ -3995,7 +3985,7 @@ public class Types {
|
|||
// The arguments to the supers could be unified here to
|
||||
// get a more accurate analysis
|
||||
while (commonSupers.nonEmpty()) {
|
||||
Type t1 = asSuper(from, commonSupers.head);
|
||||
Type t1 = asSuper(from, commonSupers.head.tsym);
|
||||
Type t2 = commonSupers.head; // same as asSuper(to, commonSupers.head.tsym);
|
||||
if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments()))
|
||||
return false;
|
||||
|
@ -4026,7 +4016,7 @@ public class Types {
|
|||
from = target;
|
||||
}
|
||||
Assert.check((from.tsym.flags() & FINAL) != 0);
|
||||
Type t1 = asSuper(from, to);
|
||||
Type t1 = asSuper(from, to.tsym);
|
||||
if (t1 == null) return false;
|
||||
Type t2 = to;
|
||||
if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments()))
|
||||
|
|
|
@ -255,6 +255,9 @@ public class Annotate {
|
|||
: attr.attribType(a.annotationType, env));
|
||||
a.type = chk.checkType(a.annotationType.pos(), at, expected);
|
||||
if (a.type.isErroneous()) {
|
||||
// Need to make sure nested (anno)trees does not have null as .type
|
||||
attr.postAttr(a);
|
||||
|
||||
if (typeAnnotation) {
|
||||
return new Attribute.TypeCompound(a.type, List.<Pair<MethodSymbol,Attribute>>nil(),
|
||||
new TypeAnnotationPosition());
|
||||
|
@ -265,6 +268,10 @@ public class Annotate {
|
|||
if ((a.type.tsym.flags() & Flags.ANNOTATION) == 0) {
|
||||
log.error(a.annotationType.pos(),
|
||||
"not.annotation.type", a.type.toString());
|
||||
|
||||
// Need to make sure nested (anno)trees does not have null as .type
|
||||
attr.postAttr(a);
|
||||
|
||||
if (typeAnnotation) {
|
||||
return new Attribute.TypeCompound(a.type, List.<Pair<MethodSymbol,Attribute>>nil(), null);
|
||||
} else {
|
||||
|
@ -278,7 +285,7 @@ public class Annotate {
|
|||
Assign(make.Ident(names.value), args.head);
|
||||
}
|
||||
ListBuffer<Pair<MethodSymbol,Attribute>> buf =
|
||||
new ListBuffer<Pair<MethodSymbol,Attribute>>();
|
||||
new ListBuffer<>();
|
||||
for (List<JCExpression> tl = args; tl.nonEmpty(); tl = tl.tail) {
|
||||
JCExpression t = tl.head;
|
||||
if (!t.hasTag(ASSIGN)) {
|
||||
|
@ -304,8 +311,7 @@ public class Annotate {
|
|||
Type result = method.type.getReturnType();
|
||||
Attribute value = enterAttributeValue(result, assign.rhs, env);
|
||||
if (!method.type.isErroneous())
|
||||
buf.append(new Pair<MethodSymbol,Attribute>
|
||||
((MethodSymbol)method, value));
|
||||
buf.append(new Pair<>((MethodSymbol)method, value));
|
||||
t.type = result;
|
||||
}
|
||||
if (typeAnnotation) {
|
||||
|
|
|
@ -58,7 +58,6 @@ import static com.sun.tools.javac.code.Kinds.*;
|
|||
import static com.sun.tools.javac.code.Kinds.ERRONEOUS;
|
||||
import static com.sun.tools.javac.code.TypeTag.*;
|
||||
import static com.sun.tools.javac.code.TypeTag.WILDCARD;
|
||||
import static com.sun.tools.javac.code.TypeTag.ARRAY;
|
||||
import static com.sun.tools.javac.tree.JCTree.Tag.*;
|
||||
|
||||
/** This is the main context-dependent analysis phase in GJC. It
|
||||
|
@ -806,44 +805,33 @@ public class Attr extends JCTree.Visitor {
|
|||
Type t = tree.type != null ?
|
||||
tree.type :
|
||||
attribType(tree, env);
|
||||
return checkBase(t, tree, env, classExpected, interfaceExpected, false, checkExtensible);
|
||||
return checkBase(t, tree, env, classExpected, interfaceExpected, checkExtensible);
|
||||
}
|
||||
Type checkBase(Type t,
|
||||
JCTree tree,
|
||||
Env<AttrContext> env,
|
||||
boolean classExpected,
|
||||
boolean interfacesOnlyExpected,
|
||||
boolean interfacesOrArraysExpected,
|
||||
boolean interfaceExpected,
|
||||
boolean checkExtensible) {
|
||||
if (t.isErroneous())
|
||||
return t;
|
||||
if (t.hasTag(TYPEVAR) && !classExpected &&
|
||||
!interfacesOrArraysExpected && !interfacesOnlyExpected) {
|
||||
if (t.hasTag(TYPEVAR) && !classExpected && !interfaceExpected) {
|
||||
// check that type variable is already visible
|
||||
if (t.getUpperBound() == null) {
|
||||
log.error(tree.pos(), "illegal.forward.ref");
|
||||
return types.createErrorType(t);
|
||||
}
|
||||
} else if (classExpected) {
|
||||
t = chk.checkClassType(tree.pos(), t, checkExtensible|!allowGenerics);
|
||||
} else {
|
||||
t = chk.checkClassOrArrayType(tree.pos(), t,
|
||||
checkExtensible|!allowGenerics);
|
||||
t = chk.checkClassType(tree.pos(), t, checkExtensible|!allowGenerics);
|
||||
}
|
||||
if (interfacesOnlyExpected && !t.tsym.isInterface()) {
|
||||
if (interfaceExpected && (t.tsym.flags() & INTERFACE) == 0) {
|
||||
log.error(tree.pos(), "intf.expected.here");
|
||||
// return errType is necessary since otherwise there might
|
||||
// be undetected cycles which cause attribution to loop
|
||||
return types.createErrorType(t);
|
||||
} else if (interfacesOrArraysExpected &&
|
||||
!(t.tsym.isInterface() || t.getTag() == ARRAY)) {
|
||||
log.error(tree.pos(), "intf.or.array.expected.here");
|
||||
// return errType is necessary since otherwise there might
|
||||
// be undetected cycles which cause attribution to loop
|
||||
return types.createErrorType(t);
|
||||
} else if (checkExtensible &&
|
||||
classExpected &&
|
||||
t.tsym.isInterface()) {
|
||||
(t.tsym.flags() & INTERFACE) != 0) {
|
||||
log.error(tree.pos(), "no.intf.expected.here");
|
||||
return types.createErrorType(t);
|
||||
}
|
||||
|
@ -855,12 +843,6 @@ public class Attr extends JCTree.Visitor {
|
|||
chk.checkNonCyclic(tree.pos(), t);
|
||||
return t;
|
||||
}
|
||||
//where
|
||||
private Object asTypeParam(Type t) {
|
||||
return (t.hasTag(TYPEVAR))
|
||||
? diags.fragment("type.parameter", t)
|
||||
: t;
|
||||
}
|
||||
|
||||
Type attribIdentAsEnumType(Env<AttrContext> env, JCIdent id) {
|
||||
Assert.check((env.enclClass.sym.flags() & ENUM) != 0);
|
||||
|
@ -2254,7 +2236,8 @@ public class Attr extends JCTree.Visitor {
|
|||
// empty annotations, if only declaration annotations were given.
|
||||
// This method will raise an error for such a type.
|
||||
for (JCAnnotation ai : annotations) {
|
||||
if (typeAnnotations.annotationType(ai.attribute, sym) == TypeAnnotations.AnnotationType.DECLARATION) {
|
||||
if (!ai.type.isErroneous() &&
|
||||
typeAnnotations.annotationType(ai.attribute, sym) == TypeAnnotations.AnnotationType.DECLARATION) {
|
||||
log.error(ai.pos(), "annotation.type.not.applicable");
|
||||
}
|
||||
}
|
||||
|
@ -2714,9 +2697,10 @@ public class Attr extends JCTree.Visitor {
|
|||
Pair<Symbol, Resolve.ReferenceLookupHelper> refResult = null;
|
||||
List<Type> saved_undet = resultInfo.checkContext.inferenceContext().save();
|
||||
try {
|
||||
refResult = rs.resolveMemberReference(that.pos(), localEnv, that, that.expr.type,
|
||||
that.name, argtypes, typeargtypes, true, referenceCheck,
|
||||
resultInfo.checkContext.inferenceContext());
|
||||
refResult = rs.resolveMemberReference(localEnv, that, that.expr.type,
|
||||
that.name, argtypes, typeargtypes, referenceCheck,
|
||||
resultInfo.checkContext.inferenceContext(),
|
||||
resultInfo.checkContext.deferredAttrContext().mode);
|
||||
} finally {
|
||||
resultInfo.checkContext.inferenceContext().rollback(saved_undet);
|
||||
}
|
||||
|
@ -2736,6 +2720,7 @@ public class Attr extends JCTree.Visitor {
|
|||
case HIDDEN:
|
||||
case STATICERR:
|
||||
case MISSING_ENCL:
|
||||
case WRONG_STATICNESS:
|
||||
targetError = true;
|
||||
break;
|
||||
default:
|
||||
|
@ -2787,26 +2772,6 @@ public class Attr extends JCTree.Visitor {
|
|||
chk.checkRaw(that.expr, localEnv);
|
||||
}
|
||||
|
||||
if (!that.kind.isUnbound() &&
|
||||
that.getMode() == ReferenceMode.INVOKE &&
|
||||
TreeInfo.isStaticSelector(that.expr, names) &&
|
||||
!that.sym.isStatic()) {
|
||||
log.error(that.expr.pos(), "invalid.mref", Kinds.kindName(that.getMode()),
|
||||
diags.fragment("non-static.cant.be.ref", Kinds.kindName(refSym), refSym));
|
||||
result = that.type = types.createErrorType(target);
|
||||
return;
|
||||
}
|
||||
|
||||
if (that.kind.isUnbound() &&
|
||||
that.getMode() == ReferenceMode.INVOKE &&
|
||||
TreeInfo.isStaticSelector(that.expr, names) &&
|
||||
that.sym.isStatic()) {
|
||||
log.error(that.expr.pos(), "invalid.mref", Kinds.kindName(that.getMode()),
|
||||
diags.fragment("static.method.in.unbound.lookup", Kinds.kindName(refSym), refSym));
|
||||
result = that.type = types.createErrorType(target);
|
||||
return;
|
||||
}
|
||||
|
||||
if (that.sym.isStatic() && TreeInfo.isStaticSelector(that.expr, names) &&
|
||||
exprType.getTypeArguments().nonEmpty()) {
|
||||
//static ref with class type-args
|
||||
|
@ -3984,7 +3949,7 @@ public class Attr extends JCTree.Visitor {
|
|||
Set<Type> boundSet = new HashSet<Type>();
|
||||
if (bounds.nonEmpty()) {
|
||||
// accept class or interface or typevar as first bound.
|
||||
bounds.head.type = checkBase(bounds.head.type, bounds.head, env, false, false, false, false);
|
||||
bounds.head.type = checkBase(bounds.head.type, bounds.head, env, false, false, false);
|
||||
boundSet.add(types.erasure(bounds.head.type));
|
||||
if (bounds.head.type.isErroneous()) {
|
||||
return bounds.head.type;
|
||||
|
@ -4000,7 +3965,7 @@ public class Attr extends JCTree.Visitor {
|
|||
// if first bound was a class or interface, accept only interfaces
|
||||
// as further bounds.
|
||||
for (JCExpression bound : bounds.tail) {
|
||||
bound.type = checkBase(bound.type, bound, env, false, false, true, false);
|
||||
bound.type = checkBase(bound.type, bound, env, false, true, false);
|
||||
if (bound.type.isErroneous()) {
|
||||
bounds = List.of(bound);
|
||||
}
|
||||
|
@ -4619,9 +4584,8 @@ public class Attr extends JCTree.Visitor {
|
|||
validateAnnotatedType(t, t.type);
|
||||
}
|
||||
repeat = false;
|
||||
} else if (enclTr.getKind() == JCTree.Kind.PRIMITIVE_TYPE) {
|
||||
// This happens in test TargetTypeTest52.java
|
||||
// Is there anything to do?
|
||||
} else if (enclTr.getKind() == JCTree.Kind.PRIMITIVE_TYPE ||
|
||||
enclTr.getKind() == JCTree.Kind.ERRONEOUS) {
|
||||
repeat = false;
|
||||
} else {
|
||||
Assert.error("Unexpected tree: " + enclTr + " with kind: " + enclTr.getKind() +
|
||||
|
|
|
@ -707,37 +707,6 @@ public class Check {
|
|||
return t;
|
||||
}
|
||||
|
||||
// Analog of checkClassType that calls checkClassOrArrayType instead
|
||||
Type checkClassOrArrayType(DiagnosticPosition pos,
|
||||
Type t, boolean noBounds) {
|
||||
t = checkClassOrArrayType(pos, t);
|
||||
if (noBounds && t.isParameterized()) {
|
||||
List<Type> args = t.getTypeArguments();
|
||||
while (args.nonEmpty()) {
|
||||
if (args.head.hasTag(WILDCARD))
|
||||
return typeTagError(pos,
|
||||
diags.fragment("type.req.exact"),
|
||||
args.head);
|
||||
args = args.tail;
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
/** Check that type is a reifiable class, interface or array type.
|
||||
* @param pos Position to be used for error reporting.
|
||||
* @param t The type to be checked.
|
||||
*/
|
||||
Type checkReifiableReferenceType(DiagnosticPosition pos, Type t) {
|
||||
t = checkClassOrArrayType(pos, t);
|
||||
if (!t.isErroneous() && !types.isReifiable(t)) {
|
||||
log.error(pos, "illegal.generic.type.for.instof");
|
||||
return types.createErrorType(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.
|
||||
|
@ -2253,9 +2222,6 @@ public class Check {
|
|||
seen = seen.prepend(tv);
|
||||
for (Type b : types.getBounds(tv))
|
||||
checkNonCyclic1(pos, b, seen);
|
||||
} else if (t.hasTag(ARRAY)) {
|
||||
final ArrayType at = (ArrayType)t.unannotatedType();
|
||||
checkNonCyclic1(pos, at.elemtype, seen);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -643,15 +643,16 @@ public class DeferredAttr extends JCTree.Visitor {
|
|||
}
|
||||
JCMemberReference mref2 = new TreeCopier<Void>(make).copy(tree);
|
||||
mref2.expr = exprTree;
|
||||
Pair<Symbol, ?> lookupRes =
|
||||
rs.resolveMemberReference(tree, localEnv, mref2, exprTree.type,
|
||||
tree.name, argtypes.toList(), null, true, rs.arityMethodCheck, inferenceContext);
|
||||
switch (lookupRes.fst.kind) {
|
||||
Symbol lookupSym =
|
||||
rs.resolveMemberReferenceByArity(localEnv, mref2, exprTree.type,
|
||||
tree.name, argtypes.toList(), inferenceContext);
|
||||
switch (lookupSym.kind) {
|
||||
//note: as argtypes are erroneous types, type-errors must
|
||||
//have been caused by arity mismatch
|
||||
case Kinds.ABSENT_MTH:
|
||||
case Kinds.WRONG_MTH:
|
||||
case Kinds.WRONG_MTHS:
|
||||
case Kinds.WRONG_STATICNESS:
|
||||
checkContext.report(tree, diags.fragment("incompatible.arg.types.in.mref"));
|
||||
}
|
||||
}
|
||||
|
@ -1037,11 +1038,10 @@ public class DeferredAttr extends JCTree.Visitor {
|
|||
attr.memberReferenceQualifierResult(tree));
|
||||
JCMemberReference mref2 = new TreeCopier<Void>(make).copy(tree);
|
||||
mref2.expr = exprTree;
|
||||
Pair<Symbol, ReferenceLookupHelper> lookupRes =
|
||||
rs.resolveMemberReference(tree, localEnv, mref2, exprTree.type,
|
||||
tree.name, List.<Type>nil(), null, true, rs.nilMethodCheck,
|
||||
infer.emptyContext);
|
||||
Symbol res = tree.sym = lookupRes.fst;
|
||||
Symbol res =
|
||||
rs.getMemberReference(tree, localEnv, mref2,
|
||||
exprTree.type, tree.name);
|
||||
tree.sym = res;
|
||||
if (res.kind >= Kinds.ERRONEOUS ||
|
||||
res.type.hasTag(FORALL) ||
|
||||
(res.flags() & Flags.VARARGS) != 0 ||
|
||||
|
|
|
@ -1378,7 +1378,11 @@ public class Lower extends TreeTranslator {
|
|||
ref = make.Ident(sym);
|
||||
args = make.Idents(md.params);
|
||||
} else {
|
||||
ref = make.Select(make.Ident(md.params.head), sym);
|
||||
Symbol msym = sym;
|
||||
if (sym.owner.isInterface()) {
|
||||
msym = msym.clone(types.supertype(accessor.owner.type).tsym);
|
||||
}
|
||||
ref = make.Select(make.Ident(md.params.head), msym);
|
||||
args = make.Idents(md.params.tail);
|
||||
}
|
||||
JCStatement stat; // The statement accessing the private symbol.
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
package com.sun.tools.javac.comp;
|
||||
|
||||
import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
|
||||
import com.sun.tools.javac.api.Formattable.LocalizedString;
|
||||
import com.sun.tools.javac.code.*;
|
||||
import com.sun.tools.javac.code.Symbol.*;
|
||||
|
@ -110,6 +111,9 @@ public class Resolve {
|
|||
SymbolNotFoundError(ABSENT_VAR);
|
||||
methodNotFound = new
|
||||
SymbolNotFoundError(ABSENT_MTH);
|
||||
methodWithCorrectStaticnessNotFound = new
|
||||
SymbolNotFoundError(WRONG_STATICNESS,
|
||||
"method found has incorrect staticness");
|
||||
typeNotFound = new
|
||||
SymbolNotFoundError(ABSENT_TYP);
|
||||
|
||||
|
@ -144,6 +148,7 @@ public class Resolve {
|
|||
*/
|
||||
private final SymbolNotFoundError varNotFound;
|
||||
private final SymbolNotFoundError methodNotFound;
|
||||
private final SymbolNotFoundError methodWithCorrectStaticnessNotFound;
|
||||
private final SymbolNotFoundError typeNotFound;
|
||||
|
||||
public static Resolve instance(Context context) {
|
||||
|
@ -868,6 +873,12 @@ public class Resolve {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This class handles method reference applicability checks; since during
|
||||
* these checks it's sometime possible to have inference variables on
|
||||
* the actual argument types list, the method applicability check must be
|
||||
* extended so that inference variables are 'opened' as needed.
|
||||
*/
|
||||
class MethodReferenceCheck extends AbstractMethodCheck {
|
||||
|
||||
InferenceContext pendingInferenceContext;
|
||||
|
@ -2674,6 +2685,97 @@ public class Resolve {
|
|||
return resolveOperator(pos, optag, env, List.of(left, right));
|
||||
}
|
||||
|
||||
Symbol getMemberReference(DiagnosticPosition pos,
|
||||
Env<AttrContext> env,
|
||||
JCMemberReference referenceTree,
|
||||
Type site,
|
||||
Name name) {
|
||||
|
||||
site = types.capture(site);
|
||||
|
||||
ReferenceLookupHelper lookupHelper = makeReferenceLookupHelper(
|
||||
referenceTree, site, name, List.<Type>nil(), null, VARARITY);
|
||||
|
||||
Env<AttrContext> newEnv = env.dup(env.tree, env.info.dup());
|
||||
Symbol sym = lookupMethod(newEnv, env.tree.pos(), site.tsym,
|
||||
nilMethodCheck, lookupHelper);
|
||||
|
||||
env.info.pendingResolutionPhase = newEnv.info.pendingResolutionPhase;
|
||||
|
||||
return sym;
|
||||
}
|
||||
|
||||
ReferenceLookupHelper makeReferenceLookupHelper(JCMemberReference referenceTree,
|
||||
Type site,
|
||||
Name name,
|
||||
List<Type> argtypes,
|
||||
List<Type> typeargtypes,
|
||||
MethodResolutionPhase maxPhase) {
|
||||
ReferenceLookupHelper result;
|
||||
if (!name.equals(names.init)) {
|
||||
//method reference
|
||||
result =
|
||||
new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
|
||||
} else {
|
||||
if (site.hasTag(ARRAY)) {
|
||||
//array constructor reference
|
||||
result =
|
||||
new ArrayConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
|
||||
} else {
|
||||
//class constructor reference
|
||||
result =
|
||||
new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Symbol resolveMemberReferenceByArity(Env<AttrContext> env,
|
||||
JCMemberReference referenceTree,
|
||||
Type site,
|
||||
Name name,
|
||||
List<Type> argtypes,
|
||||
InferenceContext inferenceContext) {
|
||||
|
||||
boolean isStaticSelector = TreeInfo.isStaticSelector(referenceTree.expr, names);
|
||||
site = types.capture(site);
|
||||
|
||||
ReferenceLookupHelper boundLookupHelper = makeReferenceLookupHelper(
|
||||
referenceTree, site, name, argtypes, null, VARARITY);
|
||||
//step 1 - bound lookup
|
||||
Env<AttrContext> boundEnv = env.dup(env.tree, env.info.dup());
|
||||
Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(), site.tsym,
|
||||
arityMethodCheck, boundLookupHelper);
|
||||
if (isStaticSelector &&
|
||||
!name.equals(names.init) &&
|
||||
!boundSym.isStatic() &&
|
||||
boundSym.kind < ERRONEOUS) {
|
||||
boundSym = methodNotFound;
|
||||
}
|
||||
|
||||
//step 2 - unbound lookup
|
||||
Symbol unboundSym = methodNotFound;
|
||||
ReferenceLookupHelper unboundLookupHelper = null;
|
||||
Env<AttrContext> unboundEnv = env.dup(env.tree, env.info.dup());
|
||||
if (isStaticSelector) {
|
||||
unboundLookupHelper = boundLookupHelper.unboundLookup(inferenceContext);
|
||||
unboundSym = lookupMethod(unboundEnv, env.tree.pos(), site.tsym,
|
||||
arityMethodCheck, unboundLookupHelper);
|
||||
if (unboundSym.isStatic() &&
|
||||
unboundSym.kind < ERRONEOUS) {
|
||||
unboundSym = methodNotFound;
|
||||
}
|
||||
}
|
||||
|
||||
//merge results
|
||||
Symbol bestSym = choose(boundSym, unboundSym);
|
||||
env.info.pendingResolutionPhase = bestSym == unboundSym ?
|
||||
unboundEnv.info.pendingResolutionPhase :
|
||||
boundEnv.info.pendingResolutionPhase;
|
||||
|
||||
return bestSym;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolution of member references is typically done as a single
|
||||
* overload resolution step, where the argument types A are inferred from
|
||||
|
@ -2700,47 +2802,118 @@ public class Resolve {
|
|||
* the type T might be dynamically inferred (i.e. if constructor reference
|
||||
* has a raw qualifier).
|
||||
*/
|
||||
Pair<Symbol, ReferenceLookupHelper> resolveMemberReference(DiagnosticPosition pos,
|
||||
Env<AttrContext> env,
|
||||
Pair<Symbol, ReferenceLookupHelper> resolveMemberReference(Env<AttrContext> env,
|
||||
JCMemberReference referenceTree,
|
||||
Type site,
|
||||
Name name, List<Type> argtypes,
|
||||
Name name,
|
||||
List<Type> argtypes,
|
||||
List<Type> typeargtypes,
|
||||
boolean boxingAllowed,
|
||||
MethodCheck methodCheck,
|
||||
InferenceContext inferenceContext) {
|
||||
MethodResolutionPhase maxPhase = boxingAllowed ? VARARITY : BASIC;
|
||||
InferenceContext inferenceContext,
|
||||
AttrMode mode) {
|
||||
|
||||
site = types.capture(site);
|
||||
|
||||
ReferenceLookupHelper boundLookupHelper;
|
||||
if (!name.equals(names.init)) {
|
||||
//method reference
|
||||
boundLookupHelper =
|
||||
new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
|
||||
} else if (site.hasTag(ARRAY)) {
|
||||
//array constructor reference
|
||||
boundLookupHelper =
|
||||
new ArrayConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
|
||||
} else {
|
||||
//class constructor reference
|
||||
boundLookupHelper =
|
||||
new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase);
|
||||
}
|
||||
ReferenceLookupHelper boundLookupHelper = makeReferenceLookupHelper(
|
||||
referenceTree, site, name, argtypes, typeargtypes, VARARITY);
|
||||
|
||||
//step 1 - bound lookup
|
||||
Env<AttrContext> boundEnv = env.dup(env.tree, env.info.dup());
|
||||
Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(), site.tsym, methodCheck, boundLookupHelper);
|
||||
Symbol origBoundSym;
|
||||
boolean staticErrorForBound = false;
|
||||
MethodResolutionContext boundSearchResolveContext = new MethodResolutionContext();
|
||||
boundSearchResolveContext.methodCheck = methodCheck;
|
||||
Symbol boundSym = origBoundSym = lookupMethod(boundEnv, env.tree.pos(),
|
||||
site.tsym, boundSearchResolveContext, boundLookupHelper);
|
||||
SearchResultKind boundSearchResultKind = SearchResultKind.NOT_APPLICABLE_MATCH;
|
||||
boolean isStaticSelector = TreeInfo.isStaticSelector(referenceTree.expr, names);
|
||||
boolean shouldCheckForStaticness = isStaticSelector &&
|
||||
referenceTree.getMode() == ReferenceMode.INVOKE;
|
||||
if (boundSym.kind != WRONG_MTHS && boundSym.kind != WRONG_MTH) {
|
||||
if (shouldCheckForStaticness) {
|
||||
if (!boundSym.isStatic()) {
|
||||
staticErrorForBound = true;
|
||||
if (hasAnotherApplicableMethod(
|
||||
boundSearchResolveContext, boundSym, true)) {
|
||||
boundSearchResultKind = SearchResultKind.BAD_MATCH_MORE_SPECIFIC;
|
||||
} else {
|
||||
boundSearchResultKind = SearchResultKind.BAD_MATCH;
|
||||
if (boundSym.kind < ERRONEOUS) {
|
||||
boundSym = methodWithCorrectStaticnessNotFound;
|
||||
}
|
||||
}
|
||||
} else if (boundSym.kind < ERRONEOUS) {
|
||||
boundSearchResultKind = SearchResultKind.GOOD_MATCH;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//step 2 - unbound lookup
|
||||
ReferenceLookupHelper unboundLookupHelper = boundLookupHelper.unboundLookup(inferenceContext);
|
||||
Symbol origUnboundSym = null;
|
||||
Symbol unboundSym = methodNotFound;
|
||||
ReferenceLookupHelper unboundLookupHelper = null;
|
||||
Env<AttrContext> unboundEnv = env.dup(env.tree, env.info.dup());
|
||||
Symbol unboundSym = lookupMethod(unboundEnv, env.tree.pos(), site.tsym, methodCheck, unboundLookupHelper);
|
||||
SearchResultKind unboundSearchResultKind = SearchResultKind.NOT_APPLICABLE_MATCH;
|
||||
boolean staticErrorForUnbound = false;
|
||||
if (isStaticSelector) {
|
||||
unboundLookupHelper = boundLookupHelper.unboundLookup(inferenceContext);
|
||||
MethodResolutionContext unboundSearchResolveContext =
|
||||
new MethodResolutionContext();
|
||||
unboundSearchResolveContext.methodCheck = methodCheck;
|
||||
unboundSym = origUnboundSym = lookupMethod(unboundEnv, env.tree.pos(),
|
||||
site.tsym, unboundSearchResolveContext, unboundLookupHelper);
|
||||
|
||||
if (unboundSym.kind != WRONG_MTH && unboundSym.kind != WRONG_MTHS) {
|
||||
if (shouldCheckForStaticness) {
|
||||
if (unboundSym.isStatic()) {
|
||||
staticErrorForUnbound = true;
|
||||
if (hasAnotherApplicableMethod(
|
||||
unboundSearchResolveContext, unboundSym, false)) {
|
||||
unboundSearchResultKind = SearchResultKind.BAD_MATCH_MORE_SPECIFIC;
|
||||
} else {
|
||||
unboundSearchResultKind = SearchResultKind.BAD_MATCH;
|
||||
if (unboundSym.kind < ERRONEOUS) {
|
||||
unboundSym = methodWithCorrectStaticnessNotFound;
|
||||
}
|
||||
}
|
||||
} else if (unboundSym.kind < ERRONEOUS) {
|
||||
unboundSearchResultKind = SearchResultKind.GOOD_MATCH;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//merge results
|
||||
Pair<Symbol, ReferenceLookupHelper> res;
|
||||
Symbol bestSym = choose(boundSym, unboundSym);
|
||||
res = new Pair<Symbol, ReferenceLookupHelper>(bestSym,
|
||||
if (bestSym.kind < ERRONEOUS && (staticErrorForBound || staticErrorForUnbound)) {
|
||||
if (staticErrorForBound) {
|
||||
boundSym = methodWithCorrectStaticnessNotFound;
|
||||
}
|
||||
if (staticErrorForUnbound) {
|
||||
unboundSym = methodWithCorrectStaticnessNotFound;
|
||||
}
|
||||
bestSym = choose(boundSym, unboundSym);
|
||||
}
|
||||
if (bestSym == methodWithCorrectStaticnessNotFound && mode == AttrMode.CHECK) {
|
||||
Symbol symToPrint = origBoundSym;
|
||||
String errorFragmentToPrint = "non-static.cant.be.ref";
|
||||
if (staticErrorForBound && staticErrorForUnbound) {
|
||||
if (unboundSearchResultKind == SearchResultKind.BAD_MATCH_MORE_SPECIFIC) {
|
||||
symToPrint = origUnboundSym;
|
||||
errorFragmentToPrint = "static.method.in.unbound.lookup";
|
||||
}
|
||||
} else {
|
||||
if (!staticErrorForBound) {
|
||||
symToPrint = origUnboundSym;
|
||||
errorFragmentToPrint = "static.method.in.unbound.lookup";
|
||||
}
|
||||
}
|
||||
log.error(referenceTree.expr.pos(), "invalid.mref",
|
||||
Kinds.kindName(referenceTree.getMode()),
|
||||
diags.fragment(errorFragmentToPrint,
|
||||
Kinds.kindName(symToPrint), symToPrint));
|
||||
}
|
||||
res = new Pair<>(bestSym,
|
||||
bestSym == unboundSym ? unboundLookupHelper : boundLookupHelper);
|
||||
env.info.pendingResolutionPhase = bestSym == unboundSym ?
|
||||
unboundEnv.info.pendingResolutionPhase :
|
||||
|
@ -2748,18 +2921,42 @@ public class Resolve {
|
|||
|
||||
return res;
|
||||
}
|
||||
//where
|
||||
private Symbol choose(Symbol s1, Symbol s2) {
|
||||
if (lookupSuccess(s1) && lookupSuccess(s2)) {
|
||||
return ambiguityError(s1, s2);
|
||||
} else if (lookupSuccess(s1) ||
|
||||
(canIgnore(s2) && !canIgnore(s1))) {
|
||||
return s1;
|
||||
} else if (lookupSuccess(s2) ||
|
||||
(canIgnore(s1) && !canIgnore(s2))) {
|
||||
return s2;
|
||||
|
||||
enum SearchResultKind {
|
||||
GOOD_MATCH, //type I
|
||||
BAD_MATCH_MORE_SPECIFIC, //type II
|
||||
BAD_MATCH, //type III
|
||||
NOT_APPLICABLE_MATCH //type IV
|
||||
}
|
||||
|
||||
boolean hasAnotherApplicableMethod(MethodResolutionContext resolutionContext,
|
||||
Symbol bestSoFar, boolean staticMth) {
|
||||
for (Candidate c : resolutionContext.candidates) {
|
||||
if (resolutionContext.step != c.step ||
|
||||
!c.isApplicable() ||
|
||||
c.sym == bestSoFar) {
|
||||
continue;
|
||||
} else {
|
||||
return s1;
|
||||
if (c.sym.isStatic() == staticMth) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//where
|
||||
private Symbol choose(Symbol boundSym, Symbol unboundSym) {
|
||||
if (lookupSuccess(boundSym) && lookupSuccess(unboundSym)) {
|
||||
return ambiguityError(boundSym, unboundSym);
|
||||
} else if (lookupSuccess(boundSym) ||
|
||||
(canIgnore(unboundSym) && !canIgnore(boundSym))) {
|
||||
return boundSym;
|
||||
} else if (lookupSuccess(unboundSym) ||
|
||||
(canIgnore(boundSym) && !canIgnore(unboundSym))) {
|
||||
return unboundSym;
|
||||
} else {
|
||||
return boundSym;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2780,6 +2977,8 @@ public class Resolve {
|
|||
InapplicableSymbolsError errSyms =
|
||||
(InapplicableSymbolsError)s;
|
||||
return errSyms.filterCandidates(errSyms.mapCandidates()).isEmpty();
|
||||
case WRONG_STATICNESS:
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -2894,7 +3093,6 @@ public class Resolve {
|
|||
List<Type> argtypes, List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
|
||||
super(name, site, argtypes, typeargtypes, maxPhase);
|
||||
this.referenceTree = referenceTree;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3324,6 +3522,11 @@ public class Resolve {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStatic() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an external representation for this erroneous symbol to be
|
||||
* used during attribution - by default this returns the symbol of a
|
||||
|
@ -3398,7 +3601,11 @@ public class Resolve {
|
|||
class SymbolNotFoundError extends ResolveError {
|
||||
|
||||
SymbolNotFoundError(int kind) {
|
||||
super(kind, "symbol not found error");
|
||||
this(kind, "symbol not found error");
|
||||
}
|
||||
|
||||
SymbolNotFoundError(int kind, String debugName) {
|
||||
super(kind, debugName);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -3436,7 +3643,8 @@ public class Resolve {
|
|||
hasLocation = !location.name.equals(names._this) &&
|
||||
!location.name.equals(names._super);
|
||||
}
|
||||
boolean isConstructor = kind == ABSENT_MTH && name == names.init;
|
||||
boolean isConstructor = (kind == ABSENT_MTH || kind == WRONG_STATICNESS) &&
|
||||
name == names.init;
|
||||
KindName kindname = isConstructor ? KindName.CONSTRUCTOR : absentKind(kind);
|
||||
Name idname = isConstructor ? site.tsym.name : name;
|
||||
String errKey = getErrorKey(kindname, typeargtypes.nonEmpty(), hasLocation);
|
||||
|
|
|
@ -483,17 +483,8 @@ public class Code {
|
|||
/** Emit an invokedynamic instruction.
|
||||
*/
|
||||
public void emitInvokedynamic(int desc, Type mtype) {
|
||||
// N.B. this format is under consideration by the JSR 292 EG
|
||||
int argsize = width(mtype.getParameterTypes());
|
||||
int prevPos = pendingStatPos;
|
||||
try {
|
||||
//disable line number generation (we could have used 'emit1', that
|
||||
//bypasses stackmap generation - which is needed for indy calls)
|
||||
pendingStatPos = Position.NOPOS;
|
||||
emitop(invokedynamic);
|
||||
} finally {
|
||||
pendingStatPos = prevPos;
|
||||
}
|
||||
emitop(invokedynamic);
|
||||
if (!alive) return;
|
||||
emit2(desc);
|
||||
emit2(0);
|
||||
|
@ -1790,8 +1781,9 @@ public class Code {
|
|||
|
||||
void markInitialized(UninitializedType old) {
|
||||
Type newtype = old.initializedType();
|
||||
for (int i=0; i<stacksize; i++)
|
||||
for (int i=0; i<stacksize; i++) {
|
||||
if (stack[i] == old) stack[i] = newtype;
|
||||
}
|
||||
for (int i=0; i<lvar.length; i++) {
|
||||
LocalVar lv = lvar[i];
|
||||
if (lv != null && lv.sym.type == old) {
|
||||
|
@ -2112,7 +2104,6 @@ public class Code {
|
|||
private void endScope(int adr) {
|
||||
LocalVar v = lvar[adr];
|
||||
if (v != null) {
|
||||
lvar[adr] = null;
|
||||
if (v.isLastRangeInitialized()) {
|
||||
char length = (char)(curCP() - v.lastRange().start_pc);
|
||||
if (length < Character.MAX_VALUE) {
|
||||
|
@ -2121,6 +2112,12 @@ public class Code {
|
|||
fillLocalVarPosition(v);
|
||||
}
|
||||
}
|
||||
/** the call to curCP() can implicitly adjust the current cp, if so
|
||||
* the alive range of local variables may be modified. Thus we need
|
||||
* all of them. For this reason assigning null to the given address
|
||||
* should be the last action to do.
|
||||
*/
|
||||
lvar[adr] = null;
|
||||
}
|
||||
state.defined.excl(adr);
|
||||
}
|
||||
|
|
|
@ -575,9 +575,6 @@ compiler.err.intf.annotation.member.clash=\
|
|||
compiler.err.intf.expected.here=\
|
||||
interface expected here
|
||||
|
||||
compiler.err.intf.or.array.expected.here=\
|
||||
interface or array type expected here
|
||||
|
||||
compiler.err.intf.meth.cant.have.body=\
|
||||
interface abstract methods cannot have body
|
||||
|
||||
|
|
|
@ -73,15 +73,11 @@ public class ConstructorDocImpl
|
|||
/**
|
||||
* Get the name.
|
||||
*
|
||||
* @return the name of the member qualified by class (but not package)
|
||||
* @return the name of the member.
|
||||
*/
|
||||
public String name() {
|
||||
ClassSymbol c = sym.enclClass();
|
||||
String n = c.name.toString();
|
||||
for (c = c.owner.enclClass(); c != null; c = c.owner.enclClass()) {
|
||||
n = c.name.toString() + "." + n;
|
||||
}
|
||||
return n;
|
||||
return c.name.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -27,6 +27,7 @@ package javax.lang.model.util;
|
|||
|
||||
import javax.annotation.processing.SupportedSourceVersion;
|
||||
import javax.lang.model.SourceVersion;
|
||||
import javax.lang.model.type.IntersectionType;
|
||||
import static javax.lang.model.SourceVersion.*;
|
||||
|
||||
/**
|
||||
|
@ -98,4 +99,17 @@ public class SimpleTypeVisitor8<R, P> extends SimpleTypeVisitor7<R, P> {
|
|||
protected SimpleTypeVisitor8(R defaultValue){
|
||||
super(defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation visits an {@code IntersectionType} by calling
|
||||
* {@code defaultAction}.
|
||||
*
|
||||
* @param t {@inheritDoc}
|
||||
* @param p {@inheritDoc}
|
||||
* @return the result of {@code defaultAction}
|
||||
*/
|
||||
@Override
|
||||
public R visitIntersection(IntersectionType t, P p){
|
||||
return defaultAction(t, p);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -101,4 +101,17 @@ public class TypeKindVisitor8<R, P> extends TypeKindVisitor7<R, P> {
|
|||
protected TypeKindVisitor8(R defaultValue) {
|
||||
super(defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation visits an {@code IntersectionType} by calling
|
||||
* {@code defaultAction}.
|
||||
*
|
||||
* @param t {@inheritDoc}
|
||||
* @param p {@inheritDoc}
|
||||
* @return the result of {@code defaultAction}
|
||||
*/
|
||||
@Override
|
||||
public R visitIntersection(IntersectionType t, P p) {
|
||||
return defaultAction(t, p);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8025633
|
||||
* @bug 8025633 8025524
|
||||
* @summary Test for valid name attribute in HTML anchors.
|
||||
* @author Bhavesh Patel
|
||||
* @library ../lib/
|
||||
|
@ -196,10 +196,10 @@ public class TestAnchorNames extends JavadocTester {
|
|||
//Test nested class
|
||||
|
||||
{BUG_ID + FS + "pkg1" + FS + "RegClass._NestedClas$.html",
|
||||
"<a name=\"RegClass._NestedClas:D--\">"
|
||||
"<a name=\"Z:Z_NestedClas:D--\">"
|
||||
},
|
||||
{BUG_ID + FS + "pkg1" + FS + "RegClass._NestedClas$.html",
|
||||
"<a href=\"../pkg1/RegClass._NestedClas$.html#RegClass._NestedClas:D--\">"
|
||||
"<a href=\"../pkg1/RegClass._NestedClas$.html#Z:Z_NestedClas:D--\">"
|
||||
},
|
||||
|
||||
//Test class use page
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8025524
|
||||
* @summary Test for constructor name which should be a non-qualified name.
|
||||
* @author Bhavesh Patel
|
||||
* @library ../lib/
|
||||
* @build JavadocTester TestConstructors
|
||||
* @run main TestConstructors
|
||||
*/
|
||||
|
||||
public class TestConstructors extends JavadocTester {
|
||||
|
||||
private static final String BUG_ID = "8025524";
|
||||
|
||||
//Input for string search tests.
|
||||
private static final String[][] TEST = {
|
||||
{BUG_ID + FS + "pkg1" + FS + "Outer.html",
|
||||
"<a href=\"../pkg1/Outer.html#Outer--\">Outer</a></span>()"
|
||||
},
|
||||
{BUG_ID + FS + "pkg1" + FS + "Outer.html",
|
||||
"<a name=\"Outer--\">"
|
||||
},
|
||||
{BUG_ID + FS + "pkg1" + FS + "Outer.html",
|
||||
"<a href=\"../pkg1/Outer.html#Outer-int-\">Outer</a></span>(int i)"
|
||||
},
|
||||
{BUG_ID + FS + "pkg1" + FS + "Outer.html",
|
||||
"<a name=\"Outer-int-\">"
|
||||
},
|
||||
{BUG_ID + FS + "pkg1" + FS + "Outer.Inner.html",
|
||||
"<a href=\"../pkg1/Outer.Inner.html#Inner--\">Inner</a></span>()"
|
||||
},
|
||||
{BUG_ID + FS + "pkg1" + FS + "Outer.Inner.html",
|
||||
"<a name=\"Inner--\">"
|
||||
},
|
||||
{BUG_ID + FS + "pkg1" + FS + "Outer.Inner.html",
|
||||
"<a href=\"../pkg1/Outer.Inner.html#Inner-int-\">Inner</a></span>(int i)"
|
||||
},
|
||||
{BUG_ID + FS + "pkg1" + FS + "Outer.Inner.html",
|
||||
"<a name=\"Inner-int-\">"
|
||||
},
|
||||
{BUG_ID + FS + "pkg1" + FS + "Outer.Inner.NestedInner.html",
|
||||
"<a href=\"../pkg1/Outer.Inner.NestedInner.html#NestedInner--\">NestedInner</a></span>()"
|
||||
},
|
||||
{BUG_ID + FS + "pkg1" + FS + "Outer.Inner.NestedInner.html",
|
||||
"<a name=\"NestedInner--\">"
|
||||
},
|
||||
{BUG_ID + FS + "pkg1" + FS + "Outer.Inner.NestedInner.html",
|
||||
"<a href=\"../pkg1/Outer.Inner.NestedInner.html#NestedInner-int-\">NestedInner</a></span>(int i)"
|
||||
},
|
||||
{BUG_ID + FS + "pkg1" + FS + "Outer.Inner.NestedInner.html",
|
||||
"<a name=\"NestedInner-int-\">"
|
||||
}
|
||||
};
|
||||
|
||||
private static final String[][] NEGATED_TEST = {
|
||||
{BUG_ID + FS + "pkg1" + FS + "Outer.Inner.html",
|
||||
"Outer.Inner--"
|
||||
},
|
||||
{BUG_ID + FS + "pkg1" + FS + "Outer.Inner.html",
|
||||
"Outer.Inner-int-"
|
||||
},
|
||||
{BUG_ID + FS + "pkg1" + FS + "Outer.Inner.NestedInner.html",
|
||||
"Outer.Inner.NestedInner--"
|
||||
},
|
||||
{BUG_ID + FS + "pkg1" + FS + "Outer.Inner.NestedInner.html",
|
||||
"Outer.Inner.NestedInner-int-"
|
||||
}
|
||||
};
|
||||
|
||||
private static final String[] ARGS = new String[] {
|
||||
"-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg1"
|
||||
};
|
||||
|
||||
/**
|
||||
* The entry point of the test.
|
||||
* @param args the array of command line arguments.
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
TestConstructors tester = new TestConstructors();
|
||||
run(tester, ARGS, TEST, NEGATED_TEST);
|
||||
tester.printSummary();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public String getBugId() {
|
||||
return BUG_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public String getBugName() {
|
||||
return getClass().getName();
|
||||
}
|
||||
}
|
|
@ -21,18 +21,55 @@
|
|||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8021339
|
||||
* @summary Allow arrays in intersection types
|
||||
* @compile -doe -XDrawDiagnostics InferArraysInIntersections.java
|
||||
*/
|
||||
import java.util.*;
|
||||
package pkg1;
|
||||
|
||||
class InferArraysInIntersections {
|
||||
<T> T m(List<? super T> t) { return null; }
|
||||
public class Outer {
|
||||
|
||||
void test(List<char[]> lc) {
|
||||
Runnable r = m(lc); //inference fails here
|
||||
}
|
||||
/**
|
||||
* An outer constructor.
|
||||
*/
|
||||
public Outer() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Another outer constructor.
|
||||
*/
|
||||
public Outer(int i) {
|
||||
}
|
||||
|
||||
/**
|
||||
* A nested class.
|
||||
*/
|
||||
public class Inner {
|
||||
|
||||
/**
|
||||
* An inner constructor.
|
||||
*/
|
||||
public Inner() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Another inner constructor.
|
||||
*/
|
||||
public Inner(int i) {
|
||||
}
|
||||
|
||||
/**
|
||||
* A nested inner class.
|
||||
*/
|
||||
public class NestedInner {
|
||||
|
||||
/**
|
||||
* A nested inner constructor.
|
||||
*/
|
||||
public NestedInner() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Another nested inner constructor.
|
||||
*/
|
||||
public NestedInner(int i) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,6 @@
|
|||
* @test /nodynamiccopyright/
|
||||
* @bug 7042623
|
||||
* @summary Regression: javac silently crash when attributing non-existent annotation
|
||||
* @ignore
|
||||
* @compile/fail/ref=T7042623.out -XDrawDiagnostics -XDdev T7042623.java
|
||||
*/
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8019486 8026861
|
||||
* @bug 8019486 8026861 8027142
|
||||
* @summary javac, generates erroneous LVT for a test case with lambda code
|
||||
* @library /tools/javac/lib
|
||||
* @build ToolBox
|
||||
|
@ -68,7 +68,14 @@ public class WrongLNTForLambdaTest {
|
|||
/* 22 */ " Runnable r4 = super :: notify;\n" +
|
||||
/* 23 */ " }\n" +
|
||||
/* 24 */ " private void foo() {}\n" +
|
||||
/* 25 */ "}";
|
||||
/* 25 */ " void assignLambda() {\n" +
|
||||
/* 26 */ " Runnable r = () -> { };\n" +
|
||||
/* 27 */ " }\n" +
|
||||
/* 28 */ " void callLambda(int i, Runnable r) {\n" +
|
||||
/* 29 */ " callLambda(0,\n" +
|
||||
/* 30 */ " () -> { });\n" +
|
||||
/* 31 */ " }\n" +
|
||||
/* 32 */ "}";
|
||||
|
||||
static final int[][] simpleLambdaExpectedLNT = {
|
||||
// {line-number, start-pc},
|
||||
|
@ -102,6 +109,18 @@ public class WrongLNTForLambdaTest {
|
|||
{22, 0}, //number -> number / 1
|
||||
};
|
||||
|
||||
static final int[][] assignmentExpectedLNT = {
|
||||
// {line-number, start-pc},
|
||||
{26, 0}, //number -> number / 1
|
||||
{27, 6}, //number -> number / 1
|
||||
};
|
||||
|
||||
static final int[][] callExpectedLNT = {
|
||||
// {line-number, start-pc},
|
||||
{29, 0}, //number -> number / 1
|
||||
{31, 10}, //number -> number / 1
|
||||
};
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new WrongLNTForLambdaTest().run();
|
||||
}
|
||||
|
@ -120,6 +139,10 @@ public class WrongLNTForLambdaTest {
|
|||
"Foo.class").toUri()), "$deserializeLambda$", deserializeExpectedLNT);
|
||||
checkClassFile(new File(Paths.get(System.getProperty("user.dir"),
|
||||
"Foo.class").toUri()), "lambda$MR$variablesInLambdas$notify$8bc4f5bd$1", lambdaBridgeExpectedLNT);
|
||||
checkClassFile(new File(Paths.get(System.getProperty("user.dir"),
|
||||
"Foo.class").toUri()), "assignLambda", assignmentExpectedLNT);
|
||||
checkClassFile(new File(Paths.get(System.getProperty("user.dir"),
|
||||
"Foo.class").toUri()), "callLambda", callExpectedLNT);
|
||||
}
|
||||
|
||||
void compileTestClass() throws Exception {
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8026963
|
||||
* @summary type annotations code crashes for lambdas with void argument
|
||||
* @compile/fail/ref=TypeAnnotationsCrashWithErroneousTreeTest.out -XDrawDiagnostics -XDshouldStopPolicy=FLOW TypeAnnotationsCrashWithErroneousTreeTest.java
|
||||
*/
|
||||
|
||||
public class TypeAnnotationsCrashWithErroneousTreeTest {
|
||||
private void t(this) {}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
TypeAnnotationsCrashWithErroneousTreeTest.java:9:20: compiler.err.illegal.start.of.type
|
||||
1 error
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8025113
|
||||
* @author sogoel
|
||||
* @summary Resources cannot be declared outside t-w-r block
|
||||
* @compile/fail/ref=ResDeclOutsideTry.out -XDrawDiagnostics ResDeclOutsideTry.java
|
||||
*/
|
||||
|
||||
public class ResDeclOutsideTry implements AutoCloseable {
|
||||
ResDeclOutsideTry tr1;
|
||||
ResDeclOutsideTry tr2 = new ResDeclOutsideTry();
|
||||
|
||||
String test1() {
|
||||
try (tr1 = new ResDeclOutsideTry(); tr2;) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
ResDeclOutsideTry.java:14:17: compiler.err.expected: token.identifier
|
||||
ResDeclOutsideTry.java:14:48: compiler.err.expected: token.identifier
|
||||
2 errors
|
195
langtools/test/tools/javac/TryWithResources/ResInNestedExpr.java
Normal file
195
langtools/test/tools/javac/TryWithResources/ResInNestedExpr.java
Normal file
|
@ -0,0 +1,195 @@
|
|||
/*
|
||||
* Copyright (c) 2010, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8025113
|
||||
* @author sogoel
|
||||
* @summary Resource creation in nested expressions
|
||||
*/
|
||||
|
||||
/**
|
||||
* This test checks for resource creation in nested expressions.
|
||||
* test1() - Create 3 resource in nested new expressions, style 1
|
||||
* test2() - Create 3 resource in nested new expressions, style 2
|
||||
* test3() - Create 4 resources with resources as parameters: new expression; typeid & new expression
|
||||
*/
|
||||
|
||||
public class ResInNestedExpr {
|
||||
|
||||
static final int expected = 5;
|
||||
static int closed = 0;
|
||||
|
||||
static void closing(String clazz) {
|
||||
closed++;
|
||||
}
|
||||
|
||||
static void checkClosedCount() {
|
||||
if (expected != closed) {
|
||||
throw new RuntimeException("Did not find enough closed resources."
|
||||
+ "Expected " + expected + ", but found " + closed);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* The "expected output" is each class name gotten with getSimpleName() to unclutter things.
|
||||
* Each test method returns a classname of the resource and that is compared with
|
||||
* values in this array.
|
||||
*/
|
||||
static String[] expectedOutput = {
|
||||
"aResource::bResource::cResource", //test1
|
||||
"aResource::bResource::cResource&aResource::cResource", //test3
|
||||
"aResource::bResource::cResource&aResource::cResource"}; //test2
|
||||
|
||||
static void compare(String s1, String s2) {
|
||||
if (s1.compareTo(s2) != 0) {
|
||||
throw new RuntimeException(s1 + "!=" + s2);
|
||||
}
|
||||
}
|
||||
|
||||
String test1() {
|
||||
String ret = null;
|
||||
try (bResource br = new bResource(new cResource());
|
||||
aResource ar = new aResource(br)) {
|
||||
ret = ar.getClass().getSimpleName() + "::" +
|
||||
ar.getB().getClass().getSimpleName() + "::" +
|
||||
ar.getB().getC().getClass().getSimpleName();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
String test2() {
|
||||
String ret = null;
|
||||
try (aResource ar = new aResource(new bResource(new cResource()), new cResource())) {
|
||||
String abc = ar.getClass().getSimpleName() + "::" +
|
||||
ar.getB().getClass().getSimpleName() + "::" +
|
||||
ar.getB().getC().getClass().getSimpleName();
|
||||
String ac = ar.getClass().getSimpleName() + "::" +
|
||||
ar.getC().getClass().getSimpleName();
|
||||
ret = abc + "&" + ac;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
String test3() {
|
||||
String ret = null;
|
||||
try (bResource br = new bResource(new cResource());
|
||||
aResource ar = new aResource(br, new cResource())) {
|
||||
String abc = ar.getClass().getSimpleName() + "::" +
|
||||
ar.getB().getClass().getSimpleName() + "::" +
|
||||
ar.getB().getC().getClass().getSimpleName();
|
||||
String ac = ar.getClass().getSimpleName() + "::" +
|
||||
ar.getC().getClass().getSimpleName();
|
||||
ret = abc + "&" + ac;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static void main(String... args) {
|
||||
ResInNestedExpr t = new ResInNestedExpr();
|
||||
int eo = 0;
|
||||
compare(expectedOutput[eo++], t.test1());
|
||||
compare(expectedOutput[eo++], t.test3());
|
||||
compare(expectedOutput[eo++], t.test2());
|
||||
ResInNestedExpr.checkClosedCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* A resource to implement AutoCloseable
|
||||
* Contains two other resources as data items.
|
||||
*/
|
||||
static class aResource implements AutoCloseable {
|
||||
|
||||
bResource bR;
|
||||
cResource cR;
|
||||
|
||||
public aResource() {
|
||||
bR = null;
|
||||
cR = null;
|
||||
}
|
||||
|
||||
public aResource(bResource br) {
|
||||
bR = br;
|
||||
}
|
||||
|
||||
public aResource(cResource cr) {
|
||||
cR = cr;
|
||||
}
|
||||
|
||||
public aResource(bResource br, cResource cr) {
|
||||
bR = br;
|
||||
cR = cr;
|
||||
}
|
||||
|
||||
public bResource getB() {
|
||||
return bR;
|
||||
}
|
||||
|
||||
public cResource getC() {
|
||||
return cR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
ResInNestedExpr.closing(this.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A resource to implement AutoCloseable
|
||||
* Contains one other resources as a data item.
|
||||
*/
|
||||
static class bResource implements AutoCloseable {
|
||||
|
||||
cResource cR;
|
||||
|
||||
public bResource() {
|
||||
cR = null;
|
||||
}
|
||||
|
||||
public bResource(cResource cr) {
|
||||
cR = cr;
|
||||
}
|
||||
|
||||
public cResource getC() {
|
||||
return cR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
ResInNestedExpr.closing(this.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
/** A resource to implement AutoCloseable */
|
||||
static class cResource implements AutoCloseable {
|
||||
|
||||
public cResource() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
ResInNestedExpr.closing(this.getClass().getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8025113
|
||||
* @author sogoel
|
||||
* @summary Resource var cannot have same name as local variable
|
||||
* @compile/fail/ref=ResourceNameConflict.out -XDrawDiagnostics ResourceNameConflict.java
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test methods and their description
|
||||
* test1() - negative test - local variable used as test resource
|
||||
* test2() - negative test - test resource already defined in an enclosing for statement
|
||||
*/
|
||||
|
||||
public class ResourceNameConflict implements AutoCloseable {
|
||||
|
||||
static final String str = "asdf";
|
||||
|
||||
void test1() {
|
||||
String tr = "A resource spec var cannot have same name as local var.";
|
||||
try (ResourceNameConflict tr = new ResourceNameConflict()) {
|
||||
}
|
||||
}
|
||||
|
||||
void test2(String... strArray) {
|
||||
for (String str : strArray) {
|
||||
try (ResourceNameConflict str = new ResourceNameConflict()) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
ResourceNameConflict.java:21:35: compiler.err.already.defined: kindname.variable, tr, kindname.method, test1()
|
||||
ResourceNameConflict.java:27:39: compiler.err.already.defined: kindname.variable, str, kindname.method, test2(java.lang.String...)
|
||||
2 errors
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8025113
|
||||
* @author sogoel
|
||||
* @summary Redeclaration of resource variables
|
||||
* @compile/fail/ref=ResourceRedecl.out -XDrawDiagnostics ResourceRedecl.java
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class ResourceRedecl {
|
||||
|
||||
public void test() {
|
||||
// compiler error if name of an exception param is redeclared within the Block of the catch clause as a local var;
|
||||
// or as an exception param of a catch clause in a try statement;
|
||||
// or as a resource in a try-with-resources statement
|
||||
try {
|
||||
} catch (Exception exParam1) {
|
||||
Object exParam1 = new Object();
|
||||
try (java.io.FileInputStream exParam1 = new java.io.FileInputStream("foo.txt")) {
|
||||
Object exParam1 = new Object();
|
||||
} catch (IOException exParam1) {
|
||||
}
|
||||
}
|
||||
|
||||
// compiler error if resource is redeclared within the try Block as a local var
|
||||
// or as an exception param of a catch clause in a try statement
|
||||
try (java.io.FileInputStream exParam2 = new java.io.FileInputStream("bar.txt")) {
|
||||
Object exParam2 = new Object();
|
||||
try (BufferedReader br = new BufferedReader(new FileReader("zee.txt"))) {
|
||||
} catch (IOException exParam2) {
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
ResourceRedecl.java:19:20: compiler.err.already.defined: kindname.variable, exParam1, kindname.method, test()
|
||||
ResourceRedecl.java:20:42: compiler.err.already.defined: kindname.variable, exParam1, kindname.method, test()
|
||||
ResourceRedecl.java:21:24: compiler.err.already.defined: kindname.variable, exParam1, kindname.method, test()
|
||||
ResourceRedecl.java:22:34: compiler.err.already.defined: kindname.variable, exParam1, kindname.method, test()
|
||||
ResourceRedecl.java:29:20: compiler.err.already.defined: kindname.variable, exParam2, kindname.method, test()
|
||||
ResourceRedecl.java:31:34: compiler.err.already.defined: kindname.variable, exParam2, kindname.method, test()
|
||||
6 errors
|
119
langtools/test/tools/javac/TryWithResources/ResourceShadow.java
Normal file
119
langtools/test/tools/javac/TryWithResources/ResourceShadow.java
Normal file
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* Copyright (c) 2010, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8025113
|
||||
* @author sogoel
|
||||
* @summary Test shadowing of resource variable
|
||||
*/
|
||||
|
||||
/*
|
||||
* "...a variable declared in a resource specification
|
||||
* may be shadowed (6.3.1) anywhere inside a class declaration nested
|
||||
* within the Block of the try."
|
||||
*/
|
||||
public class ResourceShadow {
|
||||
|
||||
static final String str = "asdf"; //this is okay
|
||||
|
||||
/**
|
||||
* Resource variable shadows switch and case variables
|
||||
*/
|
||||
String test1() {
|
||||
String ret = null;
|
||||
switch (str) {
|
||||
case str: //this is okay
|
||||
try (SilentCloseable str = new SilentCloseable()) {
|
||||
SilentCloseable tr = new SilentCloseable(str);
|
||||
ret = str.getClass().getSimpleName();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ret = "";
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resource variable may be shadowed (6.3.1) anywhere inside a class
|
||||
* declaration nested within the Block of the try
|
||||
*/
|
||||
String test2() {
|
||||
String ret = null;
|
||||
try (SilentCloseable str = new SilentCloseable()) {
|
||||
class temp {
|
||||
|
||||
String str = "I am not a SilentCloseable";
|
||||
|
||||
public void printSTR() {
|
||||
System.out.println(str);
|
||||
}
|
||||
|
||||
public String getSTR() {
|
||||
return str;
|
||||
}
|
||||
}
|
||||
temp tmp = new temp();
|
||||
SilentCloseable tr = new SilentCloseable(tmp.getSTR());
|
||||
ret = tr.getMsg();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static void main(String... args) {
|
||||
ResourceShadow t = new ResourceShadow();
|
||||
if (t.test1().compareTo("SilentCloseable") != 0) {
|
||||
throw new RuntimeException("FAIL-test1");
|
||||
}
|
||||
if (t.test2().compareTo("I am not a SilentCloseable") != 0) {
|
||||
throw new RuntimeException("FAIL-test2");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SilentCloseable implements AutoCloseable {
|
||||
|
||||
SilentCloseable testres = null;
|
||||
String msg = "default";
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
}
|
||||
|
||||
public SilentCloseable() {
|
||||
}
|
||||
|
||||
public SilentCloseable(String s) {
|
||||
msg = s;
|
||||
}
|
||||
|
||||
public SilentCloseable(SilentCloseable tr) {
|
||||
testres = tr;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
|
129
langtools/test/tools/javac/TryWithResources/TestTwr09.java
Normal file
129
langtools/test/tools/javac/TryWithResources/TestTwr09.java
Normal file
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* Copyright (c) 2010, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8025113
|
||||
* @author sogoel
|
||||
* @summary t-w-r completes abruptly if the initialization of resource completes abruptly
|
||||
*/
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
|
||||
/*
|
||||
* If the initialization of the resource completes abruptly because of a
|
||||
* throw of a value V ... and the automatic ->closing of the resource completes normally,
|
||||
* then the try-with-resources statement completes abruptly because of the throw of value V.
|
||||
*/
|
||||
public class TestTwr09 {
|
||||
|
||||
/**
|
||||
* throw from ctor of nested resource
|
||||
* Check first resource is not open.
|
||||
*/
|
||||
String test1() {
|
||||
String ret = null;
|
||||
try (ResCloseable tr = new ResCloseable(new ResCloseable("throw from inner resource ctor",3))) {
|
||||
ret = "FAIL";
|
||||
} catch (RuntimeException re) {
|
||||
ret = re.getMessage();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* throw from ctor of 2nd resource.
|
||||
* 1st resource, FileInputStream should be automatically closed.
|
||||
*/
|
||||
String test2() {
|
||||
String ret = null;
|
||||
byte[] buf = new byte[1];
|
||||
try (java.io.ByteArrayInputStream tr = new java.io.ByteArrayInputStream(buf);
|
||||
ResCloseable str = new ResCloseable("throw from inner resource ctor",3)) {
|
||||
ret = "FAIL";
|
||||
} catch (final IOException fe) {
|
||||
ret = "FAIL test2";
|
||||
} catch (RuntimeException re) {
|
||||
ret = "PASS test2";
|
||||
}
|
||||
System.out.println("Ret = " + ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static void main(String... args) {
|
||||
TestTwr09 t = new TestTwr09();
|
||||
if (t.test1().compareTo("throw from inner resource ctor") != 0) {
|
||||
throw new RuntimeException("FAIL-test1");
|
||||
}
|
||||
if (t.test2().compareTo("PASS test2") != 0) {
|
||||
throw new RuntimeException("FAIL-test2");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** a simple resource the implements AutoCloseable so it can be used
|
||||
* in twr's resource specification block.
|
||||
*/
|
||||
class ResCloseable implements AutoCloseable {
|
||||
|
||||
ResCloseable testres = null;
|
||||
String msg = "default";
|
||||
boolean bOpen = false;
|
||||
|
||||
public ResCloseable() {
|
||||
bOpen = true;
|
||||
}
|
||||
|
||||
public ResCloseable(ResCloseable tr) {
|
||||
bOpen = true;
|
||||
msg = tr.getMsg();
|
||||
}
|
||||
|
||||
public ResCloseable(String s) {
|
||||
bOpen = true;
|
||||
msg = s;
|
||||
}
|
||||
|
||||
public ResCloseable(String msg, int c) {
|
||||
bOpen = true;
|
||||
if (c == 3) {
|
||||
throw new RuntimeException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
bOpen = false;
|
||||
}
|
||||
|
||||
public boolean isOpen() {
|
||||
return bOpen;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
/* @test /nodynamiccopyright/
|
||||
* @bug 8027375
|
||||
* @summary Test that javac doesn't assert/crash when there are what looks to
|
||||
* be annotations nested inside erroneous annotations.
|
||||
* @compile/fail/ref=TestCrashNestedAnnos.out -XDrawDiagnostics TestCrashNestedAnnos.java
|
||||
*/
|
||||
public class TestCrashNestedAnnos {
|
||||
// A and B are not annotation types
|
||||
@A(@A1()) int foo() {}
|
||||
@B(@B1()) int bar() {}
|
||||
}
|
||||
|
||||
class B {}
|
||||
class B1 {}
|
|
@ -0,0 +1,3 @@
|
|||
TestCrashNestedAnnos.java:9:6: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, TestCrashNestedAnnos, null)
|
||||
TestCrashNestedAnnos.java:10:6: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: B, java.lang.annotation.Annotation)
|
||||
2 errors
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8027281
|
||||
* @summary As per JVMS 4.9.2, invokespecial can only refer to direct superinterfaces
|
||||
* @compile TestDirectSuperInterfaceInvoke.java
|
||||
* @run main TestDirectSuperInterfaceInvoke
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import com.sun.tools.classfile.Attribute;
|
||||
import com.sun.tools.classfile.ClassFile;
|
||||
import com.sun.tools.classfile.Code_attribute;
|
||||
import com.sun.tools.classfile.ConstantPool.CPRefInfo;
|
||||
import com.sun.tools.classfile.Instruction;
|
||||
import com.sun.tools.classfile.Method;
|
||||
import com.sun.tools.classfile.Opcode;
|
||||
|
||||
interface BaseInterface {
|
||||
public default int testedMethod(){ return 1; }
|
||||
}
|
||||
|
||||
interface IntermediateInterface extends BaseInterface {
|
||||
}
|
||||
|
||||
interface TestInterface extends IntermediateInterface {
|
||||
public default void test() {
|
||||
IntermediateInterface.super.testedMethod();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class BaseClass implements BaseInterface { }
|
||||
|
||||
class TestClass extends BaseClass implements BaseInterface {
|
||||
public int testedMethod() {return 9;}
|
||||
public void test() {
|
||||
if (super.testedMethod() != 1)
|
||||
throw new IllegalStateException();
|
||||
if (TestClass.super.testedMethod() != 1)
|
||||
throw new IllegalStateException();
|
||||
new Runnable() {
|
||||
public void run() {
|
||||
if (TestClass.super.testedMethod() != 1)
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}.run();
|
||||
}
|
||||
}
|
||||
|
||||
public class TestDirectSuperInterfaceInvoke {
|
||||
public static void main(String... args) throws Exception {
|
||||
new TestDirectSuperInterfaceInvoke().run();
|
||||
}
|
||||
|
||||
public void run() throws Exception {
|
||||
new TestClass().test();
|
||||
verifyDefaultBody("TestClass.class");
|
||||
new TestInterface() {}.test();
|
||||
verifyDefaultBody("TestInterface.class");
|
||||
}
|
||||
|
||||
void verifyDefaultBody(String classFile) {
|
||||
String workDir = System.getProperty("test.classes");
|
||||
File file = new File(workDir, classFile);
|
||||
try {
|
||||
final ClassFile cf = ClassFile.read(file);
|
||||
for (Method m : cf.methods) {
|
||||
Code_attribute codeAttr = (Code_attribute)m.attributes.get(Attribute.Code);
|
||||
for (Instruction instr : codeAttr.getInstructions()) {
|
||||
if (instr.getOpcode() == Opcode.INVOKESPECIAL) {
|
||||
int pc_index = instr.getShort(1);
|
||||
CPRefInfo ref = (CPRefInfo)cf.constant_pool.get(pc_index);
|
||||
String className = ref.getClassName();
|
||||
if (className.equals("BaseInterface"))
|
||||
throw new IllegalStateException("Must not directly refer to TestedInterface");
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new Error("error reading " + file +": " + e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// key: compiler.err.intf.or.array.expected.here
|
||||
|
||||
import java.util.List;
|
||||
|
||||
class InterfaceExpected<T extends List & String> { }
|
|
@ -23,8 +23,10 @@
|
|||
|
||||
/*
|
||||
* @test
|
||||
* @bug 7047734
|
||||
* @summary The LVT is not generated correctly during some try/catch scenarios
|
||||
* @bug 7047734 8027660
|
||||
* @summary The LVT is not generated correctly during some try/catch scenarios;
|
||||
* javac crash while creating LVT entry for a local variable defined in
|
||||
* an inner block
|
||||
* @library /tools/javac/lib
|
||||
* @build JavacTestingAbstractProcessor LVTHarness
|
||||
* @run main LVTHarness
|
||||
|
|
|
@ -21,19 +21,21 @@
|
|||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8021339
|
||||
* @summary Allow arrays in intersection types
|
||||
* @compile ArraysInIntersections.java
|
||||
*/
|
||||
public class TestCaseLocalInInnerBlock {
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class ArraysInIntersections<T extends Serializable & Integer[]> {
|
||||
|
||||
public <S extends Serializable & Integer[]> Object m() {
|
||||
return (Serializable & Integer[]) new Integer[1];
|
||||
@AliveRange(varName="fm", bytecodeStart=23, bytecodeLength=10)
|
||||
@AliveRange(varName="newWidth", bytecodeStart=2, bytecodeLength=33)
|
||||
@AliveRange(varName="tc", bytecodeStart=5, bytecodeLength=30)
|
||||
int m() {
|
||||
int newWidth = 0;
|
||||
String tc = "b";
|
||||
if (tc != null) {
|
||||
String fm;
|
||||
if (tc.trim() != null) {
|
||||
} else if ((fm = "b") != null) {
|
||||
newWidth += fm.length();
|
||||
}
|
||||
}
|
||||
return newWidth;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +1,13 @@
|
|||
T6680106.java:11:14: compiler.err.cyclic.inheritance: T
|
||||
T6680106.java:12:14: compiler.err.cyclic.inheritance: T
|
||||
T6680106.java:13:14: compiler.err.cyclic.inheritance: T
|
||||
T6680106.java:14:14: compiler.err.cyclic.inheritance: T
|
||||
T6680106.java:15:14: compiler.err.cyclic.inheritance: T
|
||||
T6680106.java:16:14: compiler.err.cyclic.inheritance: T
|
||||
6 errors
|
||||
T6680106.java:11:25: compiler.err.type.found.req: T[], (compiler.misc.type.req.class)
|
||||
T6680106.java:12:25: compiler.err.type.found.req: S[], (compiler.misc.type.req.class)
|
||||
T6680106.java:12:40: compiler.err.type.found.req: T[], (compiler.misc.type.req.class)
|
||||
T6680106.java:13:25: compiler.err.type.found.req: S[], (compiler.misc.type.req.class)
|
||||
T6680106.java:13:40: compiler.err.type.found.req: U[], (compiler.misc.type.req.class)
|
||||
T6680106.java:13:55: compiler.err.type.found.req: T[], (compiler.misc.type.req.class)
|
||||
T6680106.java:14:30: compiler.err.type.found.req: T[], (compiler.misc.type.req.class)
|
||||
T6680106.java:15:30: compiler.err.type.found.req: S[], (compiler.misc.type.req.class)
|
||||
T6680106.java:15:50: compiler.err.type.found.req: T[], (compiler.misc.type.req.class)
|
||||
T6680106.java:16:30: compiler.err.type.found.req: S[], (compiler.misc.type.req.class)
|
||||
T6680106.java:16:50: compiler.err.type.found.req: U[], (compiler.misc.type.req.class)
|
||||
T6680106.java:16:70: compiler.err.type.found.req: T[], (compiler.misc.type.req.class)
|
||||
12 errors
|
||||
|
|
|
@ -48,19 +48,19 @@ class MethodReference22 {
|
|||
}
|
||||
|
||||
static void test2() {
|
||||
SAM2 s1 = MethodReference22::m1; //ambiguous
|
||||
call2(MethodReference22::m1); //ambiguous
|
||||
SAM2 s2 = MethodReference22::m2; //ambiguous
|
||||
call2(MethodReference22::m2); //ambiguous
|
||||
SAM2 s3 = MethodReference22::m3; //ambiguous
|
||||
call2(MethodReference22::m3); //ambiguous
|
||||
SAM2 s4 = MethodReference22::m4; //ambiguous
|
||||
call2(MethodReference22::m4); //ambiguous
|
||||
SAM2 s1 = MethodReference22::m1; //ok
|
||||
call2(MethodReference22::m1); //ok
|
||||
SAM2 s2 = MethodReference22::m2; //ok
|
||||
call2(MethodReference22::m2); //ok
|
||||
SAM2 s3 = MethodReference22::m3; //fail
|
||||
call2(MethodReference22::m3); //fail
|
||||
SAM2 s4 = MethodReference22::m4; //fail
|
||||
call2(MethodReference22::m4); //fail
|
||||
}
|
||||
|
||||
static void test3() {
|
||||
call3(MethodReference22::m1); //fail
|
||||
call3(MethodReference22::m2); //ok
|
||||
call3(MethodReference22::m1); //ok
|
||||
call3(MethodReference22::m2); //ambiguous
|
||||
call3(MethodReference22::m3); //ok
|
||||
call3(MethodReference22::m4); //fail
|
||||
}
|
||||
|
|
|
@ -1,19 +1,11 @@
|
|||
MethodReference22.java:40:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m1(java.lang.String))
|
||||
MethodReference22.java:41:15: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m1(java.lang.String))
|
||||
MethodReference22.java:41:9: compiler.err.cant.apply.symbol: kindname.method, call1, MethodReference22.SAM1, @999, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.arg.types.in.mref))
|
||||
MethodReference22.java:46:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m4(java.lang.String))
|
||||
MethodReference22.java:47:15: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m4(java.lang.String))
|
||||
MethodReference22.java:51:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m1, kindname.method, m1(MethodReference22,java.lang.String), MethodReference22, kindname.method, m1(java.lang.String), MethodReference22))
|
||||
MethodReference22.java:52:14: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1401, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m1, kindname.method, m1(MethodReference22,java.lang.String), MethodReference22, kindname.method, m1(java.lang.String), MethodReference22)))
|
||||
MethodReference22.java:53:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m2, kindname.method, m2(MethodReference22,java.lang.String), MethodReference22, kindname.method, m2(java.lang.String), MethodReference22))
|
||||
MethodReference22.java:54:14: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1504, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m2, kindname.method, m2(MethodReference22,java.lang.String), MethodReference22, kindname.method, m2(java.lang.String), MethodReference22)))
|
||||
MethodReference22.java:55:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m3, kindname.method, m3(MethodReference22,java.lang.String), MethodReference22, kindname.method, m3(java.lang.String), MethodReference22))
|
||||
MethodReference22.java:56:14: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1607, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m3, kindname.method, m3(MethodReference22,java.lang.String), MethodReference22, kindname.method, m3(java.lang.String), MethodReference22)))
|
||||
MethodReference22.java:47:9: compiler.err.cant.apply.symbol: kindname.method, call1, MethodReference22.SAM1, @1270, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.arg.types.in.mref))
|
||||
MethodReference22.java:55:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m3(MethodReference22,java.lang.String))
|
||||
MethodReference22.java:56:9: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1574, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.arg.types.in.mref))
|
||||
MethodReference22.java:57:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m4, kindname.method, m4(MethodReference22,java.lang.String), MethodReference22, kindname.method, m4(java.lang.String), MethodReference22))
|
||||
MethodReference22.java:58:14: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1710, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m4, kindname.method, m4(MethodReference22,java.lang.String), MethodReference22, kindname.method, m4(java.lang.String), MethodReference22)))
|
||||
MethodReference22.java:62:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference22.SAM1), MethodReference22, kindname.method, call3(MethodReference22.SAM2), MethodReference22
|
||||
MethodReference22.java:62:15: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m1(java.lang.String))
|
||||
MethodReference22.java:58:14: compiler.err.cant.apply.symbol: kindname.method, call2, MethodReference22.SAM2, @1667, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m4, kindname.method, m4(MethodReference22,java.lang.String), MethodReference22, kindname.method, m4(java.lang.String), MethodReference22)))
|
||||
MethodReference22.java:63:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference22.SAM1), MethodReference22, kindname.method, call3(MethodReference22.SAM2), MethodReference22
|
||||
MethodReference22.java:64:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference22.SAM1), MethodReference22, kindname.method, call3(MethodReference22.SAM2), MethodReference22
|
||||
MethodReference22.java:65:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference22.SAM1), MethodReference22, kindname.method, call3(MethodReference22.SAM2), MethodReference22
|
||||
MethodReference22.java:65:15: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m4(java.lang.String))
|
||||
18 errors
|
||||
MethodReference22.java:65:14: compiler.err.cant.apply.symbol: kindname.method, call3, MethodReference22.SAM2, @1881, kindname.class, MethodReference22, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m4, kindname.method, m4(MethodReference22,java.lang.String), MethodReference22, kindname.method, m4(java.lang.String), MethodReference22)))
|
||||
10 errors
|
||||
|
|
|
@ -36,11 +36,11 @@ class TestMethodReference51 {
|
|||
|
||||
|
||||
static void test() {
|
||||
IntSam s1 = MethodReference51::unknown; //method not found
|
||||
IntSam s2 = MethodReference51::f; //inapplicable method
|
||||
IntSam s3 = MethodReference51::g; //inapplicable methods
|
||||
IntegerIntegerSam s4 = MethodReference51::g; //ambiguous
|
||||
IntSam s5 = MethodReference51::h; //static error
|
||||
IntSam s6 = MethodReference51.foo::j; //inaccessible method
|
||||
IntSam s1 = MethodReference51::unknown; //fail
|
||||
IntSam s2 = MethodReference51::f; //fail
|
||||
IntSam s3 = MethodReference51::g; //fail
|
||||
IntegerIntegerSam s4 = MethodReference51::g; //fail
|
||||
IntSam s5 = MethodReference51::h; //fail
|
||||
IntSam s6 = MethodReference51.foo::j; //fail
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
MethodReference68.java:21:10: compiler.err.cant.apply.symbol: kindname.method, g, MethodReference68.F<Z>,Z[], @493,int, kindname.class, MethodReference68, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, MethodReference68.Foo,java.lang.Object)
|
||||
1 error
|
||||
MethodReference68.java:21:12: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, getName())
|
||||
2 errors
|
||||
|
|
110
langtools/test/tools/javac/lambda/MethodReference73.java
Normal file
110
langtools/test/tools/javac/lambda/MethodReference73.java
Normal file
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8026231
|
||||
* @summary Look at 'static' flag when checking method references
|
||||
* @compile/fail/ref=MethodReference73.out -XDrawDiagnostics MethodReference73.java
|
||||
*/
|
||||
|
||||
public class MethodReference73 {
|
||||
|
||||
interface SAM {
|
||||
void m(MethodReference73 rec, String x);
|
||||
}
|
||||
|
||||
void m1(MethodReference73 rec, String x) {}
|
||||
static void m1(MethodReference73 rec, Object x) {}
|
||||
void m1(String x) {}
|
||||
|
||||
static void m2(MethodReference73 rec, String x) {}
|
||||
void m2(Object x) {}
|
||||
static void m2(String x) {}
|
||||
|
||||
static void m3(MethodReference73 rec, String x) {}
|
||||
void m3(String x) {}
|
||||
|
||||
void m4(MethodReference73 rec, String x) {}
|
||||
static void m4(MethodReference73 rec, Object x) {}
|
||||
static void m4(String x) {}
|
||||
void m4(Object x) {}
|
||||
|
||||
static void m5(MethodReference73 rec, String x) {}
|
||||
static void m5(String x) {}
|
||||
|
||||
static void m6(MethodReference73 rec, String x) {}
|
||||
void m6(String x, int i) {}
|
||||
|
||||
void m7(MethodReference73 rec, String x) {}
|
||||
void m7(String x) {}
|
||||
|
||||
static void m8(MethodReference73 rec, String x, int i) {}
|
||||
void m8(String x) {}
|
||||
|
||||
void m9(MethodReference73 rec, String x) {}
|
||||
static void m9(MethodReference73 rec, Object x) {}
|
||||
static void m9(String x) {}
|
||||
|
||||
void m10(MethodReference73 rec, String x) {}
|
||||
static void m10(MethodReference73 rec, Object x) {}
|
||||
void m10(String x, int i) {}
|
||||
|
||||
void m11(MethodReference73 rec, String x) {}
|
||||
void m11(Object x) {}
|
||||
static void m11(String x) {}
|
||||
|
||||
static void m12(MethodReference73 rec, String x, int i) {}
|
||||
void m12(Object x) {}
|
||||
static void m12(String x) {}
|
||||
|
||||
void m13(MethodReference73 rec, String x) {}
|
||||
void m13(String x, int i) {}
|
||||
|
||||
static void m14(MethodReference73 rec, String x, int i) {}
|
||||
static void m14(String x) {}
|
||||
|
||||
void m15(MethodReference73 rec, String x) {}
|
||||
static void m15(String x) {}
|
||||
|
||||
static void m16(MethodReference73 rec, String x, int i) {}
|
||||
void m16(String x, int i) {}
|
||||
|
||||
/** For method references with a type selector two searches are performed.
|
||||
* Each of them may yield one of the following results:
|
||||
* I) a good match
|
||||
* II) a bad match more specific than a good match
|
||||
* III) a bad match with no good matches
|
||||
* IV) no applicable method found
|
||||
*
|
||||
* Whether a match is considered to be good or not depends on the staticness
|
||||
* of the matched method. The expected result of the first search is a static
|
||||
* method. The expected result of the second search is an instance method.
|
||||
*
|
||||
* If the most specific method has the wrong staticness but there is an
|
||||
* applicable method with the right staticness then we have the (II) case.
|
||||
* The (III) case is reserved for those cases when the most specific method
|
||||
* has the wrong staticness but there is no applicable method with the right
|
||||
* staticness.
|
||||
*/
|
||||
|
||||
static void test() {
|
||||
SAM s1 = MethodReference73::m1; //(II, I) ambiguous
|
||||
SAM s2 = MethodReference73::m2; //(I, II) ambiguous
|
||||
SAM s3 = MethodReference73::m3; //(I, I) ambiguous
|
||||
SAM s4 = MethodReference73::m4; //(II, II) ambiguous
|
||||
|
||||
SAM s5 = MethodReference73::m5; //(I, III) first search's result gets selected
|
||||
SAM s6 = MethodReference73::m6; //(I, IV) first search's result gets selected
|
||||
|
||||
SAM s7 = MethodReference73::m7; //(III, I) second search's result gets selected
|
||||
SAM s8 = MethodReference73::m8; //(IV, I) second search's result gets selected
|
||||
|
||||
SAM s9 = MethodReference73::m9; //(II, III) method matched by first search has the wrong staticness
|
||||
SAM s10 = MethodReference73::m10; //(II, IV) method matched by first search has the wrong staticness
|
||||
SAM s11 = MethodReference73::m11; //(III, II) method matched by second search has the wrong staticness
|
||||
SAM s12 = MethodReference73::m12; //(IV, II) method matched by second search has the wrong staticness
|
||||
SAM s13 = MethodReference73::m13; //(III, IV) method matched by first search has the wrong staticness
|
||||
SAM s14 = MethodReference73::m14; //(IV, III) method matched by second search has the wrong staticness
|
||||
SAM s15 = MethodReference73::m15; //(III, III) method matched by first search has the wrong staticness
|
||||
|
||||
SAM s16 = MethodReference73::m16; //(IV, IV) incompatible types, invalid method reference
|
||||
}
|
||||
}
|
13
langtools/test/tools/javac/lambda/MethodReference73.out
Normal file
13
langtools/test/tools/javac/lambda/MethodReference73.out
Normal file
|
@ -0,0 +1,13 @@
|
|||
MethodReference73.java:89:18: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m1, kindname.method, m1(MethodReference73,java.lang.String), MethodReference73, kindname.method, m1(java.lang.String), MethodReference73))
|
||||
MethodReference73.java:90:18: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m2, kindname.method, m2(MethodReference73,java.lang.String), MethodReference73, kindname.method, m2(java.lang.String), MethodReference73))
|
||||
MethodReference73.java:91:18: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m3, kindname.method, m3(MethodReference73,java.lang.String), MethodReference73, kindname.method, m3(java.lang.String), MethodReference73))
|
||||
MethodReference73.java:92:18: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.ref.ambiguous: m4, kindname.method, m4(MethodReference73,java.lang.String), MethodReference73, kindname.method, m4(java.lang.String), MethodReference73))
|
||||
MethodReference73.java:100:18: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m9(MethodReference73,java.lang.String))
|
||||
MethodReference73.java:101:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m10(MethodReference73,java.lang.String))
|
||||
MethodReference73.java:102:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.static.method.in.unbound.lookup: kindname.method, m11(java.lang.String))
|
||||
MethodReference73.java:103:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.static.method.in.unbound.lookup: kindname.method, m12(java.lang.String))
|
||||
MethodReference73.java:104:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m13(MethodReference73,java.lang.String))
|
||||
MethodReference73.java:105:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.static.method.in.unbound.lookup: kindname.method, m14(java.lang.String))
|
||||
MethodReference73.java:106:19: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, m15(MethodReference73,java.lang.String))
|
||||
MethodReference73.java:108:19: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbols: kindname.method, m16, MethodReference73,java.lang.String,{(compiler.misc.inapplicable.method: kindname.method, MethodReference73, m16(MethodReference73,java.lang.String,int), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, MethodReference73, m16(java.lang.String,int), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: MethodReference73, java.lang.String)))}))
|
||||
12 errors
|
|
@ -57,7 +57,7 @@ class TargetType60 {
|
|||
|
||||
static void testUnbound() {
|
||||
TargetType60 s1 = u(TargetType60::n0); //ok - resolves to u(Sam1)
|
||||
TargetType60 s2 = u(TargetType60::n1); //ambiguous (u(Sam1), u(Sam2) apply)
|
||||
TargetType60 s2 = u(TargetType60::n1); //ok - resolves to u(Sam2)
|
||||
TargetType60 s3 = u(TargetType60::n2); //none is applicable
|
||||
TargetType60 s4 = u(TargetType60::n01);//ambiguous (u(Sam1), u(Sam2) apply)
|
||||
TargetType60 s5 = u(TargetType60::n012);//ambiguous (u(Sam1), u(Sam2) apply)
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
TargetType60.java:54:21: compiler.err.ref.ambiguous: g, kindname.method, g(TargetType60.Sam0), TargetType60, kindname.method, <U>g(TargetType60.Sam1<U>), TargetType60
|
||||
TargetType60.java:55:21: compiler.err.ref.ambiguous: g, kindname.method, <U>g(TargetType60.Sam1<U>), TargetType60, kindname.method, <U>g(TargetType60.Sam2<U,java.lang.String>), TargetType60
|
||||
TargetType60.java:60:27: compiler.err.ref.ambiguous: u, kindname.method, <U>u(TargetType60.Sam1<U>), TargetType60, kindname.method, <U>u(TargetType60.Sam2<U,java.lang.String>), TargetType60
|
||||
TargetType60.java:60:29: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, n1(java.lang.String))
|
||||
TargetType60.java:61:29: compiler.err.invalid.mref: kindname.method, (compiler.misc.non-static.cant.be.ref: kindname.method, n2(TargetType60,java.lang.String))
|
||||
TargetType60.java:61:27: compiler.err.cant.apply.symbols: kindname.method, u, @1639,{(compiler.misc.inapplicable.method: kindname.method, TargetType60, <U>u(TargetType60.Sam1<U>), (compiler.misc.infer.no.conforming.assignment.exists: U, (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, n2, TargetType60,java.lang.String, U, kindname.class, TargetType60, (compiler.misc.arg.length.mismatch))))),(compiler.misc.inapplicable.method: kindname.method, TargetType60, <U>u(TargetType60.Sam2<U,java.lang.String>), (compiler.misc.infer.no.conforming.assignment.exists: U, (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.resolve.location.args: kindname.method, n2, , U,java.lang.String, (compiler.misc.location: kindname.class, TargetType60, null)))))}
|
||||
TargetType60.java:62:27: compiler.err.ref.ambiguous: u, kindname.method, <U>u(TargetType60.Sam1<U>), TargetType60, kindname.method, <U>u(TargetType60.Sam2<U,java.lang.String>), TargetType60
|
||||
TargetType60.java:63:27: compiler.err.ref.ambiguous: u, kindname.method, <U>u(TargetType60.Sam1<U>), TargetType60, kindname.method, <U>u(TargetType60.Sam2<U,java.lang.String>), TargetType60
|
||||
7 errors
|
||||
5 errors
|
||||
|
|
|
@ -356,7 +356,7 @@ public class TestInvokeDynamic
|
|||
if (lnt == null) {
|
||||
throw new Error("No LineNumberTable attribute");
|
||||
}
|
||||
if (lnt.line_number_table_length != 2) {
|
||||
if (lnt.line_number_table_length != 3) {
|
||||
throw new Error("Wrong number of entries in LineNumberTable");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
|
|
@ -0,0 +1,208 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import javax.annotation.processing.AbstractProcessor;
|
||||
import javax.annotation.processing.RoundEnvironment;
|
||||
import javax.annotation.processing.SupportedAnnotationTypes;
|
||||
import javax.annotation.processing.SupportedOptions;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.tools.Diagnostic;
|
||||
import javax.tools.DiagnosticCollector;
|
||||
import javax.tools.DiagnosticListener;
|
||||
import javax.tools.FileObject;
|
||||
import javax.tools.ForwardingJavaFileManager;
|
||||
import javax.tools.JavaFileManager;
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.JavaFileObject.Kind;
|
||||
import javax.tools.SimpleJavaFileObject;
|
||||
import com.sun.source.tree.AnnotationTree;
|
||||
import com.sun.source.tree.CompilationUnitTree;
|
||||
import com.sun.source.tree.LiteralTree;
|
||||
import com.sun.source.util.JavacTask;
|
||||
import com.sun.source.util.TreeScanner;
|
||||
import com.sun.source.util.Trees;
|
||||
import com.sun.tools.javac.api.JavacTool;
|
||||
import com.sun.tools.javac.file.JavacFileManager;
|
||||
import com.sun.tools.javac.util.Assert;
|
||||
|
||||
@SupportedAnnotationTypes("*")
|
||||
@SupportedOptions("target")
|
||||
public class Processor extends AbstractProcessor {
|
||||
|
||||
private int round = 0;
|
||||
@Override
|
||||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||
if (round++ == 0) {
|
||||
try (Writer out = processingEnv.getFiler()
|
||||
.createSourceFile("Anno.java")
|
||||
.openWriter()) {
|
||||
String target = processingEnv.getOptions().get("target");
|
||||
String code = "import java.lang.annotation.ElementType;\n" +
|
||||
"import java.lang.annotation.Target;\n" +
|
||||
"@Target(ElementType." + target + ")\n" +
|
||||
"@interface Anno { public String value(); }\n";
|
||||
out.write(code);
|
||||
} catch (IOException exc) {
|
||||
throw new IllegalStateException(exc);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void main(String... args) throws IOException, URISyntaxException {
|
||||
if (args.length != 1) throw new IllegalStateException("Must provide class name!");
|
||||
String testContent = null;
|
||||
File testSrc = new File(System.getProperty("test.src"));
|
||||
File testFile = new File(testSrc, args[0]);
|
||||
if (!testFile.canRead()) throw new IllegalStateException("Cannot read the test source");
|
||||
JavacTool compiler = JavacTool.create();
|
||||
JavacFileManager fm = compiler.getStandardFileManager(null, null, null);
|
||||
testContent = fm.getRegularFile(testFile).getCharContent(true).toString();
|
||||
JavaFileObject testFileObject = new TestFO(new URI("mem://" + args[0]), testContent);
|
||||
TestFM testFileManager = new TestFM(fm);
|
||||
JavacTask task = compiler.getTask(null,
|
||||
testFileManager,
|
||||
new DiagnosticCollector<JavaFileObject>(),
|
||||
null,
|
||||
null,
|
||||
Arrays.asList(testFileObject));
|
||||
final Trees trees = Trees.instance(task);
|
||||
final CompilationUnitTree cut = task.parse().iterator().next();
|
||||
|
||||
final Map<int[], String> annotation2Target = new TreeMap<>(new Comparator<int[]>() {
|
||||
@Override public int compare(int[] o1, int[] o2) {
|
||||
return o2[0] - o1[0];
|
||||
}
|
||||
});
|
||||
|
||||
new TreeScanner<Void, Void>() {
|
||||
@Override
|
||||
public Void visitAnnotation(AnnotationTree node, Void p) {
|
||||
int endPos = (int) trees.getSourcePositions().getEndPosition(cut, node);
|
||||
|
||||
Assert.check(endPos >= 0);
|
||||
|
||||
int startPos = (int) trees.getSourcePositions().getStartPosition(cut, node);
|
||||
String target = ((LiteralTree) node.getArguments().get(0)).getValue().toString();
|
||||
|
||||
annotation2Target.put(new int[] {startPos, endPos}, target);
|
||||
|
||||
return super.visitAnnotation(node, p);
|
||||
}
|
||||
}.scan(cut.getTypeDecls().get(0), null);
|
||||
|
||||
DiagnosticListener<JavaFileObject> noErrors = new DiagnosticListener<JavaFileObject>() {
|
||||
@Override public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
|
||||
if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
|
||||
throw new IllegalStateException(diagnostic.toString());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for (Entry<int[], String> e : annotation2Target.entrySet()) {
|
||||
StringBuilder updatedContent = new StringBuilder();
|
||||
int last = testContent.length();
|
||||
|
||||
for (int[] toRemove : annotation2Target.keySet()) {
|
||||
if (toRemove == e.getKey()) continue;
|
||||
updatedContent.insert(0, testContent.substring(toRemove[1], last));
|
||||
last = toRemove[0];
|
||||
}
|
||||
|
||||
updatedContent.insert(0, testContent.substring(0, last));
|
||||
|
||||
JavaFileObject updatedFile = new TestFO(new URI("mem://" + args[0]),
|
||||
updatedContent.toString());
|
||||
JavacTask testTask = compiler.getTask(null,
|
||||
testFileManager,
|
||||
noErrors,
|
||||
Arrays.asList("-processor", "Processor",
|
||||
"-Atarget=" + e.getValue()),
|
||||
null,
|
||||
Arrays.asList(updatedFile));
|
||||
|
||||
try {
|
||||
testTask.analyze();
|
||||
} catch (Throwable exc) {
|
||||
System.out.println("error while processing:");
|
||||
System.out.println(updatedContent);
|
||||
throw exc;
|
||||
}
|
||||
|
||||
JavacTask testTask2 = compiler.getTask(null,
|
||||
testFileManager,
|
||||
new DiagnosticCollector<JavaFileObject>(),
|
||||
null,
|
||||
null,
|
||||
Arrays.asList(updatedFile));
|
||||
|
||||
try {
|
||||
testTask2.analyze();
|
||||
} catch (Throwable exc) {
|
||||
System.out.println("error while processing:");
|
||||
System.out.println(updatedContent);
|
||||
throw exc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final class TestFO extends SimpleJavaFileObject {
|
||||
private final String content;
|
||||
public TestFO(URI uri, String content) {
|
||||
super(uri, Kind.SOURCE);
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
@Override public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
|
||||
return content;
|
||||
}
|
||||
|
||||
@Override public boolean isNameCompatible(String simpleName, Kind kind) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class TestFM extends ForwardingJavaFileManager<JavaFileManager> {
|
||||
|
||||
public TestFM(JavaFileManager fileManager) {
|
||||
super(fileManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameFile(FileObject a, FileObject b) {
|
||||
return a.equals(b);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8027310
|
||||
* @summary Ensure no exceptions on unresolvable annotations
|
||||
* @build Processor
|
||||
* @run main Processor Source.java
|
||||
*/
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Anno("TYPE")
|
||||
public class Source {
|
||||
@Anno("TYPE")
|
||||
class Inner {
|
||||
class InnerInner {
|
||||
public @Anno("CONSTRUCTOR") InnerInner(@Anno("TYPE_USE") Source. @Anno("TYPE_USE") Inner Inner.this,
|
||||
@Anno("PARAMETER") java.lang. @Anno("TYPE_USE") Runnable p) {
|
||||
Runnable r = () -> {
|
||||
@Anno("TYPE_USE") Object tested = null;
|
||||
@Anno("TYPE_USE") boolean isAnnotated = tested instanceof @Anno("TYPE_USE") String;
|
||||
};
|
||||
|
||||
@Anno("TYPE_USE") Object tested = (@Anno("TYPE_USE") String @Anno("TYPE_USE") []) null;
|
||||
@Anno("TYPE_USE") boolean isAnnotated = tested instanceof@Anno("TYPE_USE") String;
|
||||
|
||||
tested = new java.lang. @Anno("TYPE_USE") Object();
|
||||
tested = new @Anno("TYPE_USE") Object();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
Runnable r = () -> {
|
||||
@Anno("TYPE_USE") Object tested = null;
|
||||
@Anno("TYPE_USE") boolean isAnnotated = tested instanceof @Anno("TYPE_USE") String;
|
||||
};
|
||||
|
||||
@Anno("TYPE_USE") Object tested = (@Anno("TYPE_USE") String @Anno("TYPE_USE") []) null;
|
||||
@Anno("TYPE_USE") boolean isAnnotated = tested instanceof@Anno("TYPE_USE") String;
|
||||
|
||||
tested = new java.lang. @Anno("TYPE_USE") Object();
|
||||
tested = new @Anno("TYPE_USE") Object();
|
||||
}
|
||||
|
||||
@Anno("TYPE")
|
||||
@Anno("ANNOTATION_TYPE")
|
||||
@interface A { }
|
||||
abstract class Parameterized<@Anno("TYPE_PARAMETER") T extends @Anno("TYPE_USE") CharSequence &
|
||||
@Anno("TYPE_USE") Runnable>
|
||||
implements @Anno("TYPE_USE") List<@Anno("TYPE_USE") Runnable> { }
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8027730
|
||||
* @summary Test visitor support for intersection types
|
||||
*/
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.List;
|
||||
import javax.lang.model.element.*;
|
||||
import javax.lang.model.type.*;
|
||||
import javax.lang.model.util.*;
|
||||
|
||||
public class TestIntersectionTypeVisitors {
|
||||
public static void main(String... args) throws Exception {
|
||||
IntersectionType it = new TestIntersectionType();
|
||||
|
||||
boolean result = it.accept(new TypeKindVisitor8Child(), null) &&
|
||||
it.accept(new SimpleTypeVisitor8Child(), null) &&
|
||||
it.accept(new SimpleTypeVisitor6Child(), null);
|
||||
|
||||
if (!result)
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
static class TestIntersectionType implements IntersectionType {
|
||||
TestIntersectionType() {}
|
||||
|
||||
@Override
|
||||
public List<? extends TypeMirror> getBounds() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R,P> R accept(TypeVisitor<R,P> v,
|
||||
P p) {
|
||||
return v.visitIntersection(this, p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeKind getKind() {
|
||||
return TypeKind.INTERSECTION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends AnnotationMirror> getAnnotationMirrors() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
static class TypeKindVisitor8Child extends TypeKindVisitor8<Boolean, Void> {
|
||||
TypeKindVisitor8Child() {
|
||||
super(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitIntersection(IntersectionType t, Void p) {
|
||||
super.visitIntersection(t, p); // Make sure overridden method doesn't throw an exception
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static class SimpleTypeVisitor8Child extends SimpleTypeVisitor8<Boolean, Void> {
|
||||
SimpleTypeVisitor8Child() {
|
||||
super(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitIntersection(IntersectionType t, Void p) {
|
||||
super.visitIntersection(t, p); // Make sure overridden method doesn't throw an exception
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static class SimpleTypeVisitor6Child extends SimpleTypeVisitor6<Boolean, Void> {
|
||||
SimpleTypeVisitor6Child() {
|
||||
super(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean visitIntersection(IntersectionType t, Void p) {
|
||||
try {
|
||||
super.visitIntersection(t, p);
|
||||
return false;
|
||||
} catch (UnknownTypeException ute) {
|
||||
return true; // Expected
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8025844
|
||||
* @summary test DocumentationTool.Location methods
|
||||
* @build APITest
|
||||
* @run main DocumentationToolLocationTest
|
||||
*/
|
||||
|
||||
import javax.tools.DocumentationTool;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Test for DocumentationTool.Location methods.
|
||||
*/
|
||||
public class DocumentationToolLocationTest extends APITest {
|
||||
public static void main(String[] args) throws Exception {
|
||||
new DocumentationToolLocationTest().run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getName() method
|
||||
*/
|
||||
@Test
|
||||
public void testGetName() throws Exception {
|
||||
// getName() returns name(). This is for test coverage of getName.
|
||||
for (DocumentationTool.Location dl: DocumentationTool.Location.values()) {
|
||||
String expect = dl.name();
|
||||
String found = dl.getName();
|
||||
if (!Objects.equals(expect, found))
|
||||
throw new Exception("mismatch for " + dl + "; expected " + expect + ", found " + found);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test generated enum methods values() and valueOf()
|
||||
*/
|
||||
@Test
|
||||
public void testEnumMethods() throws Exception {
|
||||
DocumentationTool.Location[] values = DocumentationTool.Location.values();
|
||||
if (values.length != 3)
|
||||
throw new Exception("unexpected number of values returned");
|
||||
|
||||
for (DocumentationTool.Location dl: values) {
|
||||
DocumentationTool.Location expect = dl;
|
||||
DocumentationTool.Location found = DocumentationTool.Location.valueOf(dl.name());
|
||||
if (!Objects.equals(expect, found))
|
||||
throw new Exception("mismatch for " + dl + "; expected " + expect + ", found " + found);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,7 +16,7 @@ class pkg1.O<T>.I<S>
|
|||
superclass:
|
||||
java.lang.Object
|
||||
constructors:
|
||||
O.I()
|
||||
I()
|
||||
methods:
|
||||
void m1(O<String>.I<Number>)
|
||||
|
||||
|
@ -36,7 +36,7 @@ class pkg1.X<T>.Y
|
|||
superclass:
|
||||
java.lang.Object
|
||||
constructors:
|
||||
X.Y()
|
||||
Y()
|
||||
|
||||
class pkg1.X<T>.Y.Z<S>
|
||||
name: Z / X.Y.Z / pkg1.X.Y.Z
|
||||
|
@ -47,7 +47,7 @@ class pkg1.X<T>.Y.Z<S>
|
|||
superclass:
|
||||
java.lang.Object
|
||||
constructors:
|
||||
X.Y.Z()
|
||||
Z()
|
||||
methods:
|
||||
void m1(X<String>.Y.Z<Number>)
|
||||
|
||||
|
|
120
langtools/test/tools/javap/AccessModifiers.java
Normal file
120
langtools/test/tools/javap/AccessModifiers.java
Normal file
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8027530
|
||||
* @summary test -public, -protected, -package, -private options
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.lang.StringBuilder;
|
||||
|
||||
public class AccessModifiers {
|
||||
public int errorCount;
|
||||
protected String protectedField;
|
||||
String packageField;
|
||||
private String privateField;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new AccessModifiers().run();
|
||||
}
|
||||
|
||||
private void run() throws Exception {
|
||||
List<String> pubMembers = new ArrayList<String>();
|
||||
pubMembers.add("public int errorCount");
|
||||
pubMembers.add("public AccessModifiers");
|
||||
pubMembers.add("public static void main");
|
||||
|
||||
List<String> proMembers = new ArrayList<String>();
|
||||
proMembers.add("protected java.lang.String protectedField");
|
||||
proMembers.add("protected java.lang.String runJavap");
|
||||
|
||||
List<String> pkgMembers = new ArrayList<String>();
|
||||
pkgMembers.add("java.lang.String packageField");
|
||||
pkgMembers.add("boolean verify");
|
||||
pkgMembers.add("void error");
|
||||
|
||||
List<String> priMembers = new ArrayList<String>();
|
||||
priMembers.add("private java.lang.String privateField");
|
||||
priMembers.add("private void run() throws java.lang.Exception");
|
||||
priMembers.add("private void test");
|
||||
|
||||
List<String> expectedList = new ArrayList<String>();
|
||||
|
||||
expectedList.addAll(pubMembers);
|
||||
test("-public", expectedList);
|
||||
|
||||
expectedList.addAll(proMembers);
|
||||
test("-protected", expectedList);
|
||||
|
||||
expectedList.addAll(pkgMembers);
|
||||
test("-package", expectedList);
|
||||
|
||||
expectedList.addAll(priMembers);
|
||||
test("-private", expectedList);
|
||||
|
||||
if (errorCount > 0)
|
||||
throw new Exception(errorCount + " errors received");
|
||||
}
|
||||
|
||||
private void test(String option, List<String> expectedStrs) throws Exception {
|
||||
String output = runJavap(0, option);
|
||||
if (verify(output, expectedStrs))
|
||||
System.out.println(option + " test passed");
|
||||
}
|
||||
|
||||
protected String runJavap(int expect, String... options) {
|
||||
// convert the varargs to a list in order to add class name
|
||||
List<String> optlist = new ArrayList<String>();
|
||||
optlist.addAll(Arrays.asList(options));
|
||||
optlist.add("AccessModifiers");
|
||||
String[] newoptions = optlist.toArray(new String[optlist.size()]);
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
System.out.printf("\nRun javap " + optlist + "\n\n");
|
||||
int rc = com.sun.tools.javap.Main.run(newoptions, pw);
|
||||
pw.close();
|
||||
System.out.println(sw);
|
||||
if (rc != expect)
|
||||
throw new Error("Expect to return " + expect + ", but return " + rc);
|
||||
return sw.toString();
|
||||
}
|
||||
|
||||
boolean verify(String output, List<String> expects) {
|
||||
boolean pass = true;
|
||||
for (String expect: expects) {
|
||||
if (!output.contains(expect)) {
|
||||
error(expect + " not found");
|
||||
pass = false;
|
||||
}
|
||||
}
|
||||
return pass;
|
||||
}
|
||||
|
||||
void error(String msg) {
|
||||
System.err.println(msg);
|
||||
errorCount++;
|
||||
}
|
||||
}
|
78
langtools/test/tools/javap/InvalidOptions.java
Normal file
78
langtools/test/tools/javap/InvalidOptions.java
Normal file
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8027411
|
||||
* @summary test invalid options -h and -b
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.util.zip.*;
|
||||
|
||||
public class InvalidOptions {
|
||||
int errorCount;
|
||||
String log;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new InvalidOptions().run();
|
||||
}
|
||||
|
||||
void run() throws Exception {
|
||||
test(2, "-h", "Error: -h is no longer available - use the javah program");
|
||||
test(2, "-b", "Error: unknown option: -b",
|
||||
"Usage: javap <options> <classes>",
|
||||
"use -help for a list of possible options");
|
||||
if (errorCount > 0)
|
||||
throw new Exception(errorCount + " errors received");
|
||||
}
|
||||
|
||||
void test(int expect, String option, String ... expectedOutput) {
|
||||
String output = runJavap(expect, option);
|
||||
verify(output, expectedOutput);
|
||||
}
|
||||
|
||||
String runJavap(int expect, String... option) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
int rc = com.sun.tools.javap.Main.run(option, pw);
|
||||
pw.close();
|
||||
System.out.println("javap prints:");
|
||||
System.out.println(sw);
|
||||
if (rc != expect)
|
||||
throw new Error("Expect to return " + expect + ", but return " + rc);
|
||||
return sw.toString();
|
||||
}
|
||||
|
||||
void verify(String output, String... expects) {
|
||||
for (String expect: expects) {
|
||||
if (!output.contains(expect))
|
||||
error(expect + " not found");
|
||||
}
|
||||
}
|
||||
|
||||
void error(String msg) {
|
||||
System.err.println(msg);
|
||||
errorCount++;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue