mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 03:58:21 +00:00
Cleanup: using fragments as suggested.
This commit is contained in:
parent
8f1ea6b9cd
commit
3a3fd48628
@ -50,10 +50,15 @@ import static com.sun.tools.javac.code.Flags.BLOCK;
|
|||||||
import static com.sun.tools.javac.code.Kinds.Kind.*;
|
import static com.sun.tools.javac.code.Kinds.Kind.*;
|
||||||
import static com.sun.tools.javac.code.TypeTag.BOOLEAN;
|
import static com.sun.tools.javac.code.TypeTag.BOOLEAN;
|
||||||
import static com.sun.tools.javac.code.TypeTag.VOID;
|
import static com.sun.tools.javac.code.TypeTag.VOID;
|
||||||
|
import com.sun.tools.javac.comp.ExhaustivenessComputer.BindingPattern;
|
||||||
|
import com.sun.tools.javac.comp.ExhaustivenessComputer.EnumConstantPattern;
|
||||||
import com.sun.tools.javac.comp.ExhaustivenessComputer.ExhaustivenessResult;
|
import com.sun.tools.javac.comp.ExhaustivenessComputer.ExhaustivenessResult;
|
||||||
|
import com.sun.tools.javac.comp.ExhaustivenessComputer.PatternDescription;
|
||||||
|
import com.sun.tools.javac.comp.ExhaustivenessComputer.RecordPattern;
|
||||||
import com.sun.tools.javac.resources.CompilerProperties.Fragments;
|
import com.sun.tools.javac.resources.CompilerProperties.Fragments;
|
||||||
import static com.sun.tools.javac.tree.JCTree.Tag.*;
|
import static com.sun.tools.javac.tree.JCTree.Tag.*;
|
||||||
import com.sun.tools.javac.util.JCDiagnostic.Fragment;
|
import com.sun.tools.javac.util.JCDiagnostic.Fragment;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
/** This pass implements dataflow analysis for Java programs though
|
/** This pass implements dataflow analysis for Java programs though
|
||||||
* different AST visitor steps. Liveness analysis (see AliveAnalyzer) checks that
|
* different AST visitor steps. Liveness analysis (see AliveAnalyzer) checks that
|
||||||
@ -768,14 +773,31 @@ public class Flow {
|
|||||||
List<JCDiagnostic> details =
|
List<JCDiagnostic> details =
|
||||||
exhaustivenessResult.notExhaustiveDetails()
|
exhaustivenessResult.notExhaustiveDetails()
|
||||||
.stream()
|
.stream()
|
||||||
.sorted((pd1, pd2) -> pd1.toString().compareTo(pd2.toString()))
|
.map(this::patternToDiagnostic)
|
||||||
.map(detail -> diags.fragment(Fragments.NotExhaustiveDetail(detail)))
|
.sorted((d1, d2) -> d1.toString()
|
||||||
|
.compareTo(d2.toString()))
|
||||||
.collect(List.collector());
|
.collect(List.collector());
|
||||||
JCDiagnostic main = diags.error(null, log.currentSource(), pos, errorKey);
|
JCDiagnostic main = diags.error(null, log.currentSource(), pos, errorKey);
|
||||||
JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, details);
|
JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, details);
|
||||||
log.report(d);
|
log.report(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private JCDiagnostic patternToDiagnostic(PatternDescription desc) {
|
||||||
|
Type patternType = types.erasure(desc.type());
|
||||||
|
return diags.fragment(switch (desc) {
|
||||||
|
case BindingPattern _ ->
|
||||||
|
Fragments.BindingPattern(patternType);
|
||||||
|
case RecordPattern rp ->
|
||||||
|
Fragments.RecordPattern(patternType,
|
||||||
|
Arrays.stream(rp.nested())
|
||||||
|
.map(this::patternToDiagnostic)
|
||||||
|
.toList());
|
||||||
|
case EnumConstantPattern ep ->
|
||||||
|
Fragments.EnumConstantPattern(patternType,
|
||||||
|
ep.enumConstant());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public void visitTry(JCTry tree) {
|
public void visitTry(JCTry tree) {
|
||||||
ListBuffer<PendingExit> prevPendingExits = pendingExits;
|
ListBuffer<PendingExit> prevPendingExits = pendingExits;
|
||||||
pendingExits = new ListBuffer<>();
|
pendingExits = new ListBuffer<>();
|
||||||
|
|||||||
@ -1485,9 +1485,17 @@ compiler.err.not.exhaustive.statement.details=\
|
|||||||
the switch statement does not cover all possible input values\n\
|
the switch statement does not cover all possible input values\n\
|
||||||
missing patterns:
|
missing patterns:
|
||||||
|
|
||||||
# 0: pattern
|
# 0: type
|
||||||
compiler.misc.not.exhaustive.detail=\
|
compiler.misc.binding.pattern=\
|
||||||
{0}
|
{0} _
|
||||||
|
|
||||||
|
# 0: type, 1: list of diagnostic
|
||||||
|
compiler.misc.record.pattern=\
|
||||||
|
{0}({1})
|
||||||
|
|
||||||
|
# 0: type, 1: name
|
||||||
|
compiler.misc.enum.constant.pattern=\
|
||||||
|
{0}.{1}
|
||||||
|
|
||||||
compiler.err.initializer.must.be.able.to.complete.normally=\
|
compiler.err.initializer.must.be.able.to.complete.normally=\
|
||||||
initializer must be able to complete normally
|
initializer must be able to complete normally
|
||||||
|
|||||||
@ -234,18 +234,6 @@ public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter
|
|||||||
return messages.getLocalizedString(l, "compiler.misc.tree.tag." +
|
return messages.getLocalizedString(l, "compiler.misc.tree.tag." +
|
||||||
StringUtils.toLowerCase(tag.name()));
|
StringUtils.toLowerCase(tag.name()));
|
||||||
}
|
}
|
||||||
else if (arg instanceof BindingPattern bp) {
|
|
||||||
return formatArgument(d, bp.type(), l) + " _";
|
|
||||||
}
|
|
||||||
else if (arg instanceof RecordPattern rp) {
|
|
||||||
return formatArgument(d, rp.type(), l) +
|
|
||||||
Arrays.stream(rp.nested())
|
|
||||||
.map(pd -> formatArgument(d, pd, l))
|
|
||||||
.collect(Collectors.joining(", ", "(", ")"));
|
|
||||||
}
|
|
||||||
else if (arg instanceof EnumConstantPattern ep) {
|
|
||||||
return formatArgument(d, ep.type(), l) + "." + ep.enumConstant();
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
return String.valueOf(arg);
|
return String.valueOf(arg);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -212,7 +212,6 @@ public class RichDiagnosticFormatter extends
|
|||||||
* @param arg the argument to be translated
|
* @param arg the argument to be translated
|
||||||
*/
|
*/
|
||||||
protected void preprocessArgument(Object arg) {
|
protected void preprocessArgument(Object arg) {
|
||||||
//TODO: preprocess for patterns
|
|
||||||
if (arg instanceof Type type) {
|
if (arg instanceof Type type) {
|
||||||
preprocessType(type);
|
preprocessType(type);
|
||||||
}
|
}
|
||||||
@ -230,17 +229,6 @@ public class RichDiagnosticFormatter extends
|
|||||||
preprocessArgument(o);
|
preprocessArgument(o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (arg instanceof BindingPattern bp) {
|
|
||||||
preprocessArgument(bp.type());
|
|
||||||
}
|
|
||||||
else if (arg instanceof RecordPattern rp) {
|
|
||||||
preprocessArgument(rp.type());
|
|
||||||
Arrays.stream(rp.nested())
|
|
||||||
.forEach(this::preprocessArgument);
|
|
||||||
}
|
|
||||||
else if (arg instanceof EnumConstantPattern ep) {
|
|
||||||
preprocessArgument(ep.type());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -206,8 +206,8 @@ public class ExhaustivenessConvenientErrors extends TestRunner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
""",
|
""",
|
||||||
"lib.R(lib.A _, lib.A _)",
|
"lib.R(lib.A _,lib.A _)",
|
||||||
"lib.R(lib.B _, lib.B _)");
|
"lib.R(lib.B _,lib.B _)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -230,8 +230,8 @@ public class ExhaustivenessConvenientErrors extends TestRunner {
|
|||||||
record Root(Base b1, Base b2, Base b3) {}
|
record Root(Base b1, Base b2, Base b3) {}
|
||||||
}
|
}
|
||||||
""",
|
""",
|
||||||
"test.Test.Root(test.Test.R2 _, test.Test.Base _, test.Test.Base _)",
|
"test.Test.Root(test.Test.R2 _,test.Test.Base _,test.Test.Base _)",
|
||||||
"test.Test.Root(test.Test.R3 _, test.Test.Base _, test.Test.Base _)");
|
"test.Test.Root(test.Test.R3 _,test.Test.Base _,test.Test.Base _)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -271,7 +271,7 @@ public class ExhaustivenessConvenientErrors extends TestRunner {
|
|||||||
record Root(Base b1, Base b2, Base b3) {}
|
record Root(Base b1, Base b2, Base b3) {}
|
||||||
}
|
}
|
||||||
""",
|
""",
|
||||||
"test.Test.Root(test.Test.R2 _, test.Test.R2(test.Test.R2 _, test.Test.R2 _), test.Test.R2(test.Test.R2 _, test.Test.R2 _))");
|
"test.Test.Root(test.Test.R2 _,test.Test.R2(test.Test.R2 _,test.Test.R2 _),test.Test.R2(test.Test.R2 _,test.Test.R2 _))");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -308,7 +308,7 @@ public class ExhaustivenessConvenientErrors extends TestRunner {
|
|||||||
record NestedBaseC() implements NestedBase {}
|
record NestedBaseC() implements NestedBase {}
|
||||||
}
|
}
|
||||||
""",
|
""",
|
||||||
"test.Test.Triple(test.Test.A _, test.Test.C(test.Test.Nested _, test.Test.NestedBaseC _), test.Test.C(test.Test.Nested _, test.Test.NestedBaseC _))");
|
"test.Test.Triple(test.Test.A _,test.Test.C(test.Test.Nested _,test.Test.NestedBaseC _),test.Test.C(test.Test.Nested _,test.Test.NestedBaseC _))");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -348,10 +348,10 @@ public class ExhaustivenessConvenientErrors extends TestRunner {
|
|||||||
record Root(Base b1, Base b2, Base b3) {}
|
record Root(Base b1, Base b2, Base b3) {}
|
||||||
}
|
}
|
||||||
""",
|
""",
|
||||||
"test.Test.Root(test.Test.R2 _, test.Test.R2(test.Test.Base _, test.Test.R2 _), test.Test.R2(test.Test.R2 _, test.Test.Base _))");
|
"test.Test.Root(test.Test.R2 _,test.Test.R2(test.Test.Base _,test.Test.R2 _),test.Test.R2(test.Test.R2 _,test.Test.Base _))");
|
||||||
//ideally, the result would be as follow, but it is difficult to split Base on two distinct places:
|
//ideally,the result would be as follow,but it is difficult to split Base on two distinct places:
|
||||||
// "test.Test.Root(test.Test.R2 _, test.Test.R2(test.Test.R1 _, test.Test.R2 _), test.Test.R2(test.Test.R2 _, test.Test.R1 _))",
|
// "test.Test.Root(test.Test.R2 _,test.Test.R2(test.Test.R1 _,test.Test.R2 _),test.Test.R2(test.Test.R2 _,test.Test.R1 _))",
|
||||||
// "test.Test.Root(test.Test.R2 _, test.Test.R2(test.Test.R2 _, test.Test.R2 _), test.Test.R2(test.Test.R2 _, test.Test.R2 _))");
|
// "test.Test.Root(test.Test.R2 _,test.Test.R2(test.Test.R2 _,test.Test.R2 _),test.Test.R2(test.Test.R2 _,test.Test.R2 _))");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -388,10 +388,10 @@ public class ExhaustivenessConvenientErrors extends TestRunner {
|
|||||||
record NestedBaseC() implements NestedBase {}
|
record NestedBaseC() implements NestedBase {}
|
||||||
}
|
}
|
||||||
""",
|
""",
|
||||||
"test.Test.Triple(test.Test.A _, test.Test.C(test.Test.Nested _, test.Test.NestedBaseA _), test.Test.C _)",
|
"test.Test.Triple(test.Test.A _,test.Test.C(test.Test.Nested _,test.Test.NestedBaseA _),test.Test.C _)",
|
||||||
//the following could be:
|
//the following could be:
|
||||||
//test.Test.Triple(test.Test.A _, test.Test.C(test.Test.Nested _, test.Test.NestedBaseC _), test.Test.C(test.Test.Nested _, test.Test.NestedBaseC _))
|
//test.Test.Triple(test.Test.A _,test.Test.C(test.Test.Nested _,test.Test.NestedBaseC _),test.Test.C(test.Test.Nested _,test.Test.NestedBaseC _))
|
||||||
"test.Test.Triple(test.Test.A _, test.Test.C(test.Test.Nested _, test.Test.NestedBaseC _), test.Test.C _)");
|
"test.Test.Triple(test.Test.A _,test.Test.C(test.Test.Nested _,test.Test.NestedBaseC _),test.Test.C _)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -410,7 +410,7 @@ public class ExhaustivenessConvenientErrors extends TestRunner {
|
|||||||
}
|
}
|
||||||
public record R(R r1, R r2, R r3, Object o) {}
|
public record R(R r1, R r2, R r3, Object o) {}
|
||||||
""",
|
""",
|
||||||
"test.R(test.R _, test.R _, test.R(test.R _, test.R _, test.R _, java.lang.Object _), java.lang.Object _)");
|
"test.R(test.R _,test.R _,test.R(test.R _,test.R _,test.R _,java.lang.Object _),java.lang.Object _)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -527,7 +527,7 @@ public class ExhaustivenessConvenientErrors extends TestRunner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
""",
|
""",
|
||||||
"Test.Pair(Test.Pair(Test.Pair _, Test.Base _), Test.Pair(Test.Pair(Test.Pair _, Test.Base _), Test.Base _))");
|
"Test.Pair(Test.Pair(Test.Pair _,Test.Base _),Test.Pair(Test.Pair(Test.Pair _,Test.Base _),Test.Base _))");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doTest(Path base, String[] libraryCode, String testCode, String... expectedMissingPatterns) throws IOException {
|
private void doTest(Path base, String[] libraryCode, String testCode, String... expectedMissingPatterns) throws IOException {
|
||||||
@ -576,7 +576,7 @@ public class ExhaustivenessConvenientErrors extends TestRunner {
|
|||||||
if (d instanceof JCDiagnostic.MultilineDiagnostic diag) {
|
if (d instanceof JCDiagnostic.MultilineDiagnostic diag) {
|
||||||
diag.getSubdiagnostics()
|
diag.getSubdiagnostics()
|
||||||
.stream()
|
.stream()
|
||||||
.map(fragment -> fragment.getArgs()[0].toString())
|
.map(fragment -> fragment.toString())
|
||||||
.forEach(missingPatterns::add);
|
.forEach(missingPatterns::add);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user