mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-20 11:04:34 +02:00
6979327: method handle invocation should use casts instead of type parameters to specify return type
Infer return type for polymorphic signature calls according to updated JSR 292 draft Reviewed-by: jjg
This commit is contained in:
parent
73825fc885
commit
cd74d63c12
26 changed files with 516 additions and 380 deletions
|
@ -171,11 +171,10 @@ public enum Source {
|
||||||
public boolean allowUnderscoresInLiterals() {
|
public boolean allowUnderscoresInLiterals() {
|
||||||
return compareTo(JDK1_7) >= 0;
|
return compareTo(JDK1_7) >= 0;
|
||||||
}
|
}
|
||||||
public boolean allowStringsInSwitch() {
|
public boolean allowExoticIdentifiers() {
|
||||||
return compareTo(JDK1_7) >= 0;
|
return compareTo(JDK1_7) >= 0;
|
||||||
}
|
}
|
||||||
// JSR 292: recognize @PolymorphicSignature on java/dyn names
|
public boolean allowStringsInSwitch() {
|
||||||
public boolean allowPolymorphicSignature() {
|
|
||||||
return compareTo(JDK1_7) >= 0;
|
return compareTo(JDK1_7) >= 0;
|
||||||
}
|
}
|
||||||
public static SourceVersion toSourceVersion(Source source) {
|
public static SourceVersion toSourceVersion(Source source) {
|
||||||
|
|
|
@ -214,6 +214,16 @@ public abstract class Symbol implements Element {
|
||||||
return (flags() & INTERFACE) != 0;
|
return (flags() & INTERFACE) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Recognize if this symbol was marked @PolymorphicSignature in the source. */
|
||||||
|
public boolean isPolymorphicSignatureGeneric() {
|
||||||
|
return (flags() & (POLYMORPHIC_SIGNATURE | HYPOTHETICAL)) == POLYMORPHIC_SIGNATURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Recognize if this symbol was split from a @PolymorphicSignature symbol in the source. */
|
||||||
|
public boolean isPolymorphicSignatureInstance() {
|
||||||
|
return (flags() & (POLYMORPHIC_SIGNATURE | HYPOTHETICAL)) == (POLYMORPHIC_SIGNATURE | HYPOTHETICAL);
|
||||||
|
}
|
||||||
|
|
||||||
/** Is this symbol declared (directly or indirectly) local
|
/** Is this symbol declared (directly or indirectly) local
|
||||||
* to a method or variable initializer?
|
* to a method or variable initializer?
|
||||||
* Also includes fields of inner classes which are in
|
* Also includes fields of inner classes which are in
|
||||||
|
|
|
@ -1185,7 +1185,10 @@ public class Attr extends JCTree.Visitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitExec(JCExpressionStatement tree) {
|
public void visitExec(JCExpressionStatement tree) {
|
||||||
attribExpr(tree.expr, env);
|
//a fresh environment is required for 292 inference to work properly ---
|
||||||
|
//see Infer.instantiatePolymorphicSignatureInstance()
|
||||||
|
Env<AttrContext> localEnv = env.dup(tree);
|
||||||
|
attribExpr(tree.expr, localEnv);
|
||||||
result = null;
|
result = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1443,23 +1446,19 @@ public class Attr extends JCTree.Visitor {
|
||||||
restype.tsym);
|
restype.tsym);
|
||||||
}
|
}
|
||||||
|
|
||||||
// as a special case, MethodHandle.<T>invoke(abc) and InvokeDynamic.<T>foo(abc)
|
// Special case logic for JSR 292 types.
|
||||||
// has type <T>, and T can be a primitive type.
|
if (rs.allowTransitionalJSR292 &&
|
||||||
if (tree.meth.getTag() == JCTree.SELECT && !typeargtypes.isEmpty()) {
|
tree.meth.getTag() == JCTree.SELECT &&
|
||||||
JCFieldAccess mfield = (JCFieldAccess) tree.meth;
|
!typeargtypes.isEmpty()) {
|
||||||
if ((mfield.selected.type.tsym != null &&
|
JCFieldAccess mfield = (JCFieldAccess) tree.meth;
|
||||||
(mfield.selected.type.tsym.flags() & POLYMORPHIC_SIGNATURE) != 0)
|
// MethodHandle.<T>invoke(abc) and InvokeDynamic.<T>foo(abc)
|
||||||
||
|
// has type <T>, and T can be a primitive type.
|
||||||
(mfield.sym != null &&
|
if (mfield.sym != null &&
|
||||||
(mfield.sym.flags() & POLYMORPHIC_SIGNATURE) != 0)) {
|
mfield.sym.isPolymorphicSignatureInstance())
|
||||||
assert types.isSameType(restype, typeargtypes.head) : mtype;
|
typeargtypesNonRefOK = true;
|
||||||
assert mfield.selected.type == syms.methodHandleType
|
|
||||||
|| mfield.selected.type == syms.invokeDynamicType;
|
|
||||||
typeargtypesNonRefOK = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!typeargtypesNonRefOK) {
|
if (!(rs.allowTransitionalJSR292 && typeargtypesNonRefOK)) {
|
||||||
chk.checkRefTypes(tree.typeargs, typeargtypes);
|
chk.checkRefTypes(tree.typeargs, typeargtypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2023,7 +2022,10 @@ public class Attr extends JCTree.Visitor {
|
||||||
public void visitTypeCast(JCTypeCast tree) {
|
public void visitTypeCast(JCTypeCast tree) {
|
||||||
Type clazztype = attribType(tree.clazz, env);
|
Type clazztype = attribType(tree.clazz, env);
|
||||||
chk.validate(tree.clazz, env, false);
|
chk.validate(tree.clazz, env, false);
|
||||||
Type exprtype = attribExpr(tree.expr, env, Infer.anyPoly);
|
//a fresh environment is required for 292 inference to work properly ---
|
||||||
|
//see Infer.instantiatePolymorphicSignatureInstance()
|
||||||
|
Env<AttrContext> localEnv = env.dup(tree);
|
||||||
|
Type exprtype = attribExpr(tree.expr, localEnv, Infer.anyPoly);
|
||||||
Type owntype = chk.checkCastable(tree.expr.pos(), exprtype, clazztype);
|
Type owntype = chk.checkCastable(tree.expr.pos(), exprtype, clazztype);
|
||||||
if (exprtype.constValue() != null)
|
if (exprtype.constValue() != null)
|
||||||
owntype = cfolder.coerce(exprtype, owntype);
|
owntype = cfolder.coerce(exprtype, owntype);
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
|
|
||||||
package com.sun.tools.javac.comp;
|
package com.sun.tools.javac.comp;
|
||||||
|
|
||||||
|
import com.sun.tools.javac.tree.JCTree;
|
||||||
|
import com.sun.tools.javac.tree.JCTree.JCTypeCast;
|
||||||
import com.sun.tools.javac.util.*;
|
import com.sun.tools.javac.util.*;
|
||||||
import com.sun.tools.javac.util.List;
|
import com.sun.tools.javac.util.List;
|
||||||
import com.sun.tools.javac.code.*;
|
import com.sun.tools.javac.code.*;
|
||||||
|
@ -543,4 +545,56 @@ public class Infer {
|
||||||
args.head, bounds);
|
args.head, bounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute a synthetic method type corresponding to the requested polymorphic
|
||||||
|
* method signature. If no explicit return type is supplied, a provisional
|
||||||
|
* return type is computed (just Object in case of non-transitional 292)
|
||||||
|
*/
|
||||||
|
Type instantiatePolymorphicSignatureInstance(Env<AttrContext> env, Type site,
|
||||||
|
Name name,
|
||||||
|
MethodSymbol spMethod, // sig. poly. method or null if none
|
||||||
|
List<Type> argtypes,
|
||||||
|
List<Type> typeargtypes) {
|
||||||
|
final Type restype;
|
||||||
|
if (rs.allowTransitionalJSR292 && typeargtypes.nonEmpty()) {
|
||||||
|
restype = typeargtypes.head;
|
||||||
|
} else {
|
||||||
|
//The return type for a polymorphic signature call is computed from
|
||||||
|
//the enclosing tree E, as follows: if E is a cast, then use the
|
||||||
|
//target type of the cast expression as a return type; if E is an
|
||||||
|
//expression statement, the return type is 'void' - otherwise the
|
||||||
|
//return type is simply 'Object'.
|
||||||
|
switch (env.outer.tree.getTag()) {
|
||||||
|
case JCTree.TYPECAST:
|
||||||
|
restype = ((JCTypeCast)env.outer.tree).clazz.type; break;
|
||||||
|
case JCTree.EXEC:
|
||||||
|
restype = syms.voidType; break;
|
||||||
|
default:
|
||||||
|
restype = syms.objectType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Type> paramtypes = Type.map(argtypes, implicitArgType);
|
||||||
|
List<Type> exType = spMethod != null ?
|
||||||
|
spMethod.getThrownTypes() :
|
||||||
|
List.of(syms.throwableType); // make it throw all exceptions
|
||||||
|
|
||||||
|
MethodType mtype = new MethodType(paramtypes,
|
||||||
|
restype,
|
||||||
|
exType,
|
||||||
|
syms.methodClass);
|
||||||
|
return mtype;
|
||||||
|
}
|
||||||
|
//where
|
||||||
|
Mapping implicitArgType = new Mapping ("implicitArgType") {
|
||||||
|
public Type apply(Type t) {
|
||||||
|
t = types.erasure(t);
|
||||||
|
if (t.tag == BOT)
|
||||||
|
// nulls type as the marker type Null (which has no instances)
|
||||||
|
// infer as java.lang.Void for now
|
||||||
|
t = types.boxedClass(syms.voidType).type;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -769,9 +769,17 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||||
&& types.isSameType(c.type, syms.deprecatedType))
|
&& types.isSameType(c.type, syms.deprecatedType))
|
||||||
s.flags_field |= Flags.DEPRECATED;
|
s.flags_field |= Flags.DEPRECATED;
|
||||||
// Internally to java.dyn, a @PolymorphicSignature annotation
|
// Internally to java.dyn, a @PolymorphicSignature annotation
|
||||||
// translates to a classfile attribute.
|
// acts like a classfile attribute.
|
||||||
if (!c.type.isErroneous()
|
if (!c.type.isErroneous() &&
|
||||||
&& types.isSameType(c.type, syms.polymorphicSignatureType)) {
|
types.isSameType(c.type, syms.polymorphicSignatureType)) {
|
||||||
|
if (!target.hasMethodHandles()) {
|
||||||
|
// Somebody is compiling JDK7 source code to a JDK6 target.
|
||||||
|
// Make it a strict warning, since it is unlikely but important.
|
||||||
|
log.strictWarning(env.tree.pos(),
|
||||||
|
"wrong.target.for.polymorphic.signature.definition",
|
||||||
|
target.name);
|
||||||
|
}
|
||||||
|
// Pull the flag through for better diagnostics, even on a bad target.
|
||||||
s.flags_field |= Flags.POLYMORPHIC_SIGNATURE;
|
s.flags_field |= Flags.POLYMORPHIC_SIGNATURE;
|
||||||
}
|
}
|
||||||
if (!annotated.add(a.type.tsym))
|
if (!annotated.add(a.type.tsym))
|
||||||
|
|
|
@ -69,9 +69,13 @@ public class Resolve {
|
||||||
JCDiagnostic.Factory diags;
|
JCDiagnostic.Factory diags;
|
||||||
public final boolean boxingEnabled; // = source.allowBoxing();
|
public final boolean boxingEnabled; // = source.allowBoxing();
|
||||||
public final boolean varargsEnabled; // = source.allowVarargs();
|
public final boolean varargsEnabled; // = source.allowVarargs();
|
||||||
public final boolean allowPolymorphicSignature;
|
public final boolean allowMethodHandles;
|
||||||
|
public final boolean allowInvokeDynamic;
|
||||||
|
public final boolean allowTransitionalJSR292;
|
||||||
private final boolean debugResolve;
|
private final boolean debugResolve;
|
||||||
|
|
||||||
|
Scope polymorphicSignatureScope;
|
||||||
|
|
||||||
public static Resolve instance(Context context) {
|
public static Resolve instance(Context context) {
|
||||||
Resolve instance = context.get(resolveKey);
|
Resolve instance = context.get(resolveKey);
|
||||||
if (instance == null)
|
if (instance == null)
|
||||||
|
@ -107,7 +111,14 @@ public class Resolve {
|
||||||
varargsEnabled = source.allowVarargs();
|
varargsEnabled = source.allowVarargs();
|
||||||
Options options = Options.instance(context);
|
Options options = Options.instance(context);
|
||||||
debugResolve = options.get("debugresolve") != null;
|
debugResolve = options.get("debugresolve") != null;
|
||||||
allowPolymorphicSignature = source.allowPolymorphicSignature() || options.get("invokedynamic") != null;
|
allowTransitionalJSR292 = options.get("allowTransitionalJSR292") != null;
|
||||||
|
Target target = Target.instance(context);
|
||||||
|
allowMethodHandles = allowTransitionalJSR292 ||
|
||||||
|
target.hasMethodHandles();
|
||||||
|
allowInvokeDynamic = (allowTransitionalJSR292 ||
|
||||||
|
target.hasInvokedynamic()) &&
|
||||||
|
options.get("invokedynamic") != null;
|
||||||
|
polymorphicSignatureScope = new Scope(syms.noSymbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** error symbols, which are returned when resolution fails
|
/** error symbols, which are returned when resolution fails
|
||||||
|
@ -246,7 +257,8 @@ public class Resolve {
|
||||||
/* `sym' is accessible only if not overridden by
|
/* `sym' is accessible only if not overridden by
|
||||||
* another symbol which is a member of `site'
|
* another symbol which is a member of `site'
|
||||||
* (because, if it is overridden, `sym' is not strictly
|
* (because, if it is overridden, `sym' is not strictly
|
||||||
* speaking a member of `site'.)
|
* speaking a member of `site'). A polymorphic signature method
|
||||||
|
* cannot be overridden (e.g. MH.invokeExact(Object[])).
|
||||||
*/
|
*/
|
||||||
private boolean notOverriddenIn(Type site, Symbol sym) {
|
private boolean notOverriddenIn(Type site, Symbol sym) {
|
||||||
if (sym.kind != MTH || sym.isConstructor() || sym.isStatic())
|
if (sym.kind != MTH || sym.isConstructor() || sym.isStatic())
|
||||||
|
@ -254,6 +266,7 @@ public class Resolve {
|
||||||
else {
|
else {
|
||||||
Symbol s2 = ((MethodSymbol)sym).implementation(site.tsym, types, true);
|
Symbol s2 = ((MethodSymbol)sym).implementation(site.tsym, types, true);
|
||||||
return (s2 == null || s2 == sym ||
|
return (s2 == null || s2 == sym ||
|
||||||
|
s2.isPolymorphicSignatureGeneric() ||
|
||||||
!types.isSubSignature(types.memberType(site, s2), types.memberType(site, sym)));
|
!types.isSubSignature(types.memberType(site, s2), types.memberType(site, sym)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -303,7 +316,8 @@ public class Resolve {
|
||||||
boolean useVarargs,
|
boolean useVarargs,
|
||||||
Warner warn)
|
Warner warn)
|
||||||
throws Infer.InferenceException {
|
throws Infer.InferenceException {
|
||||||
assert ((m.flags() & (POLYMORPHIC_SIGNATURE|HYPOTHETICAL)) != POLYMORPHIC_SIGNATURE);
|
boolean polymorphicSignature = (m.isPolymorphicSignatureGeneric() && allowMethodHandles) ||
|
||||||
|
isTransitionalDynamicCallSite(site, m);
|
||||||
if (useVarargs && (m.flags() & VARARGS) == 0) return null;
|
if (useVarargs && (m.flags() & VARARGS) == 0) return null;
|
||||||
Type mt = types.memberType(site, m);
|
Type mt = types.memberType(site, m);
|
||||||
|
|
||||||
|
@ -311,7 +325,10 @@ public class Resolve {
|
||||||
// need to inferred.
|
// need to inferred.
|
||||||
List<Type> tvars = env.info.tvars;
|
List<Type> tvars = env.info.tvars;
|
||||||
if (typeargtypes == null) typeargtypes = List.nil();
|
if (typeargtypes == null) typeargtypes = List.nil();
|
||||||
if (mt.tag != FORALL && typeargtypes.nonEmpty()) {
|
if (allowTransitionalJSR292 && polymorphicSignature && typeargtypes.nonEmpty()) {
|
||||||
|
//transitional 292 call sites might have wrong number of targs
|
||||||
|
}
|
||||||
|
else if (mt.tag != FORALL && typeargtypes.nonEmpty()) {
|
||||||
// This is not a polymorphic method, but typeargs are supplied
|
// This is not a polymorphic method, but typeargs are supplied
|
||||||
// which is fine, see JLS3 15.12.2.1
|
// which is fine, see JLS3 15.12.2.1
|
||||||
} else if (mt.tag == FORALL && typeargtypes.nonEmpty()) {
|
} else if (mt.tag == FORALL && typeargtypes.nonEmpty()) {
|
||||||
|
@ -339,7 +356,8 @@ public class Resolve {
|
||||||
}
|
}
|
||||||
|
|
||||||
// find out whether we need to go the slow route via infer
|
// find out whether we need to go the slow route via infer
|
||||||
boolean instNeeded = tvars.tail != null/*inlined: tvars.nonEmpty()*/;
|
boolean instNeeded = tvars.tail != null || /*inlined: tvars.nonEmpty()*/
|
||||||
|
polymorphicSignature;
|
||||||
for (List<Type> l = argtypes;
|
for (List<Type> l = argtypes;
|
||||||
l.tail != null/*inlined: l.nonEmpty()*/ && !instNeeded;
|
l.tail != null/*inlined: l.nonEmpty()*/ && !instNeeded;
|
||||||
l = l.tail) {
|
l = l.tail) {
|
||||||
|
@ -347,8 +365,9 @@ public class Resolve {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instNeeded)
|
if (instNeeded)
|
||||||
return
|
return polymorphicSignature ?
|
||||||
infer.instantiateMethod(env,
|
infer.instantiatePolymorphicSignatureInstance(env, site, m.name, (MethodSymbol)m, argtypes, typeargtypes) :
|
||||||
|
infer.instantiateMethod(env,
|
||||||
tvars,
|
tvars,
|
||||||
(MethodType)mt,
|
(MethodType)mt,
|
||||||
m,
|
m,
|
||||||
|
@ -363,6 +382,14 @@ public class Resolve {
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isTransitionalDynamicCallSite(Type site, Symbol sym) {
|
||||||
|
return allowTransitionalJSR292 && // old logic that doesn't use annotations
|
||||||
|
!sym.isPolymorphicSignatureInstance() &&
|
||||||
|
((allowMethodHandles && site == syms.methodHandleType && // invokeExact, invokeGeneric, invoke
|
||||||
|
(sym.name == names.invoke && sym.isPolymorphicSignatureGeneric())) ||
|
||||||
|
(site == syms.invokeDynamicType && allowInvokeDynamic)); // InvokeDynamic.XYZ
|
||||||
|
}
|
||||||
|
|
||||||
/** Same but returns null instead throwing a NoInstanceException
|
/** Same but returns null instead throwing a NoInstanceException
|
||||||
*/
|
*/
|
||||||
Type instantiate(Env<AttrContext> env,
|
Type instantiate(Env<AttrContext> env,
|
||||||
|
@ -580,14 +607,6 @@ public class Resolve {
|
||||||
if (sym.kind == ERR) return bestSoFar;
|
if (sym.kind == ERR) return bestSoFar;
|
||||||
if (!sym.isInheritedIn(site.tsym, types)) return bestSoFar;
|
if (!sym.isInheritedIn(site.tsym, types)) return bestSoFar;
|
||||||
assert sym.kind < AMBIGUOUS;
|
assert sym.kind < AMBIGUOUS;
|
||||||
if ((sym.flags() & POLYMORPHIC_SIGNATURE) != 0 && allowPolymorphicSignature) {
|
|
||||||
assert(site.tag == CLASS);
|
|
||||||
// Never match a MethodHandle.invoke directly.
|
|
||||||
if (useVarargs | allowBoxing | operator)
|
|
||||||
return bestSoFar;
|
|
||||||
// Supply an exactly-typed implicit method instead.
|
|
||||||
sym = findPolymorphicSignatureInstance(env, sym.owner.type, sym.name, (MethodSymbol) sym, argtypes, typeargtypes);
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
if (rawInstantiate(env, site, sym, argtypes, typeargtypes,
|
if (rawInstantiate(env, site, sym, argtypes, typeargtypes,
|
||||||
allowBoxing, useVarargs, Warner.noWarnings) == null) {
|
allowBoxing, useVarargs, Warner.noWarnings) == null) {
|
||||||
|
@ -759,13 +778,6 @@ public class Resolve {
|
||||||
boolean useVarargs,
|
boolean useVarargs,
|
||||||
boolean operator) {
|
boolean operator) {
|
||||||
Symbol bestSoFar = methodNotFound;
|
Symbol bestSoFar = methodNotFound;
|
||||||
if ((site.tsym.flags() & POLYMORPHIC_SIGNATURE) != 0 &&
|
|
||||||
allowPolymorphicSignature &&
|
|
||||||
site.tag == CLASS &&
|
|
||||||
!(useVarargs | allowBoxing | operator)) {
|
|
||||||
// supply an exactly-typed implicit method in java.dyn.InvokeDynamic
|
|
||||||
bestSoFar = findPolymorphicSignatureInstance(env, site, name, null, argtypes, typeargtypes);
|
|
||||||
}
|
|
||||||
return findMethod(env,
|
return findMethod(env,
|
||||||
site,
|
site,
|
||||||
name,
|
name,
|
||||||
|
@ -907,90 +919,6 @@ public class Resolve {
|
||||||
return bestSoFar;
|
return bestSoFar;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Find or create an implicit method of exactly the given type (after erasure).
|
|
||||||
* Searches in a side table, not the main scope of the site.
|
|
||||||
* This emulates the lookup process required by JSR 292 in JVM.
|
|
||||||
* @param env The current environment.
|
|
||||||
* @param site The original type from where the selection
|
|
||||||
* takes place.
|
|
||||||
* @param name The method's name.
|
|
||||||
* @param argtypes The method's value arguments.
|
|
||||||
* @param typeargtypes The method's type arguments
|
|
||||||
*/
|
|
||||||
Symbol findPolymorphicSignatureInstance(Env<AttrContext> env,
|
|
||||||
Type site,
|
|
||||||
Name name,
|
|
||||||
MethodSymbol spMethod, // sig. poly. method or null if none
|
|
||||||
List<Type> argtypes,
|
|
||||||
List<Type> typeargtypes) {
|
|
||||||
assert allowPolymorphicSignature;
|
|
||||||
//assert site == syms.invokeDynamicType || site == syms.methodHandleType : site;
|
|
||||||
ClassSymbol c = (ClassSymbol) site.tsym;
|
|
||||||
Scope implicit = c.members().next;
|
|
||||||
if (implicit == null) {
|
|
||||||
c.members().next = implicit = new Scope(c);
|
|
||||||
}
|
|
||||||
Type restype;
|
|
||||||
if (typeargtypes.isEmpty()) {
|
|
||||||
restype = syms.objectType;
|
|
||||||
} else {
|
|
||||||
restype = typeargtypes.head;
|
|
||||||
if (!typeargtypes.tail.isEmpty())
|
|
||||||
return methodNotFound;
|
|
||||||
}
|
|
||||||
List<Type> paramtypes = Type.map(argtypes, implicitArgType);
|
|
||||||
long flags;
|
|
||||||
List<Type> exType;
|
|
||||||
if (spMethod != null) {
|
|
||||||
exType = spMethod.getThrownTypes();
|
|
||||||
flags = spMethod.flags() & AccessFlags;
|
|
||||||
} else {
|
|
||||||
// make it throw all exceptions
|
|
||||||
//assert(site == syms.invokeDynamicType);
|
|
||||||
exType = List.of(syms.throwableType);
|
|
||||||
flags = PUBLIC | STATIC;
|
|
||||||
}
|
|
||||||
MethodType mtype = new MethodType(paramtypes,
|
|
||||||
restype,
|
|
||||||
exType,
|
|
||||||
syms.methodClass);
|
|
||||||
flags |= ABSTRACT | HYPOTHETICAL | POLYMORPHIC_SIGNATURE;
|
|
||||||
Symbol m = null;
|
|
||||||
for (Scope.Entry e = implicit.lookup(name);
|
|
||||||
e.scope != null;
|
|
||||||
e = e.next()) {
|
|
||||||
Symbol sym = e.sym;
|
|
||||||
assert sym.kind == MTH;
|
|
||||||
if (types.isSameType(mtype, sym.type)
|
|
||||||
&& (sym.flags() & STATIC) == (flags & STATIC)) {
|
|
||||||
m = sym;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (m == null) {
|
|
||||||
// create the desired method
|
|
||||||
m = new MethodSymbol(flags, name, mtype, c);
|
|
||||||
implicit.enter(m);
|
|
||||||
}
|
|
||||||
assert argumentsAcceptable(argtypes, types.memberType(site, m).getParameterTypes(),
|
|
||||||
false, false, Warner.noWarnings);
|
|
||||||
assert null != instantiate(env, site, m, argtypes, typeargtypes, false, false, Warner.noWarnings);
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
//where
|
|
||||||
Mapping implicitArgType = new Mapping ("implicitArgType") {
|
|
||||||
public Type apply(Type t) { return implicitArgType(t); }
|
|
||||||
};
|
|
||||||
Type implicitArgType(Type argType) {
|
|
||||||
argType = types.erasure(argType);
|
|
||||||
if (argType.tag == BOT)
|
|
||||||
// nulls type as the marker type Null (which has no instances)
|
|
||||||
// TO DO: figure out how to access java.lang.Null safely, else throw nice error
|
|
||||||
//argType = types.boxedClass(syms.botType).type;
|
|
||||||
argType = types.boxedClass(syms.voidType).type; // REMOVE
|
|
||||||
return argType;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Load toplevel or member class with given fully qualified name and
|
/** Load toplevel or member class with given fully qualified name and
|
||||||
* verify that it is accessible.
|
* verify that it is accessible.
|
||||||
* @param env The current environment.
|
* @param env The current environment.
|
||||||
|
@ -1369,16 +1297,77 @@ public class Resolve {
|
||||||
methodResolutionCache.put(steps.head, sym);
|
methodResolutionCache.put(steps.head, sym);
|
||||||
steps = steps.tail;
|
steps = steps.tail;
|
||||||
}
|
}
|
||||||
if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
|
if (sym.kind >= AMBIGUOUS) {
|
||||||
MethodResolutionPhase errPhase =
|
if (site.tsym.isPolymorphicSignatureGeneric() ||
|
||||||
firstErroneousResolutionPhase();
|
isTransitionalDynamicCallSite(site, sym)) {
|
||||||
sym = access(methodResolutionCache.get(errPhase),
|
//polymorphic receiver - synthesize new method symbol
|
||||||
pos, site, name, true, argtypes, typeargtypes);
|
env.info.varArgs = false;
|
||||||
env.info.varArgs = errPhase.isVarargsRequired;
|
sym = findPolymorphicSignatureInstance(env,
|
||||||
|
site, name, null, argtypes, typeargtypes);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//if nothing is found return the 'first' error
|
||||||
|
MethodResolutionPhase errPhase =
|
||||||
|
firstErroneousResolutionPhase();
|
||||||
|
sym = access(methodResolutionCache.get(errPhase),
|
||||||
|
pos, site, name, true, argtypes, typeargtypes);
|
||||||
|
env.info.varArgs = errPhase.isVarargsRequired;
|
||||||
|
}
|
||||||
|
} else if (allowMethodHandles && sym.isPolymorphicSignatureGeneric()) {
|
||||||
|
//non-instantiated polymorphic signature - synthesize new method symbol
|
||||||
|
env.info.varArgs = false;
|
||||||
|
sym = findPolymorphicSignatureInstance(env,
|
||||||
|
site, name, (MethodSymbol)sym, argtypes, typeargtypes);
|
||||||
}
|
}
|
||||||
return sym;
|
return sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Find or create an implicit method of exactly the given type (after erasure).
|
||||||
|
* Searches in a side table, not the main scope of the site.
|
||||||
|
* This emulates the lookup process required by JSR 292 in JVM.
|
||||||
|
* @param env Attribution environment
|
||||||
|
* @param site The original type from where the selection takes place.
|
||||||
|
* @param name The method's name.
|
||||||
|
* @param spMethod A template for the implicit method, or null.
|
||||||
|
* @param argtypes The required argument types.
|
||||||
|
* @param typeargtypes The required type arguments.
|
||||||
|
*/
|
||||||
|
Symbol findPolymorphicSignatureInstance(Env<AttrContext> env, Type site,
|
||||||
|
Name name,
|
||||||
|
MethodSymbol spMethod, // sig. poly. method or null if none
|
||||||
|
List<Type> argtypes,
|
||||||
|
List<Type> typeargtypes) {
|
||||||
|
if (typeargtypes.nonEmpty() && (site.tsym.isPolymorphicSignatureGeneric() ||
|
||||||
|
(spMethod != null && spMethod.isPolymorphicSignatureGeneric()))) {
|
||||||
|
log.warning(env.tree.pos(), "type.parameter.on.polymorphic.signature");
|
||||||
|
}
|
||||||
|
|
||||||
|
Type mtype = infer.instantiatePolymorphicSignatureInstance(env,
|
||||||
|
site, name, spMethod, argtypes, typeargtypes);
|
||||||
|
long flags = ABSTRACT | HYPOTHETICAL | POLYMORPHIC_SIGNATURE |
|
||||||
|
(spMethod != null ?
|
||||||
|
spMethod.flags() & Flags.AccessFlags :
|
||||||
|
Flags.PUBLIC | Flags.STATIC);
|
||||||
|
Symbol m = null;
|
||||||
|
for (Scope.Entry e = polymorphicSignatureScope.lookup(name);
|
||||||
|
e.scope != null;
|
||||||
|
e = e.next()) {
|
||||||
|
Symbol sym = e.sym;
|
||||||
|
if (types.isSameType(mtype, sym.type) &&
|
||||||
|
(sym.flags() & Flags.STATIC) == (flags & Flags.STATIC) &&
|
||||||
|
types.isSameType(sym.owner.type, site)) {
|
||||||
|
m = sym;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (m == null) {
|
||||||
|
// create the desired method
|
||||||
|
m = new MethodSymbol(flags, name, mtype, site.tsym);
|
||||||
|
polymorphicSignatureScope.enter(m);
|
||||||
|
}
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
/** Resolve a qualified method identifier, throw a fatal error if not
|
/** Resolve a qualified method identifier, throw a fatal error if not
|
||||||
* found.
|
* found.
|
||||||
* @param pos The position to use for error reporting.
|
* @param pos The position to use for error reporting.
|
||||||
|
|
|
@ -1098,12 +1098,6 @@ public class ClassReader implements Completer {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
new AttributeReader(names.PolymorphicSignature, V45_3/*S.B.V51*/, CLASS_OR_MEMBER_ATTRIBUTE) {
|
|
||||||
void read(Symbol sym, int attrLen) {
|
|
||||||
sym.flags_field |= POLYMORPHIC_SIGNATURE;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
// The following attributes for a Code attribute are not currently handled
|
// The following attributes for a Code attribute are not currently handled
|
||||||
// StackMapTable
|
// StackMapTable
|
||||||
|
@ -1289,6 +1283,9 @@ public class ClassReader implements Completer {
|
||||||
sym.flags_field |= PROPRIETARY;
|
sym.flags_field |= PROPRIETARY;
|
||||||
else
|
else
|
||||||
proxies.append(proxy);
|
proxies.append(proxy);
|
||||||
|
if (majorVersion >= V51.major && proxy.type.tsym == syms.polymorphicSignatureType.tsym) {
|
||||||
|
sym.flags_field |= POLYMORPHIC_SIGNATURE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
annotate.later(new AnnotationCompleter(sym, proxies.toList()));
|
annotate.later(new AnnotationCompleter(sym, proxies.toList()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -652,13 +652,6 @@ public class ClassWriter extends ClassFile {
|
||||||
endAttr(alenIdx);
|
endAttr(alenIdx);
|
||||||
acount++;
|
acount++;
|
||||||
}
|
}
|
||||||
if ((flags & POLYMORPHIC_SIGNATURE) != 0) {
|
|
||||||
if (target.majorVersion < 51)
|
|
||||||
throw new AssertionError("PolymorphicSignature attributes in java/dyn must be written with -target 7 (required major version is 51, current is"+target.majorVersion+")");
|
|
||||||
int alenIdx = writeAttr(names.PolymorphicSignature);
|
|
||||||
endAttr(alenIdx);
|
|
||||||
acount++;
|
|
||||||
}
|
|
||||||
return acount;
|
return acount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -259,6 +259,14 @@ public enum Target {
|
||||||
return compareTo(JDK1_7) >= 0;
|
return compareTo(JDK1_7) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Does the VM support polymorphic method handle invocation?
|
||||||
|
* Affects the linkage information output to the classfile.
|
||||||
|
* An alias for {@code hasInvokedynamic}, since all the JSR 292 features appear together.
|
||||||
|
*/
|
||||||
|
public boolean hasMethodHandles() {
|
||||||
|
return hasInvokedynamic();
|
||||||
|
}
|
||||||
|
|
||||||
/** Although we may not have support for class literals, should we
|
/** Although we may not have support for class literals, should we
|
||||||
* avoid initializing the class that the literal refers to?
|
* avoid initializing the class that the literal refers to?
|
||||||
* See 4468823
|
* See 4468823
|
||||||
|
|
|
@ -282,6 +282,13 @@ public class Main {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// phase this out with JSR 292 PFD
|
||||||
|
if ("no".equals(options.get("allowTransitionalJSR292"))) {
|
||||||
|
options.put("allowTransitionalJSR292", null);
|
||||||
|
} else if (target.hasInvokedynamic() && options.get("allowTransitionalJSR292") == null) {
|
||||||
|
options.put("allowTransitionalJSR292", "allowTransitionalJSR292");
|
||||||
|
}
|
||||||
|
|
||||||
// handle this here so it works even if no other options given
|
// handle this here so it works even if no other options given
|
||||||
String showClass = options.get("showClass");
|
String showClass = options.get("showClass");
|
||||||
if (showClass != null) {
|
if (showClass != null) {
|
||||||
|
|
|
@ -108,6 +108,10 @@ public class Scanner implements Lexer {
|
||||||
*/
|
*/
|
||||||
private boolean allowUnderscoresInLiterals;
|
private boolean allowUnderscoresInLiterals;
|
||||||
|
|
||||||
|
/** Allow exotic identifiers.
|
||||||
|
*/
|
||||||
|
private boolean allowExoticIdentifiers;
|
||||||
|
|
||||||
/** The source language setting.
|
/** The source language setting.
|
||||||
*/
|
*/
|
||||||
private Source source;
|
private Source source;
|
||||||
|
@ -181,6 +185,7 @@ public class Scanner implements Lexer {
|
||||||
allowBinaryLiterals = source.allowBinaryLiterals();
|
allowBinaryLiterals = source.allowBinaryLiterals();
|
||||||
allowHexFloats = source.allowHexFloats();
|
allowHexFloats = source.allowHexFloats();
|
||||||
allowUnderscoresInLiterals = source.allowBinaryLiterals();
|
allowUnderscoresInLiterals = source.allowBinaryLiterals();
|
||||||
|
allowExoticIdentifiers = source.allowExoticIdentifiers(); // for invokedynamic
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final boolean hexFloatsWork = hexFloatsWork();
|
private static final boolean hexFloatsWork = hexFloatsWork();
|
||||||
|
@ -1010,6 +1015,10 @@ public class Scanner implements Lexer {
|
||||||
case '#':
|
case '#':
|
||||||
scanChar();
|
scanChar();
|
||||||
if (ch == '\"') {
|
if (ch == '\"') {
|
||||||
|
if (!allowExoticIdentifiers) {
|
||||||
|
lexError("unsupported.exotic.id", source.name);
|
||||||
|
allowExoticIdentifiers = true;
|
||||||
|
}
|
||||||
scanChar();
|
scanChar();
|
||||||
if (ch == '\"')
|
if (ch == '\"')
|
||||||
lexError(pos, "empty.bytecode.ident");
|
lexError(pos, "empty.bytecode.ident");
|
||||||
|
|
|
@ -128,6 +128,11 @@ compiler.err.call.to.super.not.allowed.in.enum.ctor=\
|
||||||
compiler.err.no.superclass=\
|
compiler.err.no.superclass=\
|
||||||
{0} has no superclass
|
{0} has no superclass
|
||||||
|
|
||||||
|
compiler.warn.type.parameter.on.polymorphic.signature=\
|
||||||
|
change obsolete notation for MethodHandle invocations from x.<T>invoke(y) to (T)x.invoke(y)
|
||||||
|
compiler.warn.wrong.target.for.polymorphic.signature.definition=\
|
||||||
|
MethodHandle API building requires -target 7 runtimes or better; current is -target {0}
|
||||||
|
|
||||||
compiler.err.concrete.inheritance.conflict=\
|
compiler.err.concrete.inheritance.conflict=\
|
||||||
methods {0} from {1} and {2} from {3} are inherited with the same signature
|
methods {0} from {1} and {2} from {3} are inherited with the same signature
|
||||||
|
|
||||||
|
@ -1242,6 +1247,10 @@ compiler.err.unsupported.underscore.lit=\
|
||||||
underscores in literals are not supported in -source {0}\n\
|
underscores in literals are not supported in -source {0}\n\
|
||||||
(use -source 7 or higher to enable underscores in literals)
|
(use -source 7 or higher to enable underscores in literals)
|
||||||
|
|
||||||
|
compiler.err.unsupported.exotic.id=\
|
||||||
|
exotic identifiers #"___" are not supported in -source {0}\n\
|
||||||
|
(use -source 7 or higher to enable exotic identifiers)
|
||||||
|
|
||||||
compiler.err.automatic.resource.management.not.supported.in.source=\
|
compiler.err.automatic.resource.management.not.supported.in.source=\
|
||||||
automatic resource management is not supported in -source {0}\n\
|
automatic resource management is not supported in -source {0}\n\
|
||||||
(use -source 7 or higher to enable automatic resource management)
|
(use -source 7 or higher to enable automatic resource management)
|
||||||
|
|
|
@ -103,7 +103,6 @@ public class Names {
|
||||||
public final Name RuntimeInvisibleTypeAnnotations;
|
public final Name RuntimeInvisibleTypeAnnotations;
|
||||||
public final Name RuntimeVisibleParameterAnnotations;
|
public final Name RuntimeVisibleParameterAnnotations;
|
||||||
public final Name RuntimeInvisibleParameterAnnotations;
|
public final Name RuntimeInvisibleParameterAnnotations;
|
||||||
public final Name PolymorphicSignature;
|
|
||||||
public final Name Value;
|
public final Name Value;
|
||||||
public final Name EnclosingMethod;
|
public final Name EnclosingMethod;
|
||||||
public final Name desiredAssertionStatus;
|
public final Name desiredAssertionStatus;
|
||||||
|
@ -116,6 +115,7 @@ public class Names {
|
||||||
public final Name value;
|
public final Name value;
|
||||||
public final Name getMessage;
|
public final Name getMessage;
|
||||||
public final Name getClass;
|
public final Name getClass;
|
||||||
|
public final Name invoke; //allowTransitionalJSR292 only
|
||||||
public final Name TYPE;
|
public final Name TYPE;
|
||||||
public final Name TYPE_USE;
|
public final Name TYPE_USE;
|
||||||
public final Name TYPE_PARAMETER;
|
public final Name TYPE_PARAMETER;
|
||||||
|
@ -215,7 +215,6 @@ public class Names {
|
||||||
RuntimeInvisibleTypeAnnotations = fromString("RuntimeInvisibleTypeAnnotations");
|
RuntimeInvisibleTypeAnnotations = fromString("RuntimeInvisibleTypeAnnotations");
|
||||||
RuntimeVisibleParameterAnnotations = fromString("RuntimeVisibleParameterAnnotations");
|
RuntimeVisibleParameterAnnotations = fromString("RuntimeVisibleParameterAnnotations");
|
||||||
RuntimeInvisibleParameterAnnotations = fromString("RuntimeInvisibleParameterAnnotations");
|
RuntimeInvisibleParameterAnnotations = fromString("RuntimeInvisibleParameterAnnotations");
|
||||||
PolymorphicSignature = fromString("PolymorphicSignature");
|
|
||||||
Value = fromString("Value");
|
Value = fromString("Value");
|
||||||
EnclosingMethod = fromString("EnclosingMethod");
|
EnclosingMethod = fromString("EnclosingMethod");
|
||||||
|
|
||||||
|
@ -230,6 +229,7 @@ public class Names {
|
||||||
value = fromString("value");
|
value = fromString("value");
|
||||||
getMessage = fromString("getMessage");
|
getMessage = fromString("getMessage");
|
||||||
getClass = fromString("getClass");
|
getClass = fromString("getClass");
|
||||||
|
invoke = fromString("invoke"); //allowTransitionalJSR292 only
|
||||||
|
|
||||||
TYPE = fromString("TYPE");
|
TYPE = fromString("TYPE");
|
||||||
TYPE_USE = fromString("TYPE_USE");
|
TYPE_USE = fromString("TYPE_USE");
|
||||||
|
|
|
@ -114,3 +114,4 @@ compiler.warn.proc.type.already.exists # JavacFiler: just menti
|
||||||
compiler.warn.unchecked.assign # DEAD, replaced by compiler.misc.unchecked.assign
|
compiler.warn.unchecked.assign # DEAD, replaced by compiler.misc.unchecked.assign
|
||||||
compiler.warn.unchecked.cast.to.type # DEAD, replaced by compiler.misc.unchecked.cast.to.type
|
compiler.warn.unchecked.cast.to.type # DEAD, replaced by compiler.misc.unchecked.cast.to.type
|
||||||
compiler.warn.unexpected.archive.file # Paths: zip file with unknown extn
|
compiler.warn.unexpected.archive.file # Paths: zip file with unknown extn
|
||||||
|
compiler.warn.wrong.target.for.polymorphic.signature.definition # Transitional 292
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010, 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.warn.type.parameter.on.polymorphic.signature
|
||||||
|
// key: compiler.err.unreported.exception.need.to.catch.or.throw
|
||||||
|
|
||||||
|
import java.dyn.InvokeDynamic;
|
||||||
|
|
||||||
|
class TypeParameterOnPolymorphicSignature {
|
||||||
|
{ InvokeDynamic.<void>call("",123); }
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010, 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.unsupported.exotic.id
|
||||||
|
// options: -source 6
|
||||||
|
|
||||||
|
class UnsupportedExoticID {
|
||||||
|
void m() {
|
||||||
|
Object #"Hello!" = null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -23,12 +23,12 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
* @bug 6754038
|
* @bug 6754038 6979327
|
||||||
* @summary Generate call sites for method handle
|
* @summary Generate call sites for method handle
|
||||||
* @author jrose
|
* @author jrose
|
||||||
*
|
*
|
||||||
* @library ..
|
* @library ..
|
||||||
* @compile -source 7 -target 7 InvokeDyn.java
|
* @compile -source 7 -target 7 -XDinvokedynamic -XDallowTransitionalJSR292=no InvokeDyn.java
|
||||||
*/
|
*/
|
||||||
//No: @run main/othervm -XX:+EnableInvokeDynamic meth.InvokeDyn
|
//No: @run main/othervm -XX:+EnableInvokeDynamic meth.InvokeDyn
|
||||||
|
|
||||||
|
@ -44,16 +44,21 @@
|
||||||
|
|
||||||
package meth;
|
package meth;
|
||||||
|
|
||||||
import java.dyn.InvokeDynamic;
|
import java.dyn.*;
|
||||||
|
|
||||||
public class InvokeDyn {
|
public class InvokeDyn {
|
||||||
|
class CS extends CallSite {
|
||||||
|
CS(Object x, Object y, Object z) { throw new RuntimeException(); }
|
||||||
|
}
|
||||||
|
//@BootstrapMethod(CS.class) //note: requires 6964498
|
||||||
void test() throws Throwable {
|
void test() throws Throwable {
|
||||||
Object x = "hello";
|
Object x = "hello";
|
||||||
InvokeDynamic.greet(x, "world", 123);
|
Object ojunk; int ijunk;
|
||||||
InvokeDynamic.greet(x, "mundus", 456);
|
ojunk = InvokeDynamic.greet(x, "world", 123);
|
||||||
InvokeDynamic.greet(x, "kosmos", 789);
|
ojunk = InvokeDynamic.greet(x, "mundus", 456);
|
||||||
InvokeDynamic.<String>cogitate(10.11121, 3.14);
|
ojunk = InvokeDynamic.greet(x, "kosmos", 789);
|
||||||
InvokeDynamic.<void>#"yow: what I mean to say is, please treat this one specially"(null);
|
ojunk = (String) InvokeDynamic.cogitate(10.11121, 3.14);
|
||||||
InvokeDynamic.<int>invoke("goodbye");
|
InvokeDynamic.#"yow: what I mean to say is, please treat this one specially"(null);
|
||||||
|
ijunk = (int) InvokeDynamic.invoke("goodbye");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
59
langtools/test/tools/javac/meth/InvokeDynTrans.java
Normal file
59
langtools/test/tools/javac/meth/InvokeDynTrans.java
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2008-2010, 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 6754038 6979327
|
||||||
|
* @summary Generate call sites for method handle
|
||||||
|
* @author jrose
|
||||||
|
*
|
||||||
|
* @library ..
|
||||||
|
* @compile/fail/ref=InvokeDynTrans.out -Werror -XDrawDiagnostics -source 7 -target 7 InvokeDynTrans.java
|
||||||
|
*/
|
||||||
|
//No: @run main/othervm -XX:+EnableInvokeDynamic meth.InvokeDyn
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Standalone testing:
|
||||||
|
* <code>
|
||||||
|
* $ cd $MY_REPO_DIR/langtools
|
||||||
|
* $ (cd make; make)
|
||||||
|
* $ ./dist/bootstrap/bin/javac -d dist test/tools/javac/meth/InvokeDyn.java
|
||||||
|
* $ javap -c -classpath dist meth.InvokeDyn
|
||||||
|
* </code>
|
||||||
|
*/
|
||||||
|
|
||||||
|
package meth;
|
||||||
|
|
||||||
|
import java.dyn.InvokeDynamic;
|
||||||
|
|
||||||
|
public class InvokeDynTrans {
|
||||||
|
void test() throws Throwable {
|
||||||
|
Object x = "hello";
|
||||||
|
InvokeDynamic.greet(x, "world", 123);
|
||||||
|
InvokeDynamic.greet(x, "mundus", 456);
|
||||||
|
InvokeDynamic.greet(x, "kosmos", 789);
|
||||||
|
InvokeDynamic.<String>cogitate(10.11121, 3.14);
|
||||||
|
InvokeDynamic.<void>#"yow: what I mean to say is, please treat this one specially"(null);
|
||||||
|
InvokeDynamic.<int>invoke("goodbye");
|
||||||
|
}
|
||||||
|
}
|
6
langtools/test/tools/javac/meth/InvokeDynTrans.out
Normal file
6
langtools/test/tools/javac/meth/InvokeDynTrans.out
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
InvokeDynTrans.java:55:39: compiler.warn.type.parameter.on.polymorphic.signature
|
||||||
|
InvokeDynTrans.java:56:91: compiler.warn.type.parameter.on.polymorphic.signature
|
||||||
|
InvokeDynTrans.java:57:34: compiler.warn.type.parameter.on.polymorphic.signature
|
||||||
|
- compiler.err.warnings.and.werror
|
||||||
|
1 error
|
||||||
|
3 warnings
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -23,11 +23,11 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
* @bug 6754038
|
* @bug 6754038 6979327
|
||||||
* @summary Generate call sites for method handle
|
* @summary Generate call sites for method handle
|
||||||
* @author jrose
|
* @author jrose
|
||||||
*
|
*
|
||||||
* @compile -source 7 -target 7 InvokeMH.java
|
* @compile -source 7 -target 7 -XDallowTransitionalJSR292=no InvokeMH.java
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -57,20 +57,17 @@ public class InvokeMH {
|
||||||
Object k = "kosmos";
|
Object k = "kosmos";
|
||||||
mh_SiO.invokeExact((String)k, 789);
|
mh_SiO.invokeExact((String)k, 789);
|
||||||
o = mh_SiO.invokeExact((String)null, 000);
|
o = mh_SiO.invokeExact((String)null, 000);
|
||||||
o = mh_SiO.<Object>invokeExact("arda", -123);
|
o = (Object) mh_SiO.invokeExact("arda", -123);
|
||||||
|
|
||||||
// sig = ()String
|
// sig = ()String
|
||||||
s = mh_vS.<String>invokeExact();
|
s = (String) mh_vS.invokeExact();
|
||||||
|
|
||||||
// sig = ()int
|
// sig = ()int
|
||||||
i = mh_vi.<int>invokeExact();
|
i = (int) mh_vi.invokeExact();
|
||||||
o = mh_vi.<int>invokeExact();
|
o = (int) mh_vi.invokeExact();
|
||||||
//s = mh_vi.<int>invokeExact(); //BAD
|
|
||||||
mh_vi.<int>invokeExact();
|
|
||||||
|
|
||||||
// sig = ()void
|
// sig = ()void
|
||||||
//o = mh_vv.<void>invokeExact(); //BAD
|
mh_vv.invokeExact();
|
||||||
mh_vv.<void>invokeExact();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void testGen(MethodHandle mh_SiO,
|
void testGen(MethodHandle mh_SiO,
|
||||||
|
@ -80,24 +77,23 @@ public class InvokeMH {
|
||||||
Object o; String s; int i; // for return type testing
|
Object o; String s; int i; // for return type testing
|
||||||
|
|
||||||
// next five must have sig = (*,*)*
|
// next five must have sig = (*,*)*
|
||||||
mh_SiO.invokeGeneric((Object)"world", (Object)123);
|
o = mh_SiO.invokeGeneric((Object)"world", (Object)123);
|
||||||
mh_SiO.<void>invokeGeneric((Object)"mundus", (Object)456);
|
mh_SiO.invokeGeneric((Object)"mundus", (Object)456);
|
||||||
Object k = "kosmos";
|
Object k = "kosmos";
|
||||||
mh_SiO.invokeGeneric(k, 789);
|
o = mh_SiO.invokeGeneric(k, 789);
|
||||||
o = mh_SiO.invokeGeneric(null, 000);
|
o = mh_SiO.invokeGeneric(null, 000);
|
||||||
o = mh_SiO.<Object>invokeGeneric("arda", -123);
|
o = mh_SiO.invokeGeneric("arda", -123);
|
||||||
|
|
||||||
// sig = ()String
|
// sig = ()String
|
||||||
o = mh_vS.invokeGeneric();
|
o = mh_vS.invokeGeneric();
|
||||||
|
|
||||||
// sig = ()int
|
// sig = ()int
|
||||||
i = mh_vi.<int>invokeGeneric();
|
i = (int) mh_vi.invokeGeneric();
|
||||||
o = mh_vi.invokeGeneric();
|
o = (int) mh_vi.invokeGeneric();
|
||||||
//s = mh_vi.<int>invokeGeneric(); //BAD
|
mh_vi.invokeGeneric();
|
||||||
mh_vi.<void>invokeGeneric();
|
|
||||||
|
|
||||||
// sig = ()void
|
// sig = ()void
|
||||||
//o = mh_vv.<void>invokeGeneric(); //BAD
|
mh_vv.invokeGeneric();
|
||||||
o = mh_vv.invokeGeneric();
|
o = mh_vv.invokeGeneric();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
102
langtools/test/tools/javac/meth/InvokeMHTrans.java
Normal file
102
langtools/test/tools/javac/meth/InvokeMHTrans.java
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
/* Copyright (c) 2008, 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 6754038 6979327
|
||||||
|
* @summary Generate call sites for method handle
|
||||||
|
* @author jrose
|
||||||
|
*
|
||||||
|
* @compile/fail/ref=InvokeMHTrans.out -Werror -XDrawDiagnostics -source 7 -target 7 InvokeMHTrans.java
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Standalone testing:
|
||||||
|
* <code>
|
||||||
|
* $ cd $MY_REPO_DIR/langtools
|
||||||
|
* $ (cd make; make)
|
||||||
|
* $ ./dist/bootstrap/bin/javac -d dist test/tools/javac/meth/InvokeMH.java
|
||||||
|
* $ javap -c -classpath dist meth.InvokeMH
|
||||||
|
* </code>
|
||||||
|
*/
|
||||||
|
|
||||||
|
package meth;
|
||||||
|
|
||||||
|
import java.dyn.MethodHandle;
|
||||||
|
|
||||||
|
public class InvokeMHTrans {
|
||||||
|
void test(MethodHandle mh_SiO,
|
||||||
|
MethodHandle mh_vS,
|
||||||
|
MethodHandle mh_vi,
|
||||||
|
MethodHandle mh_vv) throws Throwable {
|
||||||
|
Object o; String s; int i; // for return type testing
|
||||||
|
|
||||||
|
// next five must have sig = (String,int)Object
|
||||||
|
mh_SiO.invokeExact("world", 123);
|
||||||
|
mh_SiO.invokeExact("mundus", 456);
|
||||||
|
Object k = "kosmos";
|
||||||
|
mh_SiO.invokeExact((String)k, 789);
|
||||||
|
o = mh_SiO.invokeExact((String)null, 000);
|
||||||
|
o = mh_SiO.<Object>invokeExact("arda", -123);
|
||||||
|
|
||||||
|
// sig = ()String
|
||||||
|
s = mh_vS.<String>invokeExact();
|
||||||
|
|
||||||
|
// sig = ()int
|
||||||
|
i = mh_vi.<int>invokeExact();
|
||||||
|
o = mh_vi.<int>invokeExact();
|
||||||
|
//s = mh_vi.<int>invokeExact(); //BAD
|
||||||
|
mh_vi.<int>invokeExact();
|
||||||
|
|
||||||
|
// sig = ()void
|
||||||
|
//o = mh_vv.<void>invokeExact(); //BAD
|
||||||
|
mh_vv.<void>invokeExact();
|
||||||
|
}
|
||||||
|
|
||||||
|
void testGen(MethodHandle mh_SiO,
|
||||||
|
MethodHandle mh_vS,
|
||||||
|
MethodHandle mh_vi,
|
||||||
|
MethodHandle mh_vv) throws Throwable {
|
||||||
|
Object o; String s; int i; // for return type testing
|
||||||
|
|
||||||
|
// next five must have sig = (*,*)*
|
||||||
|
mh_SiO.invokeGeneric((Object)"world", (Object)123);
|
||||||
|
mh_SiO.<void>invokeGeneric((Object)"mundus", (Object)456);
|
||||||
|
Object k = "kosmos";
|
||||||
|
mh_SiO.invokeGeneric(k, 789);
|
||||||
|
o = mh_SiO.invokeGeneric(null, 000);
|
||||||
|
o = mh_SiO.<Object>invokeGeneric("arda", -123);
|
||||||
|
|
||||||
|
// sig = ()String
|
||||||
|
o = mh_vS.invokeGeneric();
|
||||||
|
|
||||||
|
// sig = ()int
|
||||||
|
i = mh_vi.<int>invokeGeneric();
|
||||||
|
o = mh_vi.invokeGeneric();
|
||||||
|
//s = mh_vi.<int>invokeGeneric(); //BAD
|
||||||
|
mh_vi.<void>invokeGeneric();
|
||||||
|
|
||||||
|
// sig = ()void
|
||||||
|
//o = mh_vv.<void>invokeGeneric(); //BAD
|
||||||
|
o = mh_vv.invokeGeneric();
|
||||||
|
}
|
||||||
|
}
|
13
langtools/test/tools/javac/meth/InvokeMHTrans.out
Normal file
13
langtools/test/tools/javac/meth/InvokeMHTrans.out
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
InvokeMHTrans.java:59:39: compiler.warn.type.parameter.on.polymorphic.signature
|
||||||
|
InvokeMHTrans.java:62:38: compiler.warn.type.parameter.on.polymorphic.signature
|
||||||
|
InvokeMHTrans.java:65:35: compiler.warn.type.parameter.on.polymorphic.signature
|
||||||
|
InvokeMHTrans.java:66:35: compiler.warn.type.parameter.on.polymorphic.signature
|
||||||
|
InvokeMHTrans.java:68:31: compiler.warn.type.parameter.on.polymorphic.signature
|
||||||
|
InvokeMHTrans.java:72:32: compiler.warn.type.parameter.on.polymorphic.signature
|
||||||
|
InvokeMHTrans.java:83:35: compiler.warn.type.parameter.on.polymorphic.signature
|
||||||
|
InvokeMHTrans.java:87:41: compiler.warn.type.parameter.on.polymorphic.signature
|
||||||
|
InvokeMHTrans.java:93:37: compiler.warn.type.parameter.on.polymorphic.signature
|
||||||
|
InvokeMHTrans.java:96:34: compiler.warn.type.parameter.on.polymorphic.signature
|
||||||
|
- compiler.err.warnings.and.werror
|
||||||
|
1 error
|
||||||
|
10 warnings
|
|
@ -1,98 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
#
|
|
||||||
# Copyright (c) 2008, 2009, 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 6754038
|
|
||||||
# @summary Verify correct rejection of strongly typed return values
|
|
||||||
# @run shell MakeNegTests.sh
|
|
||||||
|
|
||||||
default_template=InvokeMH.java
|
|
||||||
javacflags='-source 7 -target 7'
|
|
||||||
# the rest of this file is a generic "//BAD"-line tester
|
|
||||||
|
|
||||||
: ${TESTSRC=.} ${TESTCLASSES=.}
|
|
||||||
javac="${TESTJAVA+${TESTJAVA}/bin/}javac"
|
|
||||||
|
|
||||||
verbose=false quiet=false
|
|
||||||
|
|
||||||
main() {
|
|
||||||
case "${@-}" in
|
|
||||||
*.java*)
|
|
||||||
for template in "$@"; do
|
|
||||||
expand_and_test "$template"
|
|
||||||
done;;
|
|
||||||
*) expand_and_test "${TESTSRC}/$default_template";;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
expand_and_test() {
|
|
||||||
template=$1
|
|
||||||
expand "$@"
|
|
||||||
testneg "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
expand() {
|
|
||||||
template=$1
|
|
||||||
badlines=` grep -n < "$template" '//BAD' `
|
|
||||||
badcount=` echo "$badlines" | wc -l `
|
|
||||||
[ $badcount -gt 0 ] || { echo "No negative test cases in $template"; exit 1; }
|
|
||||||
$quiet || echo "Expanding $badcount negative test cases from $template:"
|
|
||||||
$quiet || echo "$badlines"
|
|
||||||
badnums=` echo "$badlines" | sed 's/:.*//' `
|
|
||||||
casestem=` getcasestem "$template" `
|
|
||||||
tclassname=` basename "$template" .java `
|
|
||||||
rm -f "$casestem"*.java
|
|
||||||
for badnum in $badnums; do
|
|
||||||
casefile="$casestem"${badnum}.java
|
|
||||||
cclassname=` basename "$casefile" .java `
|
|
||||||
sed < "$template" > "$casefile" "
|
|
||||||
s|@compile|@compile/fail|
|
|
||||||
/ @[a-z]/s|@|##|
|
|
||||||
${badnum}s:^ *[/*]*: :
|
|
||||||
s/${tclassname}/${cclassname}/g
|
|
||||||
"
|
|
||||||
$verbose && diff -u "$template" "$casefile"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
getcasestem() {
|
|
||||||
echo `basename $1` | sed 's/\.java$//;s/_BAD[0-9]*$//;s/$/_BAD/'
|
|
||||||
}
|
|
||||||
|
|
||||||
testneg() {
|
|
||||||
template=$1
|
|
||||||
for casefile in ` getcasestem "$template" `*.java; do
|
|
||||||
$quiet || echo -------- $javac $javacflags "$casefile"
|
|
||||||
$javac $javacflags "$casefile" > "$casefile".errlog 2>&1 && {
|
|
||||||
echo "*** Compilation unexpectedly succeeded: $casefile"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
$quiet || echo "Compilation failed as expected"
|
|
||||||
$quiet || head ` $verbose || echo -3 ` < "$casefile".errlog
|
|
||||||
rm "$casefile".errlog
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
main "$@"
|
|
|
@ -1,97 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
#
|
|
||||||
# Copyright (c) 2008, 2009, 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 6746458
|
|
||||||
# @summary Verify correct rejection of illegal quoted identifiers.
|
|
||||||
# @run shell MakeNegTests.sh
|
|
||||||
|
|
||||||
default_template=QuotedIdent.java
|
|
||||||
# the rest of this file is a generic "//BAD"-line tester
|
|
||||||
|
|
||||||
: ${TESTSRC=.} ${TESTCLASSES=.}
|
|
||||||
javac="${TESTJAVA+${TESTJAVA}/bin/}javac"
|
|
||||||
|
|
||||||
verbose=false quiet=false
|
|
||||||
|
|
||||||
main() {
|
|
||||||
case "${@-}" in
|
|
||||||
*.java*)
|
|
||||||
for template in "$@"; do
|
|
||||||
expand_and_test "$template"
|
|
||||||
done;;
|
|
||||||
*) expand_and_test "${TESTSRC}/$default_template";;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
expand_and_test() {
|
|
||||||
template=$1
|
|
||||||
expand "$@"
|
|
||||||
testneg "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
expand() {
|
|
||||||
template=$1
|
|
||||||
badlines=` grep -n < "$template" '//BAD' `
|
|
||||||
badcount=` echo "$badlines" | wc -l `
|
|
||||||
[ $badcount -gt 0 ] || { echo "No negative test cases in $template"; exit 1; }
|
|
||||||
$quiet || echo "Expanding $badcount negative test cases from $template:"
|
|
||||||
$quiet || echo "$badlines"
|
|
||||||
badnums=` echo "$badlines" | sed 's/:.*//' `
|
|
||||||
casestem=` getcasestem "$template" `
|
|
||||||
tclassname=` basename "$template" .java `
|
|
||||||
rm "$casestem"*.java
|
|
||||||
for badnum in $badnums; do
|
|
||||||
casefile="$casestem"${badnum}.java
|
|
||||||
cclassname=` basename "$casefile" .java `
|
|
||||||
sed < "$template" > "$casefile" "
|
|
||||||
s|@compile|@compile/fail|
|
|
||||||
/ @[a-z]/s|@|##|
|
|
||||||
${badnum}s:^ *[/*]*: :
|
|
||||||
s/${tclassname}/${cclassname}/g
|
|
||||||
"
|
|
||||||
$verbose && diff -u "$template" "$casefile"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
getcasestem() {
|
|
||||||
echo `basename $1` | sed 's/.*\///;s/\.java$//;s/_BAD[0-9]*$//;s/$/_BAD/'
|
|
||||||
}
|
|
||||||
|
|
||||||
testneg() {
|
|
||||||
template=$1
|
|
||||||
for casefile in ` getcasestem "$template" `*.java; do
|
|
||||||
$quiet || echo -------- $javac "$casefile"
|
|
||||||
$javac "$casefile" > "$casefile".errlog 2>&1 && {
|
|
||||||
echo "*** Compilation unexpectedly succeeded: $casefile"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
$quiet || echo "Compilation failed as expected"
|
|
||||||
$quiet || head ` $verbose || echo -3 ` < "$casefile".errlog
|
|
||||||
rm "$casefile".errlog
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
main "$@"
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -31,6 +31,7 @@
|
||||||
* (The filename, directory name, or volume label syntax is incorrect)
|
* (The filename, directory name, or volume label syntax is incorrect)
|
||||||
*
|
*
|
||||||
* @library ..
|
* @library ..
|
||||||
|
* @compile -source 7 -target 7 -XDinvokedynamic QuotedIdent.java
|
||||||
* @run main quid.QuotedIdent
|
* @run main quid.QuotedIdent
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -119,7 +120,7 @@ public class QuotedIdent {
|
||||||
s = #"int".class.getName();
|
s = #"int".class.getName();
|
||||||
check(31, s, QuotedIdent.class.getName()+"$int");
|
check(31, s, QuotedIdent.class.getName()+"$int");
|
||||||
|
|
||||||
Class x86 = Class.forName(QuotedIdent.class.getName()+"$*86");
|
Class<?> x86 = Class.forName(QuotedIdent.class.getName()+"$*86");
|
||||||
if (x86 != #"*86".class)
|
if (x86 != #"*86".class)
|
||||||
check(32, "reflected "+x86, "static "+#"*86".class);
|
check(32, "reflected "+x86, "static "+#"*86".class);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -31,6 +31,7 @@
|
||||||
* (The filename, directory name, or volume label syntax is incorrect)
|
* (The filename, directory name, or volume label syntax is incorrect)
|
||||||
*
|
*
|
||||||
* @library ..
|
* @library ..
|
||||||
|
* @compile -source 7 -target 7 -XDinvokedynamic QuotedIdent.java
|
||||||
* @run main quid.QuotedIdent2
|
* @run main quid.QuotedIdent2
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
|
@ -72,7 +73,7 @@ public class QuotedIdent2 {
|
||||||
s = QuotedIdent.#"int".class.getName();
|
s = QuotedIdent.#"int".class.getName();
|
||||||
check(31, s, QuotedIdent.class.getName()+"$int");
|
check(31, s, QuotedIdent.class.getName()+"$int");
|
||||||
|
|
||||||
Class x86 = Class.forName(QuotedIdent.class.getName()+"$*86");
|
Class<?> x86 = Class.forName(QuotedIdent.class.getName()+"$*86");
|
||||||
if (x86 != #"*86".class)
|
if (x86 != #"*86".class)
|
||||||
check(32, "reflected "+x86, "static "+#"*86".class);
|
check(32, "reflected "+x86, "static "+#"*86".class);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue