diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java index 702b51d3b96..151c39fae40 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Type.java @@ -2338,7 +2338,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons this.originalType = (originalType == null ? noType : originalType); } - private ErrorType(Type originalType, TypeSymbol tsym, + public ErrorType(Type originalType, TypeSymbol tsym, List metadata) { super(noType, List.nil(), null, metadata); this.tsym = tsym; @@ -2393,10 +2393,6 @@ public abstract class Type extends AnnoConstruct implements TypeMirror, PoolCons public boolean isCompound() { return false; } public boolean isInterface() { return false; } - public List allparams() { return List.nil(); } - @DefinedBy(Api.LANGUAGE_MODEL) - public List getTypeArguments() { return List.nil(); } - @DefinedBy(Api.LANGUAGE_MODEL) public TypeKind getKind() { return TypeKind.ERROR; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java index 54edc19560b..44ccbade4a9 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java @@ -5081,6 +5081,14 @@ public class Attr extends JCTree.Visitor { } owntype = types.createErrorType(tree.type); } + } else if (clazztype.hasTag(ERROR)) { + ErrorType parameterizedErroneous = + new ErrorType(clazztype.getOriginalType(), + clazztype.tsym, + clazztype.getMetadata()); + + parameterizedErroneous.typarams_field = actuals; + owntype = parameterizedErroneous; } result = check(tree, owntype, KindSelector.TYP, resultInfo); } diff --git a/test/langtools/tools/javac/recovery/AttrRecovery.java b/test/langtools/tools/javac/recovery/AttrRecovery.java index 629cef45c62..19325420af7 100644 --- a/test/langtools/tools/javac/recovery/AttrRecovery.java +++ b/test/langtools/tools/javac/recovery/AttrRecovery.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8301580 8322159 8333107 8332230 + * @bug 8301580 8322159 8333107 8332230 8338678 * @summary Verify error recovery w.r.t. Attr * @library /tools/lib * @enablePreview @@ -34,9 +34,23 @@ * @run main AttrRecovery */ +import com.sun.source.tree.VariableTree; +import com.sun.source.util.TaskEvent; +import com.sun.source.util.TaskListener; +import com.sun.source.util.TreePathScanner; +import com.sun.source.util.Trees; import java.nio.file.Path; +import java.util.IdentityHashMap; import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.stream.Collectors; +import javax.lang.model.element.Element; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.TypeKind; +import javax.lang.model.type.TypeMirror; +import javax.tools.Diagnostic; import toolbox.JavacTask; import toolbox.Task.Expect; @@ -234,4 +248,80 @@ public class AttrRecovery extends TestRunner { } } + @Test + public void testParameterizedErroneousType() throws Exception { + String code = """ + public class C { + Undefined1 variable1; + } + """; + Path curPath = Path.of("."); + List actual = new JavacTask(tb) + .options("-XDrawDiagnostics") + .sources(code) + .outdir(curPath) + .callback(task -> { + task.addTaskListener(new TaskListener() { + @Override + public void finished(TaskEvent e) { + Trees trees = Trees.instance(task); + + if (e.getKind() == TaskEvent.Kind.ANALYZE) { + new TreePathScanner() { + @Override + public Void visitVariable(VariableTree tree, Void p) { + VariableElement var = (VariableElement) trees.getElement(getCurrentPath()); + + trees.printMessage(Diagnostic.Kind.NOTE, type2String(var.asType()), tree, e.getCompilationUnit()); + + return super.visitVariable(tree, p); + } + }.scan(e.getCompilationUnit(), null); + } + } + Map identityRename = new IdentityHashMap<>(); + String type2String(TypeMirror type) { + StringBuilder result = new StringBuilder(); + + result.append(type.getKind()); + result.append(":"); + result.append(type.toString()); + + if (type.getKind() == TypeKind.DECLARED || + type.getKind() == TypeKind.ERROR) { + DeclaredType dt = (DeclaredType) type; + Element el = task.getTypes().asElement(dt); + result.append(":"); + result.append(el.toString()); + if (!dt.getTypeArguments().isEmpty()) { + result.append(dt.getTypeArguments() + .stream() + .map(tm -> type2String(tm)) + .collect(Collectors.joining(", ", "<", ">"))); + } + } else { + throw new AssertionError(type.getKind().name()); + } + + return result.toString(); + } + }); + }) + .run(Expect.FAIL) + .writeAll() + .getOutputLines(OutputKind.DIRECT); + + List expected = List.of( + "C.java:2:5: compiler.err.cant.resolve.location: kindname.class, Undefined1, , , (compiler.misc.location: kindname.class, C, null)", + "C.java:2:16: compiler.err.cant.resolve.location: kindname.class, Undefined2, , , (compiler.misc.location: kindname.class, C, null)", + "C.java:2:28: compiler.err.cant.resolve.location: kindname.class, Undefined3, , , (compiler.misc.location: kindname.class, C, null)", + "C.java:2:40: compiler.note.proc.messager: ERROR:Undefined1:Undefined1", + "3 errors" + ); + + if (!Objects.equals(actual, expected)) { + error("Expected: " + expected + ", but got: " + actual); + } + } + }