Generating remove() for Iterator using same mechanism.

This commit is contained in:
Evgeny Gerashchenko
2013-09-24 17:14:17 +04:00
parent b4368ad578
commit 47b70427e1
7 changed files with 27 additions and 56 deletions
@@ -28,16 +28,12 @@ import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeUtils;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import java.util.Collections;
import java.util.List;
import static org.jetbrains.asm4.Opcodes.*;
import static org.jetbrains.jet.codegen.AsmUtil.genMethodThrow;
import static org.jetbrains.asm4.Opcodes.ACC_STATIC;
import static org.jetbrains.asm4.Opcodes.RETURN;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.enumEntryNeedSubclass;
public abstract class ClassBodyCodegen extends MemberCodegen {
@@ -75,8 +71,6 @@ public abstract class ClassBodyCodegen extends MemberCodegen {
generateStaticInitializer();
generateRemoveInIterator();
generateKotlinAnnotation();
}
@@ -196,29 +190,4 @@ public abstract class ClassBodyCodegen extends MemberCodegen {
}
return clInitCodegen;
}
private void generateRemoveInIterator() {
// generates stub 'remove' function for subclasses of Iterator to be compatible with java.util.Iterator
if (isIteratorWithoutRemoveImpl(descriptor)) {
MethodVisitor mv = v.getVisitor().visitMethod(ACC_PUBLIC, "remove", "()V", null, null);
genMethodThrow(mv, "java/lang/UnsupportedOperationException", "Mutating method called on a Kotlin Iterator");
}
}
private static boolean isIteratorWithoutRemoveImpl(@NotNull ClassDescriptor classDescriptor) {
ClassDescriptor iteratorOfT = KotlinBuiltIns.getInstance().getIterator();
JetType iteratorOfAny =
TypeUtils.substituteParameters(iteratorOfT, Collections.singletonList(KotlinBuiltIns.getInstance().getAnyType()));
if (!JetTypeChecker.INSTANCE.isSubtypeOf(classDescriptor.getDefaultType(), iteratorOfAny)) {
return false;
}
for (FunctionDescriptor function : classDescriptor.getDefaultType().getMemberScope().getFunctions(Name.identifier("remove"))) {
if (function.getValueParameters().isEmpty() && function.getTypeParameters().isEmpty()) {
return false;
}
}
return true;
}
}
@@ -522,6 +522,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
}
if (isSubclass(descriptor, builtIns.getIterator())) {
if (CodegenUtil.getDeclaredFunctionByRawSignature(descriptor, Name.identifier("remove"),
builtIns.getUnit()) == null) {
result.add("remove()V");
}
}
return result;
}