Treat any coroutine as it has non-const closure

Because it's always does capture controller
This commit is contained in:
Denis Zharkov
2016-07-04 15:32:54 +03:00
parent df4bf61378
commit d657bc8110
8 changed files with 83 additions and 2 deletions
@@ -101,7 +101,10 @@ public class JvmCodegenUtil {
}
public static boolean isConst(@NotNull CalculatedClosure closure) {
return closure.getCaptureThis() == null && closure.getCaptureReceiverType() == null && closure.getCaptureVariables().isEmpty();
return closure.getCaptureThis() == null &&
closure.getCaptureReceiverType() == null &&
closure.getCaptureVariables().isEmpty() &&
!closure.isCoroutine();
}
private static boolean isCallInsideSameClassAsDeclared(@NotNull CallableMemberDescriptor descriptor, @NotNull CodegenContext context) {
@@ -40,4 +40,6 @@ public interface CalculatedClosure {
@NotNull
List<Pair<String, Type>> getRecordedFields();
boolean isCoroutine();
}
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.TypeMapperUtilsKt;
import org.jetbrains.kotlin.codegen.when.SwitchCodegenUtil;
import org.jetbrains.kotlin.codegen.when.WhenByEnumsMapping;
import org.jetbrains.kotlin.coroutines.CoroutineUtilKt;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor;
@@ -270,7 +271,11 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
String name = inventAnonymousClassName();
Collection<KotlinType> supertypes = runtimeTypes.getSupertypesForClosure(functionDescriptor);
ClassDescriptor classDescriptor = recordClassForCallable(functionLiteral, functionDescriptor, supertypes, name);
recordClosure(classDescriptor, name);
MutableClosure closure = recordClosure(classDescriptor, name);
if (CoroutineUtilKt.getControllerTypeIfCoroutine(functionDescriptor) != null) {
closure.setCoroutine(true);
}
classStack.push(classDescriptor);
nameStack.push(name);
@@ -39,6 +39,7 @@ public final class MutableClosure implements CalculatedClosure {
private Map<DeclarationDescriptor, Integer> parameterOffsetInConstructor;
private List<Pair<String, Type>> recordedFields;
private KotlinType captureReceiverType;
private boolean isCoroutine;
MutableClosure(@NotNull ClassDescriptor classDescriptor, @Nullable ClassDescriptor enclosingClass) {
this.enclosingClass = enclosingClass;
@@ -109,6 +110,15 @@ public final class MutableClosure implements CalculatedClosure {
return recordedFields != null ? recordedFields : Collections.<Pair<String, Type>>emptyList();
}
@Override
public boolean isCoroutine() {
return isCoroutine;
}
public void setCoroutine(boolean coroutine) {
this.isCoroutine = coroutine;
}
public void recordField(String name, Type type) {
if (recordedFields == null) {
recordedFields = new LinkedList<Pair<String, Type>>();