Fixes for KT-4991: Prefix/postfix expressions resolved to local extensions are not supported in codegen;
KT-4989: Verify error on local functions and extensions; KT-4987: NegativeArraySizeException on local extension convention function on nullable Int #KT-4991 Fixed #KT-4989 Fixed #KT-4987 Fixed
This commit is contained in:
@@ -3069,24 +3069,25 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
|
||||
@Override
|
||||
public StackValue visitPrefixExpression(@NotNull JetPrefixExpression expression, StackValue receiver) {
|
||||
DeclarationDescriptor op = bindingContext.get(REFERENCE_TARGET, expression.getOperationReference());
|
||||
assert op instanceof FunctionDescriptor : String.valueOf(op);
|
||||
DeclarationDescriptor originalOperation = bindingContext.get(REFERENCE_TARGET, expression.getOperationReference());
|
||||
ResolvedCall<?> resolvedCall = getResolvedCallWithAssert(expression, bindingContext);
|
||||
CallableDescriptor op = resolvedCall.getResultingDescriptor();
|
||||
|
||||
assert op instanceof FunctionDescriptor || originalOperation == null : String.valueOf(op);
|
||||
Callable callable = resolveToCallable((FunctionDescriptor) op, false);
|
||||
if (callable instanceof IntrinsicMethod) {
|
||||
Type returnType = typeMapper.mapType((FunctionDescriptor) op);
|
||||
Type returnType = typeMapper.mapType(op);
|
||||
((IntrinsicMethod) callable).generate(this, v, returnType, expression,
|
||||
Collections.singletonList(expression.getBaseExpression()), receiver);
|
||||
return StackValue.onStack(returnType);
|
||||
}
|
||||
|
||||
DeclarationDescriptor cls = op.getContainingDeclaration();
|
||||
ResolvedCall<?> resolvedCall = getResolvedCallWithAssert(expression, bindingContext);
|
||||
|
||||
if (isPrimitiveNumberClassDescriptor(cls) || !(op.getName().asString().equals("inc") || op.getName().asString().equals("dec"))) {
|
||||
if (isPrimitiveNumberClassDescriptor(cls) || !(originalOperation.getName().asString().equals("inc") || originalOperation.getName().asString().equals("dec"))) {
|
||||
return invokeFunction(resolvedCall, receiver);
|
||||
}
|
||||
|
||||
CallableMethod callableMethod = (CallableMethod) callable;
|
||||
|
||||
StackValue value = gen(expression.getBaseExpression());
|
||||
value.dupReceiver(v);
|
||||
@@ -3096,6 +3097,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
value.put(type, v);
|
||||
invokeFunction(resolvedCall, StackValue.onStack(type));
|
||||
|
||||
CallableMethod callableMethod = (CallableMethod) callable;
|
||||
value.store(callableMethod.getReturnType(), v);
|
||||
value.put(type, v);
|
||||
return StackValue.onStack(type);
|
||||
@@ -3117,23 +3119,26 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
return StackValue.onStack(base.type);
|
||||
}
|
||||
|
||||
DeclarationDescriptor op = bindingContext.get(REFERENCE_TARGET, expression.getOperationReference());
|
||||
if (!(op instanceof FunctionDescriptor)) {
|
||||
throw new UnsupportedOperationException("Don't know how to generate this postfix expression: " + op);
|
||||
DeclarationDescriptor originalOperation = bindingContext.get(REFERENCE_TARGET, expression.getOperationReference());
|
||||
String originalOperationName = originalOperation != null ? originalOperation.getName().asString() : null;
|
||||
ResolvedCall<?> resolvedCall = getResolvedCallWithAssert(expression, bindingContext);
|
||||
DeclarationDescriptor op = resolvedCall.getResultingDescriptor();
|
||||
if (!(op instanceof FunctionDescriptor) || originalOperation == null) {
|
||||
throw new UnsupportedOperationException("Don't know how to generate this postfix expression: " + originalOperationName + " " + op);
|
||||
}
|
||||
|
||||
Type asmType = expressionType(expression);
|
||||
DeclarationDescriptor cls = op.getContainingDeclaration();
|
||||
|
||||
int increment;
|
||||
if (op.getName().asString().equals("inc")) {
|
||||
if (originalOperationName.equals("inc")) {
|
||||
increment = 1;
|
||||
}
|
||||
else if (op.getName().asString().equals("dec")) {
|
||||
else if (originalOperationName.equals("dec")) {
|
||||
increment = -1;
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("Unsupported postfix operation: " + op);
|
||||
throw new UnsupportedOperationException("Unsupported postfix operation: " + originalOperationName + " " + op);
|
||||
}
|
||||
|
||||
boolean isPrimitiveNumberClassDescriptor = isPrimitiveNumberClassDescriptor(cls);
|
||||
@@ -3161,7 +3166,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
storeType = type;
|
||||
}
|
||||
else {
|
||||
ResolvedCall<?> resolvedCall = getResolvedCallWithAssert(expression, bindingContext);
|
||||
Callable callable = resolveToCallable((FunctionDescriptor) op, false);
|
||||
invokeFunction(resolvedCall, StackValue.onStack(type));
|
||||
CallableMethod callableMethod = (CallableMethod) callable;
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
class It(val id: String)
|
||||
|
||||
fun box(): String {
|
||||
val projectId = "projectId"
|
||||
val it = It("it")
|
||||
|
||||
|
||||
fun selectMetaRunnerId(): String {
|
||||
fun Int?.inc() = (this ?: 0) + 1
|
||||
var counter: Int? = null
|
||||
fun path(metaRunnerId: String) = counter != 2
|
||||
|
||||
while (true) {
|
||||
val name = projectId + "_" + it.id + (if (counter == null) "" else "_$counter")
|
||||
if (!path(name)) {
|
||||
return name
|
||||
}
|
||||
counter++
|
||||
}
|
||||
}
|
||||
val X = selectMetaRunnerId()
|
||||
if (X != projectId + "_" + it.id + "_2") return "fail: $X"
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
fun box(): String {
|
||||
fun Int?.inc() = (this ?: 0) + 1
|
||||
var counter: Int? = null
|
||||
counter++
|
||||
return if (counter == 1) "OK" else "fail: $counter"
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
var a = A()
|
||||
var b = A()
|
||||
|
||||
class A(var value: Int = 0)
|
||||
|
||||
fun prefix(inc: A.() -> A) {
|
||||
++a
|
||||
}
|
||||
|
||||
fun postfix(inc: A.() -> A) {
|
||||
b++
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
prefix { ++value; this }
|
||||
|
||||
if (a.value != 1) return "fail 1"
|
||||
|
||||
postfix { value++; this }
|
||||
|
||||
if (b.value != 1) return "fail 2"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -3511,6 +3511,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt4989.kt")
|
||||
public void testKt4989() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/kt4989.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("localExtensionOnNullableParameter.kt")
|
||||
public void testLocalExtensionOnNullableParameter() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/functions/localFunctions/localExtensionOnNullableParameter.kt");
|
||||
@@ -5012,6 +5018,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt4987.kt")
|
||||
public void testKt4987() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/operatorConventions/kt4987.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt4991.kt")
|
||||
public void testKt4991() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/operatorConventions/kt4991.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/operatorConventions/compareTo")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(org.jetbrains.jet.JUnit3RunnerWithInners.class)
|
||||
|
||||
Reference in New Issue
Block a user