Skip to content
This repository was archived by the owner on Apr 24, 2023. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -590,14 +590,10 @@ private void handleSwitch(JCTree tree,
}
}
c.labels = translatedLabels.toList();
if (c.caseKind == CaseTree.CaseKind.STATEMENT) {
previousCompletesNormally = c.completesNormally;
} else {
previousCompletesNormally = false;
JCBreak brk = make.at(TreeInfo.endPos(c.stats.last())).Break(null);
brk.target = tree;
c.stats = c.stats.append(brk);
}
previousCompletesNormally =
c.caseKind == CaseTree.CaseKind.STATEMENT &&
c.completesNormally;
appendBreakIfNeeded(tree, c);
}

if (tree.hasTag(Tag.SWITCH)) {
Expand Down Expand Up @@ -642,6 +638,14 @@ public void visitCase(JCCase c) {
}.scan(c.stats);
}

private void appendBreakIfNeeded(JCTree switchTree, JCCase c) {
if (c.caseKind == CaseTree.CaseKind.RULE) {
JCBreak brk = make.at(TreeInfo.endPos(c.stats.last())).Break(null);
brk.target = switchTree;
c.stats = c.stats.append(brk);
}
}

JCMethodInvocation makeApply(JCExpression selector, Name name, List<JCExpression> args) {
MethodSymbol method = rs.resolveInternalMethod(
currentClassTree.pos(), env,
Expand Down Expand Up @@ -740,6 +744,7 @@ public void resolve(VarSymbol commonBinding,
} else {
newLabel = List.of(make.PatternCaseLabel(binding, newGuard));
}
appendBreakIfNeeded(currentSwitch, accummulated);
nestedCases.add(make.Case(CaseKind.STATEMENT, newLabel, accummulated.stats, null));
}
if (!hasUnconditional) {
Expand Down
112 changes: 109 additions & 3 deletions test/langtools/tools/javac/patterns/PatternDesugaring.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 2023, 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
Expand All @@ -23,8 +23,9 @@

/**
* @test
* @bug 8291769
* @bug 8291769 8300195
* @summary Verify the compiled code does not have unwanted constructs.
* @enablePreview
* @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
Expand All @@ -34,11 +35,17 @@
* @run main PatternDesugaring
*/

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;

import toolbox.TestRunner;
Expand Down Expand Up @@ -198,4 +205,103 @@ private void doTest(Path base, String[] libraryCode, String testCode, Consumer<S
validate.accept(decompiled);
}

@Test
public void testRuleCases(Path base) throws Exception {
doTestRun(base,
new String[0],
"""
package test;
public class Test {
public static void main(String... args) {
System.out.println(test(new R("a")));
System.out.println(test(new R(3)));
System.out.println(test(new R(new R("a"))));
System.out.println(test(new R(new R(3))));
}
public static int test(Object obj) {
int res;
switch (obj) {
case R(String s) -> res = s.length();
case R(Integer i) -> res = i;
case R(R(String s)) -> res = 10 + s.length();
case R(R(Integer i)) -> res = 10 + i;
default -> res = -1;
}
return res;
}
record R(Object o) {}
}
""",
output -> {
String expectedOutput = """
1
3
11
13
""";
if (!Objects.equals(output, expectedOutput)) {
throw new AssertionError("Unexpected output," +
" expected: " + expectedOutput +
" actual: " + output);
}
});
}

private void doTestRun(Path base, String[] libraryCode, String testCode, Consumer<String> validate) throws Exception {
Path current = base.resolve(".");
Path libClasses = current.resolve("libClasses");

Files.createDirectories(libClasses);

if (libraryCode.length != 0) {
Path libSrc = current.resolve("lib-src");

for (String code : libraryCode) {
tb.writeJavaFiles(libSrc, code);
}

new JavacTask(tb)
.options("--enable-preview",
"-source", JAVA_VERSION)
.outdir(libClasses)
.files(tb.findJavaFiles(libSrc))
.run();
}

Path src = current.resolve("src");
tb.writeJavaFiles(src, testCode);

Path classes = current.resolve("libClasses");

Files.createDirectories(libClasses);

var log =
new JavacTask(tb)
.options("--enable-preview",
"-source", JAVA_VERSION,
"-XDrawDiagnostics",
"-Xlint:-preview",
"--class-path", libClasses.toString(),
"-XDshould-stop.at=FLOW")
.outdir(classes)
.files(tb.findJavaFiles(src))
.run(Task.Expect.SUCCESS)
.writeAll();

ClassLoader cl = new URLClassLoader(new URL[] {classes.toUri().toURL()});
Class<?> testClass = cl.loadClass("test.Test");
Method main = testClass.getMethod("main", String[].class);
PrintStream prevOut = System.out;
var data = new ByteArrayOutputStream();
try (var outStream = new PrintStream(data, true, StandardCharsets.UTF_8)) {
System.setOut(outStream);
main.invoke(null, (Object) new String[0]);
} finally {
System.setOut(prevOut);
}
String output = new String(data.toByteArray(), StandardCharsets.UTF_8);
output = output.replaceAll("\\R", "\n");
validate.accept(output);
}

}