From f5596af95ac511c78044c4aa79c720a5ab000afa Mon Sep 17 00:00:00 2001 From: Stephan Herrmann Date: Wed, 28 Aug 2024 22:54:12 +0200 Subject: [PATCH] [23] JEP 455: Primitive Types in Patterns, instanceof, and switch (Preview) + fix previous commit for remaining types long,float,double + precise distinction of non-int constants + add PrimitiveInPatternsTestSH to the suite (pending consolidation with PrimitiveInPatternsTest) + enable run.javac against release candidate "23" --- .../jdt/internal/compiler/ClassFile.java | 21 ++++----- .../compiler/ast/SwitchStatement.java | 10 +++-- .../regression/AbstractRegressionTest.java | 5 ++- .../regression/PrimitiveInPatternsTestSH.java | 43 ++++++++++++++++--- .../tests/compiler/regression/TestAll.java | 1 + 5 files changed, 59 insertions(+), 21 deletions(-) diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ClassFile.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ClassFile.java index ce504e56555..6a288b0ecc1 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ClassFile.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ClassFile.java @@ -4069,19 +4069,20 @@ private int addBootStrapTypeSwitchEntry(int localContentsOffset, SwitchStatement this.contents[localContentsOffset++] = (byte) intValIdx; } else { if (c.e instanceof NullLiteral) continue; - int valIdx; - switch (c.t.id) { - case TypeIds.T_byte, TypeIds.T_char, TypeIds.T_short, TypeIds.T_int, TypeIds.T_long -> - valIdx = this.constantPool.literalIndex(c.intValue()); - case TypeIds.T_boolean -> { - // Dynamic for Boolean.getStaticFinal(TRUE|FALSE) - valIdx = this.constantPool.literalIndexForDynamic(c.primitivesBootstrapIdx, + int valIdx = switch (c.t.id) { + case TypeIds.T_boolean -> // Dynamic for Boolean.getStaticFinal(TRUE|FALSE) : + this.constantPool.literalIndexForDynamic(c.primitivesBootstrapIdx, c.c.booleanValue() ? BooleanConstant.TRUE_STRING : BooleanConstant.FALSE_STRING, ConstantPool.JavaLangBooleanSignature); - } + case TypeIds.T_byte, TypeIds.T_char, TypeIds.T_short, TypeIds.T_int, TypeIds.T_long -> + this.constantPool.literalIndex(c.intValue()); + case TypeIds.T_float -> + this.constantPool.literalIndex(c.c.floatValue()); + case TypeIds.T_double -> + this.constantPool.literalIndex(c.c.doubleValue()); default -> - throw new RuntimeException("missing case impl"); // FIXME: handle long, float, double - } + throw new IllegalArgumentException("Switch has unexpected type: "+switchStatement); //$NON-NLS-1$ + }; this.contents[localContentsOffset++] = (byte) (valIdx >> 8); this.contents[localContentsOffset++] = (byte) valIdx; } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java index 04c4fca1759..c5967cd1a28 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java @@ -1012,11 +1012,13 @@ private void generateCodeSwitchPatternPrologue(BlockScope currentScope, CodeStre } } private void generateTypeSwitchPatternPrologue(CodeStream codeStream, int invokeDynamicNumber) { + TypeBinding exprType = this.expression.resolvedType; char[] signature = (this.switchBits & Primitive) != 0 - ? "(XI)I".replace("X", String.valueOf(this.expression.resolvedType.signature())).toCharArray() //$NON-NLS-1$ //$NON-NLS-2$ + ? "(XI)I".replace("X", String.valueOf(exprType.signature())).toCharArray() //$NON-NLS-1$ //$NON-NLS-2$ : "(Ljava/lang/Object;I)I".toCharArray(); //$NON-NLS-1$ + int argsSize = TypeIds.getCategory(exprType.id) + 1; // Object | PRIM, restartIndex (PRIM = Z|S|I..) codeStream.invokeDynamic(invokeDynamicNumber, - 2, // Object / PRIM, restartIndex (PRIM = Z|S|I..) + argsSize, 1, // int ConstantPool.TYPESWITCH, signature, @@ -1199,7 +1201,7 @@ public void resolve(BlockScope upperScope) { } else { if (c2.typeID() == TypeIds.T_JavaLangString) return false; - if (con.intValue() == c2.intValue()) + if (con.equals(c2)) return true; return this.constants[idx] == c1; } @@ -1229,7 +1231,7 @@ public void resolve(BlockScope upperScope) { } else { if (!c.isPattern() && check.test(j)) { if (this.isNonTraditional) { - if (c.e instanceof NullLiteral && this.otherConstants[j].e instanceof NullLiteral) { + if (c.e instanceof NullLiteral && this.otherConstants[j].e instanceof NullLiteral) { reportDuplicateCase(c.e, this.otherConstants[j].e, length); } } else { diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java index 7f49369137d..614019875fd 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/AbstractRegressionTest.java @@ -585,8 +585,9 @@ static int minorFromRawVersion (String version, String rawVersion) { } } if (version == JavaCore.VERSION_23) { - if ("23-ea".equals(rawVersion)) { - return 0000; + switch(rawVersion) { + case "23-ea", "23": + return 0000; } } throw new RuntimeException("unknown raw javac version: " + rawVersion); diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PrimitiveInPatternsTestSH.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PrimitiveInPatternsTestSH.java index 2bad0eca56f..c73104038a3 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PrimitiveInPatternsTestSH.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/PrimitiveInPatternsTestSH.java @@ -1094,9 +1094,6 @@ public static PRIM switchPRIM(PRIM in) { case PRIM v -> v; }; } - static PRIM barPRIM() { - return VAL; - } """; String callTmpl = """ @@ -1108,7 +1105,7 @@ static PRIM barPRIM() { System.out.print('|'); """; // for all primitive types: - for (int i = 0; i < PRIMITIVES.length-3; i++) { // TODO skipping long, float, double for now + for (int i = 0; i < PRIMITIVES.length; i++) { methods.append(fillIn(methodTmpl, i)); calls.append(fillIn(callTmpl, i)); } @@ -1118,7 +1115,43 @@ static PRIM barPRIM() { classX.append(calls); classX.append("}}\n"); runConformTest(new String[] { "X.java", classX.toString() }, - "false|false|49|-1|1|-|49|-1|49|-1|"); + "false|false|49|-1|1|-|49|-1|49|-1|49|-1|49.0|-1.0|49.0|-1.0|"); + } + + public void testPrimitivePatternInSwitch_more() { + runConformTest(new String[] { + "X.java", + """ + public class X { + public static String switchbool(boolean in) { + // generic test couldn't differentiate cases by output + return switch (in) { + case true -> "true"; + case boolean v -> "v="+String.valueOf(v); + }; + } + public static String switchfloatMoreCases(float f) { + return switch (f) { + case 1.0f -> "1.0"; + case 1.5f -> "1.5"; + case float v -> "v="+String.valueOf(v); + }; + } + public static void main(String... args) { + System.out.print(switchbool(true)); + System.out.print("|"); + System.out.print(switchbool(false)); + System.out.print("|"); + System.out.print(switchfloatMoreCases(1.0f)); + System.out.print("|"); + System.out.print(switchfloatMoreCases(1.5f)); + System.out.print("|"); + System.out.print(switchfloatMoreCases(1.6f)); + System.out.print("|"); + } + } + """}, + "true|v=false|1.0|1.5|v=1.6|"); } // test from spec diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java index 44678b970ee..551bd039dc1 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/TestAll.java @@ -261,6 +261,7 @@ public static Test suite() { since_23.add(SuperAfterStatementsTest.class); since_23.add(ImplicitlyDeclaredClassesTest.class); since_23.add(PrimitiveInPatternsTest.class); + since_23.add(PrimitiveInPatternsTestSH.class); since_23.add(MarkdownCommentsTest.class); // Build final test suite