Generating remove() for Iterator using same mechanism.
This commit is contained in:
@@ -28,16 +28,12 @@ import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl;
|
|||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
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.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.jetbrains.asm4.Opcodes.*;
|
import static org.jetbrains.asm4.Opcodes.ACC_STATIC;
|
||||||
import static org.jetbrains.jet.codegen.AsmUtil.genMethodThrow;
|
import static org.jetbrains.asm4.Opcodes.RETURN;
|
||||||
import static org.jetbrains.jet.codegen.binding.CodegenBinding.enumEntryNeedSubclass;
|
import static org.jetbrains.jet.codegen.binding.CodegenBinding.enumEntryNeedSubclass;
|
||||||
|
|
||||||
public abstract class ClassBodyCodegen extends MemberCodegen {
|
public abstract class ClassBodyCodegen extends MemberCodegen {
|
||||||
@@ -75,8 +71,6 @@ public abstract class ClassBodyCodegen extends MemberCodegen {
|
|||||||
|
|
||||||
generateStaticInitializer();
|
generateStaticInitializer();
|
||||||
|
|
||||||
generateRemoveInIterator();
|
|
||||||
|
|
||||||
generateKotlinAnnotation();
|
generateKotlinAnnotation();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,29 +190,4 @@ public abstract class ClassBodyCodegen extends MemberCodegen {
|
|||||||
}
|
}
|
||||||
return clInitCodegen;
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
class MyIterator<T>(val v: T): Iterator<T> {
|
||||||
|
override fun next(): T = v
|
||||||
|
override fun hasNext(): Boolean = true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
try {
|
||||||
|
(MyIterator<String>("") as MutableIterator<String>).remove()
|
||||||
|
throw AssertionError()
|
||||||
|
} catch (e: UnsupportedOperationException) {
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
public class removeInIterator {
|
|
||||||
public static void bar(java.util.Iterator<Integer> it) {
|
|
||||||
it.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
fun box() : String {
|
|
||||||
try {
|
|
||||||
removeInIterator.bar(object : Iterator<Int> {
|
|
||||||
public override fun hasNext(): Boolean = false
|
|
||||||
public override fun next(): Int = 1
|
|
||||||
})
|
|
||||||
}
|
|
||||||
catch (e: UnsupportedOperationException) {
|
|
||||||
if (e.getMessage() == "Mutating method called on a Kotlin Iterator")
|
|
||||||
return "OK"
|
|
||||||
}
|
|
||||||
return "fail"
|
|
||||||
}
|
|
||||||
@@ -424,6 +424,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/box/builtinStubMethods"), Pattern.compile("^(.+)\\.kt$"), true);
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/box/builtinStubMethods"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("Iterator.kt")
|
||||||
|
public void testIterator() throws Exception {
|
||||||
|
doTest("compiler/testData/codegen/box/builtinStubMethods/Iterator.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("List.kt")
|
@TestMetadata("List.kt")
|
||||||
public void testList() throws Exception {
|
public void testList() throws Exception {
|
||||||
doTest("compiler/testData/codegen/box/builtinStubMethods/List.kt");
|
doTest("compiler/testData/codegen/box/builtinStubMethods/List.kt");
|
||||||
|
|||||||
-5
@@ -127,11 +127,6 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege
|
|||||||
doTestWithJava("compiler/testData/codegen/boxWithJava/functions/referencesStaticInnerClassMethodL2.kt");
|
doTestWithJava("compiler/testData/codegen/boxWithJava/functions/referencesStaticInnerClassMethodL2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("removeInIterator.kt")
|
|
||||||
public void testRemoveInIterator() throws Exception {
|
|
||||||
doTestWithJava("compiler/testData/codegen/boxWithJava/functions/removeInIterator.kt");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/boxWithJava/innerClass")
|
@TestMetadata("compiler/testData/codegen/boxWithJava/innerClass")
|
||||||
|
|||||||
Reference in New Issue
Block a user