Skip to content

Commit

Permalink
Fix code generation for record patterns
Browse files Browse the repository at this point in the history
Fixes eclipse-jdt#1804

Signed-off-by: David Thompson <[email protected]>
  • Loading branch information
datho7561 committed Jan 24, 2024
1 parent 4929232 commit b46fd69
Show file tree
Hide file tree
Showing 6 changed files with 185 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,10 @@ public void wrapupGeneration(CodeStream codeStream) {
this.primaryPattern.wrapupGeneration(codeStream);
}
@Override
public void fullWrapupGeneration(CodeStream codeStream) {
this.primaryPattern.fullWrapupGeneration(codeStream);
}
@Override
protected void generatePatternVariable(BlockScope currentScope, CodeStream codeStream, BranchLabel trueLabel,
BranchLabel falseLabel) {
this.primaryPattern.generatePatternVariable(currentScope, codeStream, trueLabel, falseLabel);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,15 +117,30 @@ public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean

int pc = codeStream.position;

if (this.elementVariable != null) {
if (this.elementVariable != null || this.pattern != null) {
addAssignment(currentScope, codeStream, this.secretInstanceOfPatternExpressionValue);
codeStream.load(this.secretInstanceOfPatternExpressionValue);
} else {
this.expression.generateCode(currentScope, codeStream, true);
}

codeStream.instance_of(this.type, this.type.resolvedType);
if (this.elementVariable != null) {
if (this.pattern != null) {
BranchLabel trueLabel = new BranchLabel(codeStream);
BranchLabel falseLabel = new BranchLabel(codeStream);
BranchLabel continueLabel = new BranchLabel(codeStream);
codeStream.ifeq(falseLabel);
codeStream.load(this.secretInstanceOfPatternExpressionValue);
this.pattern.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel);
this.pattern.fullWrapupGeneration(codeStream);
codeStream.removeVariable(this.secretInstanceOfPatternExpressionValue);
trueLabel.place();
codeStream.iconst_1();
codeStream.goto_(continueLabel);
falseLabel.place();
codeStream.iconst_0();
continueLabel.place();
} else if (this.elementVariable != null) {
BranchLabel actionLabel = new BranchLabel(codeStream);
codeStream.dup();
codeStream.ifeq(actionLabel);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,11 @@ public void resumeVariables(CodeStream codeStream, BlockScope scope) {
protected abstract void generatePatternVariable(BlockScope currentScope, CodeStream codeStream, BranchLabel trueLabel, BranchLabel falseLabel);
protected abstract void wrapupGeneration(CodeStream codeStream);

/**
* Clean up all variables (actual and secret) used in this pattern and child patterns.
*/
protected abstract void fullWrapupGeneration(CodeStream codeStream);

public TypeReference getType() {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,13 @@ public void wrapupGeneration(CodeStream codeStream) {
super.wrapupGeneration(codeStream);
}
@Override
public void fullWrapupGeneration(CodeStream codeStream) {
for (Pattern p : this.patterns) {
p.fullWrapupGeneration(codeStream);
}
super.fullWrapupGeneration(codeStream);
}
@Override
public void suspendVariables(CodeStream codeStream, BlockScope scope) {
codeStream.removeNotDefinitelyAssignedVariables(scope, this.thenInitStateIndex1);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,13 @@ public void wrapupGeneration(CodeStream codeStream) {
codeStream.removeVariable(this.secretPatternVariable);
}
@Override
public void fullWrapupGeneration(CodeStream codeStream) {
this.wrapupGeneration(codeStream);
if (this.local != null) {
codeStream.removeVariable(this.local.binding);
}
}
@Override
public LocalDeclaration getPatternVariable() {
return this.local;
}
Expand Down Expand Up @@ -269,7 +276,7 @@ private static LocalVariableBinding getNewLocalVariableBinding(BlockScope scope,
// int delta = ((TypeBinding.equalsEquals(type, TypeBinding.LONG)) ||
// (TypeBinding.equalsEquals(type, TypeBinding.DOUBLE))) ?
// 2 : 1;
l.resolvedPosition = scope.localIndex;
l.resolvedPosition = scope.startIndex + scope.localIndex;
return l;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3952,4 +3952,148 @@ public static void main(String[] args) {
"s = switch on null\n" +
"s = default threw exception");
}
public void testIssue1804_0() {
runConformTest(new String[] { "X.java", """
public class X {
record Paper(int color) {}
record Box<T>(T a) {}
public static void main(String[] args) {
Box<?> b = new Box<>(null);
boolean res = b instanceof Box(Paper a);
if (res) {
System.out.println("res is true");
} else {
System.out.println("res is false");
}
}
}
""" }, "res is false");
}
public void testIssue1804_1() {
runConformTest(new String[] { "X.java", """
public class X {
record Paper(int color) {}
record Box<T>(T a) {}
public static void main(String[] args) {
Box<?> b = new Box<>(new Paper(0));
boolean res = b instanceof Box(Paper a);
if (res) {
System.out.println("res is true");
} else {
System.out.println("res is false");
}
}
}
""" }, "res is true");
}
public void testIssue1804_2() {
runConformTest(new String[] { "X.java", """
public class X {
record Paper(int color) {}
record Box<T>(T a) {}
public static void main(String[] args) {
Box<?> b = new Box<>(new Paper(0));
boolean res = b instanceof Box(Paper a) && a == null;
if (res) {
System.out.println("res is true");
} else {
System.out.println("res is false");
}
}
}
""" }, "res is false");
}
public void testIssue1804_3() {
runConformTest(new String[] { "X.java", """
public class X {
record Paper(int color) {}
record Box<T>(T a) {}
public static void main(String[] args) {
Box b = new Box<>(null);
System.out.println(b instanceof Box(Paper a));
System.out.println(b instanceof Box(Object a));
}
}
""" }, "false\ntrue");
}
public void testIssue1804_4() {
runConformTest(new String[] { "X.java", """
public class X {
record Paper(int color) {}
record Box<T>(T a) {}
public static void main(String argv[]) {
foo(null, null);
}
public static void foo(String abc, String def) {
Box<?> p = new Box<>(new Paper(0));
boolean b = false;
switch (p) {
case Box(Paper a) -> {
b = true;
break;
}
default -> {
b = false;
break;
}
}
System.out.println(b);
}
}
""" }, "true");
}
public void testIssue1804_5() {
runConformTest(new String[] { "X.java", """
public class X {
record Paper(int color) {}
record Box<T>(T a) {}
public static void main(String argv[]) {
foo(null, null);
}
public static void foo(String abc, String def) {
Box<?> p = new Box<>(null);
boolean b = false;
switch (p) {
case Box(Paper a) -> {
b = true;
break;
}
default -> {
b = false;
break;
}
}
System.out.println(b);
}
}
""" }, "false");
}
public void testIssue1804_6() {
runConformTest(new String[] { "X.java", """
public class X {
record Paper(int color) {}
record Box<T>(T a, T b) {}
public static void main(String argv[]) {
foo(null, null);
}
public static void foo(String abc, String def) {
Box<?> p = new Box<>(new Paper(0), new Paper(1));
boolean c = false;
switch (p) {
case Box(Paper a, Paper b) -> {
System.out.println(a.color);
System.out.println(b.color);
c = true;
break;
}
default -> {
c = false;
break;
}
}
System.out.println(c);
}
}
""" }, "0\n1\ntrue");
}
}

0 comments on commit b46fd69

Please sign in to comment.