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 {
Function<TypeSymbol, String> anonymousClass2DeclareName =
cs -> anon2Name.computeIfAbsent(cs, state.eval::computeDeclareName);
TypePrinter tp = new TypePrinter(at.messages(),
TypePrinter tp = new TypePrinter(at.messages(), at.types(),
fullClassNameAndPackageToClass, anonymousClass2DeclareName,
printIntersectionTypes, anonymousTypesKind);
List<Type> captures = types.captures(type);

View File

@ -227,7 +227,7 @@ class TreeDissector {
public static String printType(AnalyzeTask at, JShell state, TypeMirror type) {
Type typeImpl = (Type) type;
try {
TypePrinter tp = new TypePrinter(at.messages(),
TypePrinter tp = new TypePrinter(at.messages(), at.types(),
state.maps::fullClassNameAndPackageToClass, true, AnonymousTypeKind.DISPLAY);
return tp.toString(typeImpl);
} 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.ClassType;
import com.sun.tools.javac.code.Type.IntersectionClassType;
import com.sun.tools.javac.code.Types;
import com.sun.tools.javac.util.JavacMessages;
import java.util.Locale;
import java.util.function.BinaryOperator;
@ -49,6 +50,7 @@ class TypePrinter extends Printer {
private static final String OBJECT = "Object";
private final JavacMessages messages;
private final Types types;
private final BinaryOperator<String> fullClassNameAndPackageToClass;
private final Function<TypeSymbol, String> anonymousToName;
private final boolean printIntersectionTypes;
@ -62,10 +64,10 @@ class TypePrinter extends Printer {
* @param printIntersectionTypes whether intersection types should be printed
* @param anonymousTypesKind how the anonymous types should be printed
*/
TypePrinter(JavacMessages messages,
TypePrinter(JavacMessages messages, Types types,
BinaryOperator<String> fullClassNameAndPackageToClass,
boolean printIntersectionTypes, AnonymousTypeKind anonymousTypesKind) {
this(messages, fullClassNameAndPackageToClass, cs -> cs.flatName().toString(),
this(messages, types, fullClassNameAndPackageToClass, cs -> cs.flatName().toString(),
printIntersectionTypes, anonymousTypesKind);
}
@ -79,11 +81,12 @@ class TypePrinter extends Printer {
* @param printIntersectionTypes whether intersection types should be printed
* @param anonymousTypesKind how the anonymous types should be printed
*/
TypePrinter(JavacMessages messages,
TypePrinter(JavacMessages messages, Types types,
BinaryOperator<String> fullClassNameAndPackageToClass,
Function<TypeSymbol, String> anonymousToName,
boolean printIntersectionTypes, AnonymousTypeKind anonymousTypesKind) {
this.messages = messages;
this.types = types;
this.fullClassNameAndPackageToClass = fullClassNameAndPackageToClass;
this.anonymousToName = anonymousToName;
this.printIntersectionTypes = printIntersectionTypes;
@ -137,7 +140,7 @@ class TypePrinter extends Printer {
.map(i -> visit(i, locale))
.collect(Collectors.joining("&"));
} else {
return OBJECT;
return visit(types.erasure(t), locale);
}
} else if (sym.name.length() == 0) {
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; }");
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",
"Object");
"Number");
}
public void testVariableTypeName() {
@ -249,7 +249,7 @@ public class TypeNameTest extends KullaTesting {
assertType("test1.get()", "CharSequence");
assertEval("class Test2<X extends Number & CharSequence> { public X get() { return null; } }");
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("Test3<? extends String> test3 = new Test3<>();");
assertType("test3.get()", "String[][]");

View File

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