Skip to content

Commit

Permalink
Do not allow dimensions and modifiers in record patterns (#2120)
Browse files Browse the repository at this point in the history
* Fixes #2119

* Fixes #2118
  • Loading branch information
srikanth-sankaran committed Mar 8, 2024
1 parent c5fa43d commit f78dfbb
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2450,6 +2450,10 @@ public interface IProblem {
*/
int PatternVariableRedeclared = Internal + 1784;

/** @since 3.37
*/
int DimensionsIllegalOnRecordPattern = Internal + 1785;

/** @since 3.28
*/
int DiscouragedValueBasedTypeSynchronization = Internal + 1820;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10454,6 +10454,14 @@ protected void consumeRecordPattern() {
length);
}

int sourceEnd = this.intStack[this.intPtr--]; // ')' position
this.intPtr--; // pop '(' position

int dimension = this.intStack[this.intPtr--];

int modifierStart = this.intStack[this.intPtr--];
int modifier = this.intStack[this.intPtr--];

TypeReference type = getTypeReference(0);

if (typeAnnotations != null) {
Expand All @@ -10465,8 +10473,6 @@ protected void consumeRecordPattern() {
type.bits |= ASTNode.HasTypeAnnotations;
}

int sourceEnd = this.intStack[this.intPtr--];
this.intPtr--;
RecordPattern recPattern = new RecordPattern(type, type.sourceStart, sourceEnd);

length = this.astLengthPtr == -1 ? 0 : this.astLengthStack[this.astLengthPtr--];
Expand All @@ -10489,8 +10495,13 @@ protected void consumeRecordPattern() {
} else {
recPattern.patterns = ASTNode.NO_TYPE_PATTERNS;
}
if (dimension != 0) {
problemReporter().dimensionsIllegalOnRecordPattern(type.sourceStart, sourceEnd);
}
if (modifier != 0) {
problemReporter().illegalModifiers(modifierStart, type.sourceStart - 2);
}
checkForDiamond(recPattern.type);
this.intPtr -= 3; // 2 for '(' and ')' and one for the 0 pushed by consumeReferenceType()
problemReporter().validateJavaFeatureSupport(JavaFeature.RECORD_PATTERNS, type.sourceStart, sourceEnd);
pushOnAstStack(recPattern);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12564,6 +12564,13 @@ public void implicitClassMissingMainMethod(TypeDeclaration typeDeclaration) {
typeDeclaration.sourceStart,
typeDeclaration.sourceStart);
}
public void dimensionsIllegalOnRecordPattern(int sourceStart, int sourceEnd) {
this.handle(IProblem.DimensionsIllegalOnRecordPattern,
NoArgument,
NoArgument,
sourceStart,
sourceEnd);
}
public boolean scheduleProblemForContext(Runnable problemComputation) {
if (this.referenceContext != null) {
CompilationResult result = this.referenceContext.compilationResult();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1093,7 +1093,7 @@
1782 = Expression type cannot be a subtype of the Pattern type
1783 = Illegal modifier for the pattern variable {0}; only final is permitted
1784 = A pattern variable with the same name is already defined in the statement

1785 = A record pattern may not specify dimensions

# Java 15 Preview - cont.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1340,6 +1340,7 @@ class ProblemAttributes {
expectedProblemAttributes.put("ImplicitClassMissingMainMethod", new ProblemAttributes(true));
expectedProblemAttributes.put("ClassExtendFinalRecord", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
expectedProblemAttributes.put("RecordErasureIncompatibilityInCanonicalConstructor", new ProblemAttributes(CategorizedProblem.CAT_TYPE));
expectedProblemAttributes.put("DimensionsIllegalOnRecordPattern", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
expectedProblemAttributes.put("JavadocInvalidModule", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
expectedProblemAttributes.put("UnderscoreCannotBeUsedHere", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
expectedProblemAttributes.put("UnnamedVariableMustHaveInitializer", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
Expand Down Expand Up @@ -2454,6 +2455,7 @@ class ProblemAttributes {
expectedProblemAttributes.put("IllegalRecordPattern", SKIP);
expectedProblemAttributes.put("ImplicitClassMissingMainMethod", SKIP);
expectedProblemAttributes.put("ClassExtendFinalRecord", SKIP);
expectedProblemAttributes.put("DimensionsIllegalOnRecordPattern", SKIP);
expectedProblemAttributes.put("RecordErasureIncompatibilityInCanonicalConstructor", SKIP);
expectedProblemAttributes.put("JavadocInvalidModule", SKIP);
expectedProblemAttributes.put("UnderscoreCannotBeUsedHere", SKIP);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4568,4 +4568,126 @@ static void foo(Object o) {
"Illegal fall-through to a pattern\n" +
"----------\n");
}
}
// https://github.com/eclipse-jdt/eclipse.jdt.core/issues/2118
// [Patterns] ECJ allows illegal modifiers with RecordPattern
public void testIllegalModifiers() {
runNegativeTest(new String[] {
"X.java",
"""
public class X {
record Point (int x, int y) {}
static void foo(Object o) {
if (o instanceof public String) {} // javac error, ecj error
if (o instanceof public String s) {} // javac error, ecj error
if (o instanceof public Point(int a, final int b)) {} // javac error, ECJ - NO ERROR!
if (o instanceof Point(public int a, final int b)) {} // javac error, ecj error
if (o instanceof final String) {} // javac error, ecj error
if (o instanceof final String s) {} // javac NO error, ecj NO error
if (o instanceof final Point(int a, int b)) {} // javac NO error, ecj NO error
switch (o) {
case public Point(int a, int b) : System.out.println("String"); // javac error, ECJ: NO ERROR!
case public Object o1: System.out.println("Default"); // both compilers error
}
switch (o) {
case final Point(int a, int b) : System.out.println("String"); // NO ERROR in either
case final Object o2: System.out.println("Default");
}
}
}
"""
},
"----------\n" +
"1. ERROR in X.java (at line 5)\n" +
" if (o instanceof public String) {} // javac error, ecj error\n" +
" ^^^^^^^^^^^^^\n" +
"Syntax error, modifiers are not allowed here\n" +
"----------\n" +
"2. ERROR in X.java (at line 6)\n" +
" if (o instanceof public String s) {} // javac error, ecj error\n" +
" ^\n" +
"Illegal modifier for the pattern variable s; only final is permitted\n" +
"----------\n" +
"3. ERROR in X.java (at line 7)\n" +
" if (o instanceof public Point(int a, final int b)) {} // javac error, ECJ - NO ERROR!\n" +
" ^^^^^^\n" +
"Syntax error, modifiers are not allowed here\n" +
"----------\n" +
"4. ERROR in X.java (at line 8)\n" +
" if (o instanceof Point(public int a, final int b)) {} // javac error, ecj error\n" +
" ^\n" +
"Illegal modifier for the pattern variable a; only final is permitted\n" +
"----------\n" +
"5. ERROR in X.java (at line 10)\n" +
" if (o instanceof final String) {} // javac error, ecj error\n" +
" ^^^^^^^^^^^^\n" +
"Syntax error, modifiers are not allowed here\n" +
"----------\n" +
"6. ERROR in X.java (at line 12)\n" +
" if (o instanceof final Point(int a, int b)) {} // javac NO error, ecj NO error\n" +
" ^^^^^\n" +
"Syntax error, modifiers are not allowed here\n" +
"----------\n" +
"7. ERROR in X.java (at line 15)\n" +
" case public Point(int a, int b) : System.out.println(\"String\"); // javac error, ECJ: NO ERROR!\n" +
" ^^^^^^\n" +
"Syntax error, modifiers are not allowed here\n" +
"----------\n" +
"8. ERROR in X.java (at line 16)\n" +
" case public Object o1: System.out.println(\"Default\"); // both compilers error\n" +
" ^^\n" +
"Illegal modifier for the pattern variable o1; only final is permitted\n" +
"----------\n" +
"9. ERROR in X.java (at line 19)\n" +
" case final Point(int a, int b) : System.out.println(\"String\"); // NO ERROR in either\n" +
" ^^^^^\n" +
"Syntax error, modifiers are not allowed here\n" +
"----------\n");
}
// https://github.com/eclipse-jdt/eclipse.jdt.core/issues/2119
// [Patterns] ECJ allows record pattern to have dimensions
public void testIssue2119() {
runNegativeTest(new String[] {
"X.java",
"""
public class X {
record Point (int x, int y) {}
static void foo(Object o) {
if (o instanceof Point [](int x, int y)) {}
}
}
"""
},
"----------\n" +
"1. ERROR in X.java (at line 5)\n" +
" if (o instanceof Point [](int x, int y)) {}\n" +
" ^^^^^^^^^^^^^^^^^^^^^^\n" +
"A record pattern may not specify dimensions\n" +
"----------\n");
}
// https://github.com/eclipse-jdt/eclipse.jdt.core/issues/2119
// [Patterns] ECJ allows record pattern to have dimensions
public void testIssue2119_2() {
runNegativeTest(new String[] {
"X.java",
"""
public class X {
record Point (int x, int y) {}
static void foo(Object o) {
if (o instanceof Point (int x, int y) []) {}
}
}
"""
},
"----------\n" +
"1. ERROR in X.java (at line 5)\n" +
" if (o instanceof Point (int x, int y) []) {}\n" +
" ^^\n" +
"Syntax error on tokens, delete these tokens\n" +
"----------\n");
}
}

0 comments on commit f78dfbb

Please sign in to comment.