8252409: JShell: Intersection types cause NoSuchFieldError

Reviewed-by: vromero
This commit is contained in:
Jan Lahoda 2021-01-29 09:19:14 +00:00
parent 64a150c518
commit 0675473486
5 changed files with 26 additions and 11 deletions

View File

@ -518,7 +518,7 @@ class ExpressionToTypeInfo {
try { try {
Function<TypeSymbol, String> anonymousClass2DeclareName = Function<TypeSymbol, String> anonymousClass2DeclareName =
cs -> anon2Name.computeIfAbsent(cs, state.eval::computeDeclareName); cs -> anon2Name.computeIfAbsent(cs, state.eval::computeDeclareName);
TypePrinter tp = new TypePrinter(at.messages(), TypePrinter tp = new TypePrinter(at.messages(), at.types(),
fullClassNameAndPackageToClass, anonymousClass2DeclareName, fullClassNameAndPackageToClass, anonymousClass2DeclareName,
printIntersectionTypes, anonymousTypesKind); printIntersectionTypes, anonymousTypesKind);
List<Type> captures = types.captures(type); List<Type> captures = types.captures(type);

View File

@ -227,7 +227,7 @@ class TreeDissector {
public static String printType(AnalyzeTask at, JShell state, TypeMirror type) { public static String printType(AnalyzeTask at, JShell state, TypeMirror type) {
Type typeImpl = (Type) type; Type typeImpl = (Type) type;
try { try {
TypePrinter tp = new TypePrinter(at.messages(), TypePrinter tp = new TypePrinter(at.messages(), at.types(),
state.maps::fullClassNameAndPackageToClass, true, AnonymousTypeKind.DISPLAY); state.maps::fullClassNameAndPackageToClass, true, AnonymousTypeKind.DISPLAY);
return tp.toString(typeImpl); return tp.toString(typeImpl);
} catch (Exception ex) { } catch (Exception ex) {

View File

@ -34,6 +34,7 @@ import com.sun.tools.javac.code.Symbol.TypeSymbol;
import com.sun.tools.javac.code.Type; import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.code.Type.ClassType; import com.sun.tools.javac.code.Type.ClassType;
import com.sun.tools.javac.code.Type.IntersectionClassType; import com.sun.tools.javac.code.Type.IntersectionClassType;
import com.sun.tools.javac.code.Types;
import com.sun.tools.javac.util.JavacMessages; import com.sun.tools.javac.util.JavacMessages;
import java.util.Locale; import java.util.Locale;
import java.util.function.BinaryOperator; import java.util.function.BinaryOperator;
@ -49,6 +50,7 @@ class TypePrinter extends Printer {
private static final String OBJECT = "Object"; private static final String OBJECT = "Object";
private final JavacMessages messages; private final JavacMessages messages;
private final Types types;
private final BinaryOperator<String> fullClassNameAndPackageToClass; private final BinaryOperator<String> fullClassNameAndPackageToClass;
private final Function<TypeSymbol, String> anonymousToName; private final Function<TypeSymbol, String> anonymousToName;
private final boolean printIntersectionTypes; private final boolean printIntersectionTypes;
@ -62,10 +64,10 @@ class TypePrinter extends Printer {
* @param printIntersectionTypes whether intersection types should be printed * @param printIntersectionTypes whether intersection types should be printed
* @param anonymousTypesKind how the anonymous types should be printed * @param anonymousTypesKind how the anonymous types should be printed
*/ */
TypePrinter(JavacMessages messages, TypePrinter(JavacMessages messages, Types types,
BinaryOperator<String> fullClassNameAndPackageToClass, BinaryOperator<String> fullClassNameAndPackageToClass,
boolean printIntersectionTypes, AnonymousTypeKind anonymousTypesKind) { boolean printIntersectionTypes, AnonymousTypeKind anonymousTypesKind) {
this(messages, fullClassNameAndPackageToClass, cs -> cs.flatName().toString(), this(messages, types, fullClassNameAndPackageToClass, cs -> cs.flatName().toString(),
printIntersectionTypes, anonymousTypesKind); printIntersectionTypes, anonymousTypesKind);
} }
@ -79,11 +81,12 @@ class TypePrinter extends Printer {
* @param printIntersectionTypes whether intersection types should be printed * @param printIntersectionTypes whether intersection types should be printed
* @param anonymousTypesKind how the anonymous types should be printed * @param anonymousTypesKind how the anonymous types should be printed
*/ */
TypePrinter(JavacMessages messages, TypePrinter(JavacMessages messages, Types types,
BinaryOperator<String> fullClassNameAndPackageToClass, BinaryOperator<String> fullClassNameAndPackageToClass,
Function<TypeSymbol, String> anonymousToName, Function<TypeSymbol, String> anonymousToName,
boolean printIntersectionTypes, AnonymousTypeKind anonymousTypesKind) { boolean printIntersectionTypes, AnonymousTypeKind anonymousTypesKind) {
this.messages = messages; this.messages = messages;
this.types = types;
this.fullClassNameAndPackageToClass = fullClassNameAndPackageToClass; this.fullClassNameAndPackageToClass = fullClassNameAndPackageToClass;
this.anonymousToName = anonymousToName; this.anonymousToName = anonymousToName;
this.printIntersectionTypes = printIntersectionTypes; this.printIntersectionTypes = printIntersectionTypes;
@ -137,7 +140,7 @@ class TypePrinter extends Printer {
.map(i -> visit(i, locale)) .map(i -> visit(i, locale))
.collect(Collectors.joining("&")); .collect(Collectors.joining("&"));
} else { } else {
return OBJECT; return visit(types.erasure(t), locale);
} }
} else if (sym.name.length() == 0) { } else if (sym.name.length() == 0) {
if (anonymousTypesKind == AnonymousTypeKind.DECLARE) { if (anonymousTypesKind == AnonymousTypeKind.DECLARE) {

View File

@ -194,7 +194,7 @@ public class TypeNameTest extends KullaTesting {
assertEval("<Z> Z choose(Z z1, Z z2) { return z1; }"); assertEval("<Z> Z choose(Z z1, Z z2) { return z1; }");
assertType("choose(1, 1L);", assertType("choose(1, 1L);",
"Number&Comparable<? extends Number&Comparable<?>&java.lang.constant.Constable&java.lang.constant.ConstantDesc>&java.lang.constant.Constable&java.lang.constant.ConstantDesc", "Number&Comparable<? extends Number&Comparable<?>&java.lang.constant.Constable&java.lang.constant.ConstantDesc>&java.lang.constant.Constable&java.lang.constant.ConstantDesc",
"Object"); "Number");
} }
public void testVariableTypeName() { public void testVariableTypeName() {
@ -249,7 +249,7 @@ public class TypeNameTest extends KullaTesting {
assertType("test1.get()", "CharSequence"); assertType("test1.get()", "CharSequence");
assertEval("class Test2<X extends Number & CharSequence> { public X get() { return null; } }"); assertEval("class Test2<X extends Number & CharSequence> { public X get() { return null; } }");
assertEval("Test2<?> test2 = new Test2<>();"); assertEval("Test2<?> test2 = new Test2<>();");
assertType("test2.get()", "Number&CharSequence", "Object"); assertType("test2.get()", "Number&CharSequence", "Number");
assertEval("class Test3<T> { T[][] get() { return null; } }"); assertEval("class Test3<T> { T[][] get() { return null; } }");
assertEval("Test3<? extends String> test3 = new Test3<>();"); assertEval("Test3<? extends String> test3 = new Test3<>();");
assertType("test3.get()", "String[][]"); assertType("test3.get()", "String[][]");

View File

@ -23,7 +23,7 @@
/* /*
* @test * @test
* @bug 8144903 8177466 8191842 8211694 8213725 8239536 8257236 * @bug 8144903 8177466 8191842 8211694 8213725 8239536 8257236 8252409
* @summary Tests for EvaluationState.variables * @summary Tests for EvaluationState.variables
* @library /tools/lib * @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api * @modules jdk.compiler/com.sun.tools.javac.api
@ -38,6 +38,7 @@ import java.nio.file.Paths;
import java.util.List; import java.util.List;
import javax.tools.Diagnostic; import javax.tools.Diagnostic;
import jdk.jshell.MethodSnippet;
import jdk.jshell.Snippet; import jdk.jshell.Snippet;
import jdk.jshell.TypeDeclSnippet; import jdk.jshell.TypeDeclSnippet;
import jdk.jshell.VarSnippet; import jdk.jshell.VarSnippet;
@ -417,10 +418,14 @@ public class VariablesTest extends KullaTesting {
public void lvtiRecompileDependentsWithIntersectionTypes() { public void lvtiRecompileDependentsWithIntersectionTypes() {
assertEval("<Z extends Runnable & CharSequence> Z get1() { return null; }", added(VALID)); assertEval("<Z extends Runnable & CharSequence> Z get1() { return null; }", added(VALID));
VarSnippet var = varKey(assertEval("var i1 = get1();", added(VALID))); assertEval("var i1 = get1();", added(VALID));
MethodSnippet get2 = methodKey(assertEval("<Z extends Runnable & Stream> Z get2() { return null; }",
ste(MAIN_SNIPPET, NONEXISTENT, RECOVERABLE_NOT_DEFINED, false, null)));
assertEval("import java.util.stream.*;", added(VALID), assertEval("import java.util.stream.*;", added(VALID),
ste(var, VALID, VALID, true, MAIN_SNIPPET)); ste(get2, RECOVERABLE_NOT_DEFINED, VALID, true, MAIN_SNIPPET));
assertEval("void t1() { i1.run(); i1.length(); }", added(VALID)); assertEval("void t1() { i1.run(); i1.length(); }", added(VALID));
assertEval("var i2 = get2();", added(VALID));
assertEval("void t2() { i2.run(); i2.count(); }", added(VALID));
} }
public void arrayInit() { public void arrayInit() {
@ -605,4 +610,11 @@ public class VariablesTest extends KullaTesting {
.remoteVMOptions("--class-path", tpath) .remoteVMOptions("--class-path", tpath)
.compilerOptions("--class-path", tpath)); .compilerOptions("--class-path", tpath));
} }
public void varIntersection() {
assertEval("interface Marker {}");
assertEval("var v = (Marker & Runnable) () -> {};", added(VALID));
assertEval("v.run()");
}
} }