Don't generate bodies of built-in stub methods into interfaces

This commit is contained in:
Alexander Udalov
2014-02-24 15:20:23 +04:00
parent 33ffd3dfca
commit 4968afebf8
4 changed files with 39 additions and 17 deletions
@@ -292,7 +292,7 @@ public class AsmUtil {
: sort == Type.BYTE || sort == Type.SHORT ? Type.INT_TYPE : type;
}
public static void genThrow(MethodVisitor mv, String exception, String message) {
public static void genThrow(@NotNull MethodVisitor mv, @NotNull String exception, @NotNull String message) {
InstructionAdapter iv = new InstructionAdapter(mv);
iv.anew(Type.getObjectType(exception));
iv.dup();
@@ -301,13 +301,6 @@ public class AsmUtil {
iv.athrow();
}
public static void genMethodThrow(MethodVisitor mv, String exception, String message) {
mv.visitCode();
genThrow(mv, exception, message);
mv.visitMaxs(-1, -1);
mv.visitEnd();
}
public static void genClosureFields(CalculatedClosure closure, ClassBuilder v, JetTypeMapper typeMapper) {
ClassifierDescriptor captureThis = closure.getCaptureThis();
int access = NO_FLAG_PACKAGE_PRIVATE | ACC_SYNTHETIC | ACC_FINAL;
@@ -489,11 +489,16 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
private void generateToArray() {
KotlinBuiltIns builtIns = KotlinBuiltIns.getInstance();
if (isSubclass(descriptor, builtIns.getCollection())) {
if (CodegenUtil.getDeclaredFunctionByRawSignature(descriptor, Name.identifier("toArray"), builtIns.getArray()) == null) {
MethodVisitor mv = v.getVisitor().visitMethod(ACC_PUBLIC, "toArray", "()[Ljava/lang/Object;", null, null);
InstructionAdapter iv = new InstructionAdapter(mv);
if (!isSubclass(descriptor, builtIns.getCollection())) return;
int access = descriptor.getKind() == ClassKind.TRAIT ?
ACC_PUBLIC | ACC_ABSTRACT :
ACC_PUBLIC;
if (CodegenUtil.getDeclaredFunctionByRawSignature(descriptor, Name.identifier("toArray"), builtIns.getArray()) == null) {
MethodVisitor mv = v.getVisitor().visitMethod(access, "toArray", "()[Ljava/lang/Object;", null, null);
if (descriptor.getKind() != ClassKind.TRAIT) {
InstructionAdapter iv = new InstructionAdapter(mv);
mv.visitCode();
iv.load(0, classAsmType);
@@ -502,11 +507,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
FunctionCodegen.endVisit(mv, "toArray", myClass);
}
}
if (!isGenericToArrayPresent()) {
MethodVisitor mv = v.getVisitor().visitMethod(ACC_PUBLIC, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", null, null);
if (!isGenericToArrayPresent()) {
MethodVisitor mv = v.getVisitor().visitMethod(access, "toArray", "([Ljava/lang/Object;)[Ljava/lang/Object;", null, null);
if (descriptor.getKind() != ClassKind.TRAIT) {
InstructionAdapter iv = new InstructionAdapter(mv);
mv.visitCode();
iv.load(0, classAsmType);
@@ -528,8 +535,15 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
) {
if (CodegenUtil.getDeclaredFunctionByRawSignature(
descriptor, Name.identifier(name), returnedClassifier, valueParameterClassifiers) == null) {
MethodVisitor mv = v.getVisitor().visitMethod(ACC_PUBLIC, name, desc, null, null);
AsmUtil.genMethodThrow(mv, "java/lang/UnsupportedOperationException", "Mutating immutable collection");
int access = descriptor.getKind() == ClassKind.TRAIT ?
ACC_PUBLIC | ACC_ABSTRACT :
ACC_PUBLIC;
MethodVisitor mv = v.getVisitor().visitMethod(access, name, desc, null, null);
if (descriptor.getKind() != ClassKind.TRAIT) {
mv.visitCode();
genThrow(mv, "java/lang/UnsupportedOperationException", "Mutating immutable collection");
FunctionCodegen.endVisit(mv, "built-in stub for " + name + desc, null);
}
}
}
@@ -0,0 +1,10 @@
trait A : Collection<String>
trait B : List<String>
trait C : Map<Long, Double>
trait D : Map.Entry<Any, Nothing>
trait E : Iterator<Int>
fun box(): String {
trait F : A, B, C, D, E
return "OK"
}
@@ -477,6 +477,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
doTest("compiler/testData/codegen/box/builtinStubMethods/Collection.kt");
}
@TestMetadata("dontGenerateBodyInTrait.kt")
public void testDontGenerateBodyInTrait() throws Exception {
doTest("compiler/testData/codegen/box/builtinStubMethods/dontGenerateBodyInTrait.kt");
}
@TestMetadata("Iterator.kt")
public void testIterator() throws Exception {
doTest("compiler/testData/codegen/box/builtinStubMethods/Iterator.kt");