Skip to content

Commit

Permalink
GROOVY-10395
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed Nov 29, 2021
1 parent 01289d0 commit a31702c
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -6978,4 +6978,51 @@ public void testCompileStatic10394() {

runConformTest(sources, "12");
}

@Test
public void testCompileStatic10395() {
for (String type : new String[] {"int", "long", "short", "byte", "char", "double", "float"}) {
//@formatter:off
String[] sources = {
"Main.groovy",
"@groovy.transform.CompileStatic\n" +
"int test(" + type + " a, " + type + " b) {\n" +
" a <=> b\n" +
"}\n" +
"assert test((" + type + ")0,(" + type + ")0) == 0\n" +
"assert test((" + type + ")0,(" + type + ")1) < 0\n" +
"assert test((" + type + ")1,(" + type + ")0) > 0\n",
};
//@formatter:on

runConformTest(sources);

String result = disassemble(getOutputFile("Main.class"), 1);
int pos = result.indexOf("ScriptBytecodeAdapter.compareTo");
assertTrue(pos < 0);
}
}

@Test
public void testCompileStatic10395b() {
//@formatter:off
String[] sources = {
"Main.groovy",
"@groovy.transform.CompileStatic\n" +
"int test(boolean a, boolean b) {\n" +
" a <=> b\n" +
"}\n" +
"assert test(false,false) == 0\n" +
"assert test(false,true) < 0\n" +
"assert test(true,false) > 0\n" +
"assert test(true,true) == 0\n",
};
//@formatter:on

runConformTest(sources);

String result = disassemble(getOutputFile("Main.class"), 1);
int pos = result.indexOf("ScriptBytecodeAdapter.compareTo");
assertTrue(pos < 0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,28 @@ Expression transformBinaryExpression(final BinaryExpression bin) {
compareToNullExpression.setSourcePosition(bin);
return compareToNullExpression;
}
// GRECLIPSE add -- GROOVY-10395
} else if (operationType == Types.COMPARE_TO) {
ClassNode leftType = staticCompilationTransformer.getTypeChooser().resolveType(leftExpression, staticCompilationTransformer.getClassNode());
ClassNode rightType = staticCompilationTransformer.getTypeChooser().resolveType(rightExpression, staticCompilationTransformer.getClassNode());
// same-type primitive compare
if (leftType.equals(rightType)
&& ClassHelper.isPrimitiveType(leftType)
|| ClassHelper.isPrimitiveType(rightType)) {
ClassNode wrapperType = ClassHelper.getWrapper(leftType);
Expression leftAndRight = new ArgumentListExpression(
staticCompilationTransformer.transform(leftExpression),
staticCompilationTransformer.transform(rightExpression)
);
// transform "a <=> b" into "[Integer|Long|Short|Byte|Double|Float|...].compare(a,b)"
MethodCallExpression call = new MethodCallExpression(new ClassExpression(wrapperType), "compare", leftAndRight);
call.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, ClassHelper.int_TYPE);
call.setMethodTarget(wrapperType.getMethods("compare").get(0));
call.setImplicitThis(false);
call.setSourcePosition(bin);
return call;
}
// GRECLIPSE end
} else if (operationType == Types.KEYWORD_IN) {
return convertInOperatorToTernary(bin, rightExpression, leftExpression);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ public Expression transformBinaryExpression(final BinaryExpression bin) {
compareToNullExpression.setSourcePosition(bin);
return compareToNullExpression;
}
// GRECLIPSE add -- GROOVY-10377
// GRECLIPSE add -- GROOVY-10377, GROOVY-10395
} else if (operationType == Types.COMPARE_IDENTICAL || operationType == Types.COMPARE_NOT_IDENTICAL) {
if (isNullConstant(rightExpression)) {
CompareToNullExpression ctn = new CompareToNullExpression(staticCompilationTransformer.transform(leftExpression), operationType == Types.COMPARE_IDENTICAL);
Expand All @@ -166,6 +166,25 @@ public Expression transformBinaryExpression(final BinaryExpression bin) {
cid.setSourcePosition(bin);
return cid;
}
} else if (operationType == Types.COMPARE_TO) {
ClassNode leftType = findType(leftExpression), rightType = findType(rightExpression);
// same-type primitive compare
if (leftType.equals(rightType)
&& ClassHelper.isPrimitiveType(leftType)
|| ClassHelper.isPrimitiveType(rightType)) {
ClassNode wrapperType = ClassHelper.getWrapper(leftType);
Expression leftAndRight = args(
staticCompilationTransformer.transform(leftExpression),
staticCompilationTransformer.transform(rightExpression)
);
// transform "a <=> b" into "[Integer|Long|Short|Byte|Double|Float|...].compare(a,b)"
MethodCallExpression call = callX(classX(wrapperType), "compare", leftAndRight);
call.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, ClassHelper.int_TYPE);
call.setMethodTarget(wrapperType.getMethods("compare").get(0));
call.setImplicitThis(false);
call.setSourcePosition(bin);
return call;
}
// GRECLIPSE end
} else if (operationType == Types.KEYWORD_IN) {
return staticCompilationTransformer.transform(convertInOperatorToTernary(bin, rightExpression, leftExpression));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,24 @@ private Expression transformRelationComparison(final BinaryExpression bin) {
Expression leftExpression = bin.getLeftExpression(), rightExpression = bin.getRightExpression();
ClassNode leftType = findType(leftExpression), rightType = findType(rightExpression);

// same-type primitive compare
if (leftType.equals(rightType)
&& ClassHelper.isPrimitiveType(leftType)
|| ClassHelper.isPrimitiveType(rightType)) {
ClassNode wrapperType = ClassHelper.getWrapper(leftType);
Expression leftAndRight = args(
staticCompilationTransformer.transform(leftExpression),
staticCompilationTransformer.transform(rightExpression)
);
// transform "a <=> b" into "[Integer|Long|Short|Byte|Double|Float|...].compare(a,b)"
MethodCallExpression call = callX(classX(wrapperType), "compare", leftAndRight);
call.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, ClassHelper.int_TYPE);
call.setMethodTarget(wrapperType.getMethods("compare").get(0));
call.setImplicitThis(false);
call.setSourcePosition(bin);
return call;
}

if (leftType.implementsInterface(ClassHelper.COMPARABLE_TYPE)
&& rightType.implementsInterface(ClassHelper.COMPARABLE_TYPE)) {
// GROOVY-5644, GROOVY-6137, GROOVY-7473, GROOVY-10394: null safety and one-time evaluation
Expand Down

0 comments on commit a31702c

Please sign in to comment.