537d20afbf
Reviewed-by: abimpoudis
160 lines
7.2 KiB
Java
160 lines
7.2 KiB
Java
/*
|
|
* Copyright (c) 2021, 2024, 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
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
* accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU General Public License version
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
* questions.
|
|
*/
|
|
|
|
/**
|
|
* @test
|
|
* @modules jdk.compiler/com.sun.tools.javac.file
|
|
* jdk.compiler/com.sun.tools.javac.main
|
|
* jdk.compiler/com.sun.tools.javac.parser
|
|
* jdk.compiler/com.sun.tools.javac.tree
|
|
* jdk.compiler/com.sun.tools.javac.util
|
|
*/
|
|
|
|
import com.sun.source.tree.CaseLabelTree;
|
|
import com.sun.source.tree.ClassTree;
|
|
import com.sun.source.tree.CompilationUnitTree;
|
|
import com.sun.source.tree.ConstantCaseLabelTree;
|
|
import com.sun.source.tree.MethodTree;
|
|
import com.sun.source.tree.PatternCaseLabelTree;
|
|
import com.sun.source.tree.SwitchTree;
|
|
import com.sun.tools.javac.file.JavacFileManager;
|
|
import com.sun.tools.javac.parser.JavacParser;
|
|
import com.sun.tools.javac.parser.ParserFactory;
|
|
import com.sun.tools.javac.util.Context;
|
|
import com.sun.tools.javac.main.Option;
|
|
import com.sun.tools.javac.util.Options;
|
|
import java.nio.charset.Charset;
|
|
|
|
public class DisambiguatePatterns {
|
|
|
|
public static void main(String... args) throws Throwable {
|
|
DisambiguatePatterns test = new DisambiguatePatterns();
|
|
test.disambiguationTest("String s",
|
|
ExpressionType.PATTERN);
|
|
test.disambiguationTest("String s when s.isEmpty()",
|
|
ExpressionType.PATTERN);
|
|
test.disambiguationTest("String s",
|
|
ExpressionType.PATTERN);
|
|
test.disambiguationTest("@Ann String s",
|
|
ExpressionType.PATTERN);
|
|
test.disambiguationTest("String s",
|
|
ExpressionType.PATTERN);
|
|
test.disambiguationTest("(String) s",
|
|
ExpressionType.EXPRESSION);
|
|
test.disambiguationTest("((String) s)",
|
|
ExpressionType.EXPRESSION);
|
|
test.disambiguationTest("((0x1))",
|
|
ExpressionType.EXPRESSION);
|
|
test.disambiguationTest("(a > b)",
|
|
ExpressionType.EXPRESSION);
|
|
test.disambiguationTest("(a >> b)",
|
|
ExpressionType.EXPRESSION);
|
|
test.disambiguationTest("(a >>> b)",
|
|
ExpressionType.EXPRESSION);
|
|
test.disambiguationTest("(a < b | a > b)",
|
|
ExpressionType.EXPRESSION);
|
|
test.disambiguationTest("(a << b | a >> b)",
|
|
ExpressionType.EXPRESSION);
|
|
test.disambiguationTest("(a << b || a < b | a >>> b)",
|
|
ExpressionType.EXPRESSION);
|
|
test.disambiguationTest("a < c.d > b",
|
|
ExpressionType.PATTERN);
|
|
test.disambiguationTest("a<? extends c.d> b",
|
|
ExpressionType.PATTERN);
|
|
test.disambiguationTest("@Ann a<? extends c.d> b",
|
|
ExpressionType.PATTERN);
|
|
test.disambiguationTest("a<? extends @Ann c.d> b",
|
|
ExpressionType.PATTERN);
|
|
test.disambiguationTest("a<? super c.d> b",
|
|
ExpressionType.PATTERN);
|
|
test.disambiguationTest("a<? super @Ann c.d> b",
|
|
ExpressionType.PATTERN);
|
|
test.disambiguationTest("a<b<c.d>> b",
|
|
ExpressionType.PATTERN);
|
|
test.disambiguationTest("a<b<@Ann c.d>> b",
|
|
ExpressionType.PATTERN);
|
|
test.disambiguationTest("a<b<c<d>>> b",
|
|
ExpressionType.PATTERN);
|
|
test.disambiguationTest("a[] b",
|
|
ExpressionType.PATTERN);
|
|
test.disambiguationTest("a[][] b",
|
|
ExpressionType.PATTERN);
|
|
test.disambiguationTest("int i",
|
|
ExpressionType.PATTERN);
|
|
test.disambiguationTest("int[] i",
|
|
ExpressionType.PATTERN);
|
|
test.disambiguationTest("a[a]",
|
|
ExpressionType.EXPRESSION);
|
|
test.disambiguationTest("a[b][c]",
|
|
ExpressionType.EXPRESSION);
|
|
test.disambiguationTest("a & b",
|
|
ExpressionType.EXPRESSION);
|
|
test.disambiguationTest("R r when (x > 0)",
|
|
ExpressionType.PATTERN);
|
|
test.disambiguationTest("R(int x) when (x > 0)",
|
|
ExpressionType.PATTERN);
|
|
}
|
|
|
|
private final ParserFactory factory;
|
|
|
|
public DisambiguatePatterns() {
|
|
Context context = new Context();
|
|
JavacFileManager jfm = new JavacFileManager(context, true, Charset.defaultCharset());
|
|
Options.instance(context).put(Option.PREVIEW, "");
|
|
factory = ParserFactory.instance(context);
|
|
}
|
|
|
|
void disambiguationTest(String snippet, ExpressionType expectedType) {
|
|
String code = """
|
|
public class Test {
|
|
private void test() {
|
|
switch (null) {
|
|
case SNIPPET -> {}
|
|
}
|
|
}
|
|
}
|
|
""".replace("SNIPPET", snippet);
|
|
JavacParser parser = factory.newParser(code, false, false, false);
|
|
CompilationUnitTree result = parser.parseCompilationUnit();
|
|
ClassTree clazz = (ClassTree) result.getTypeDecls().get(0);
|
|
MethodTree method = (MethodTree) clazz.getMembers().get(0);
|
|
SwitchTree st = (SwitchTree) method.getBody().getStatements().get(0);
|
|
CaseLabelTree label = st.getCases().get(0).getLabels().get(0);
|
|
ExpressionType actualType = switch (label) {
|
|
case ConstantCaseLabelTree et -> ExpressionType.EXPRESSION;
|
|
case PatternCaseLabelTree pt -> ExpressionType.PATTERN;
|
|
default -> throw new AssertionError("Unexpected result: " + result);
|
|
};
|
|
if (expectedType != actualType) {
|
|
throw new AssertionError("Expected: " + expectedType + ", actual: " + actualType +
|
|
", for: " + code + ", parsed: " + result);
|
|
}
|
|
}
|
|
|
|
enum ExpressionType {
|
|
PATTERN,
|
|
EXPRESSION;
|
|
}
|
|
|
|
}
|