diff --git a/build.xml b/build.xml
index 68287f6f74f..83eaecaba8b 100644
--- a/build.xml
+++ b/build.xml
@@ -167,7 +167,7 @@
-
+
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java
index c6275166cea..a06a150cb3a 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java
@@ -136,7 +136,7 @@ public abstract class ClassBodyCodegen {
private void generateStaticInitializer() {
if (staticInitializerChunks.size() > 0) {
final MethodVisitor mv = v.newMethod(null, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC,"", "()V", null, null);
- if (v.generateCode()) {
+ if (v.generateCode() == ClassBuilder.Mode.FULL) {
mv.visitCode();
InstructionAdapter v = new InstructionAdapter(mv);
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilder.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilder.java
index dba4333f031..1847c77f6d2 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilder.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilder.java
@@ -29,15 +29,22 @@ import org.objectweb.asm.MethodVisitor;
public abstract class ClassBuilder {
public static class Concrete extends ClassBuilder {
private final ClassVisitor v;
+ private final boolean stubs;
- public Concrete(ClassVisitor v) {
+ public Concrete(ClassVisitor v, boolean stubs) {
this.v = v;
+ this.stubs = stubs;
}
@Override
public ClassVisitor getVisitor() {
return v;
}
+
+ @Override
+ public Mode generateCode() {
+ return stubs ? Mode.STUBS : Mode.FULL;
+ }
}
public FieldVisitor newField(@Nullable PsiElement origin,
int access,
@@ -85,7 +92,14 @@ public abstract class ClassBuilder {
getVisitor().visitInnerClass(name, outerName, innerName, access);
}
- public boolean generateCode() {
- return true;
+ public enum Mode {
+ /** Full function bodies */
+ FULL,
+ /** Only function signatures */
+ SIGNATURES,
+ /** Function with stub bodies: just throw exception */
+ STUBS,
}
+
+ public abstract Mode generateCode();
}
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilderFactories.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilderFactories.java
new file mode 100644
index 00000000000..ff2e616aa82
--- /dev/null
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilderFactories.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.codegen;
+
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.util.TraceClassVisitor;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+/**
+ * @author Stepan Koltsov
+ */
+public class ClassBuilderFactories {
+
+ public static ClassBuilderFactory TEXT = new ClassBuilderFactory() {
+ @Override
+ public ClassBuilder newClassBuilder() {
+ return new ClassBuilder.Concrete(new TraceClassVisitor(new PrintWriter(new StringWriter())), false);
+ }
+
+ @Override
+ public String asText(ClassBuilder builder) {
+ TraceClassVisitor visitor = (TraceClassVisitor) builder.getVisitor();
+
+ StringWriter writer = new StringWriter();
+ visitor.print(new PrintWriter(writer));
+
+ return writer.toString();
+ }
+
+ @Override
+ public byte[] asBytes(ClassBuilder builder) {
+ throw new UnsupportedOperationException("TEXT generator asked for bytes");
+ }
+ };
+
+ public static ClassBuilderFactory binaries(final boolean stubs) {
+ return new ClassBuilderFactory() {
+ @Override
+ public ClassBuilder newClassBuilder() {
+ return new ClassBuilder.Concrete(new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS){
+ @Override
+ protected String getCommonSuperClass(String type1, String type2) {
+ try {
+ return super.getCommonSuperClass(type1, type2);
+ }
+ catch (Throwable t) {
+ // @todo we might need at some point do more sofisticated handling
+ return "java/lang/Object";
+ }
+ }
+ }, stubs);
+ }
+
+ @Override
+ public String asText(ClassBuilder builder) {
+ throw new UnsupportedOperationException("BINARIES generator asked for text");
+ }
+
+ @Override
+ public byte[] asBytes(ClassBuilder builder) {
+ ClassWriter visitor = (ClassWriter) builder.getVisitor();
+ return visitor.toByteArray();
+ }
+ };
+ }
+}
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilderFactory.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilderFactory.java
index d4dc9949467..e46d50c4fe2 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilderFactory.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilderFactory.java
@@ -29,56 +29,4 @@ public interface ClassBuilderFactory {
ClassBuilder newClassBuilder();
String asText(ClassBuilder builder);
byte[] asBytes(ClassBuilder builder);
-
- ClassBuilderFactory TEXT = new ClassBuilderFactory() {
- @Override
- public ClassBuilder newClassBuilder() {
- return new ClassBuilder.Concrete(new TraceClassVisitor(new PrintWriter(new StringWriter())));
- }
-
- @Override
- public String asText(ClassBuilder builder) {
- TraceClassVisitor visitor = (TraceClassVisitor) builder.getVisitor();
-
- StringWriter writer = new StringWriter();
- visitor.print(new PrintWriter(writer));
-
- return writer.toString();
- }
-
- @Override
- public byte[] asBytes(ClassBuilder builder) {
- throw new UnsupportedOperationException("TEXT generator asked for bytes");
- }
- };
-
- ClassBuilderFactory BINARIES = new ClassBuilderFactory() {
- @Override
- public ClassBuilder newClassBuilder() {
- return new ClassBuilder.Concrete(new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS){
- @Override
- protected String getCommonSuperClass(String type1, String type2) {
- try {
- return super.getCommonSuperClass(type1, type2);
- }
- catch (Throwable t) {
- // @todo we might need at some point do more sofisticated handling
- return "java/lang/Object";
- }
- }
- });
- }
-
- @Override
- public String asText(ClassBuilder builder) {
- throw new UnsupportedOperationException("BINARIES generator asked for text");
- }
-
- @Override
- public byte[] asBytes(ClassBuilder builder) {
- ClassWriter visitor = (ClassWriter) builder.getVisitor();
- return visitor.toByteArray();
- }
- };
-
}
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassCodegen.java
index aa8753a8d8d..ea884fd62d0 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassCodegen.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassCodegen.java
@@ -40,7 +40,7 @@ public class ClassCodegen {
final CodegenContext contextForInners = context.intoClass(descriptor, OwnerKind.IMPLEMENTATION, state.getTypeMapper());
- if (!classBuilder.generateCode()) {
+ if (classBuilder.generateCode() == ClassBuilder.Mode.SIGNATURES) {
// Outer class implementation must happen prior inner classes so we get proper scoping tree in JetLightClass's delegate
generateImplementation(context, aClass, OwnerKind.IMPLEMENTATION, contextForInners.accessors, classBuilder);
}
@@ -54,7 +54,7 @@ public class ClassCodegen {
}
}
- if (classBuilder.generateCode()) {
+ if (classBuilder.generateCode() != ClassBuilder.Mode.SIGNATURES) {
generateImplementation(context, aClass, OwnerKind.IMPLEMENTATION, contextForInners.accessors, classBuilder);
}
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java
index 310039906e3..c77fc814625 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java
@@ -166,7 +166,10 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
cv.newField(fun, ACC_PRIVATE | ACC_STATIC | ACC_FINAL, "$instance", classDescr, null, null);
MethodVisitor mv = cv.newMethod(fun, ACC_PUBLIC | ACC_STATIC, "$getInstance", "()" + classDescr, null, new String[0]);
- if (cv.generateCode()) {
+ if (cv.generateCode() == ClassBuilder.Mode.STUBS) {
+ StubCodegen.generateStubCode(mv);
+ }
+ else if (cv.generateCode() == ClassBuilder.Mode.FULL) {
mv.visitCode();
mv.visitFieldInsn(GETSTATIC, name, "$instance", classDescr);
mv.visitInsn(DUP);
@@ -204,7 +207,10 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
return;
final MethodVisitor mv = cv.newMethod(fun, ACC_PUBLIC, "invoke", bridge.getAsmMethod().getDescriptor(), null, new String[0]);
- if (cv.generateCode()) {
+ if (cv.generateCode() == ClassBuilder.Mode.STUBS) {
+ StubCodegen.generateStubCode(mv);
+ }
+ if (cv.generateCode() == ClassBuilder.Mode.FULL) {
mv.visitCode();
InstructionAdapter iv = new InstructionAdapter(mv);
@@ -280,7 +286,10 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
final Method constructor = new Method("", Type.VOID_TYPE, argTypes);
final MethodVisitor mv = cv.newMethod(fun, ACC_PUBLIC, "", constructor.getDescriptor(), null, new String[0]);
- if (cv.generateCode()) {
+ if (cv.generateCode() == ClassBuilder.Mode.STUBS) {
+ StubCodegen.generateStubCode(mv);
+ }
+ else if (cv.generateCode() == ClassBuilder.Mode.FULL) {
mv.visitCode();
InstructionAdapter iv = new InstructionAdapter(mv);
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java
index 678bceaa671..636e96e9cc0 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java
@@ -115,7 +115,7 @@ public class FunctionCodegen {
final MethodVisitor mv = v.newMethod(fun, flags, jvmSignature.getAsmMethod().getName(), jvmSignature.getAsmMethod().getDescriptor(), jvmSignature.getGenericsSignature(), null);
AnnotationCodegen.forMethod(mv).genAnnotations(functionDescriptor, state.getTypeMapper());
- if(v.generateCode()) {
+ if(v.generateCode() != ClassBuilder.Mode.SIGNATURES) {
int start = 0;
if (needJetAnnotations) {
if (functionDescriptor instanceof PropertyAccessorDescriptor) {
@@ -164,8 +164,12 @@ public class FunctionCodegen {
}
}
+ if (!isAbstract && v.generateCode() == ClassBuilder.Mode.STUBS) {
+ StubCodegen.generateStubCode(mv);
+ }
- if (!isAbstract && v.generateCode()) {
+
+ if (!isAbstract && v.generateCode() == ClassBuilder.Mode.FULL) {
mv.visitCode();
Label methodBegin = new Label();
@@ -323,7 +327,10 @@ public class FunctionCodegen {
descriptor = descriptor.replace("(","(L" + ownerInternalName + ";");
final MethodVisitor mv = v.newMethod(null, flags | (isConstructor ? 0 : ACC_STATIC), isConstructor ? "" : jvmSignature.getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, descriptor, null, null);
InstructionAdapter iv = new InstructionAdapter(mv);
- if (v.generateCode()) {
+ if (v.generateCode() == ClassBuilder.Mode.STUBS) {
+ StubCodegen.generateStubCode(mv);
+ }
+ else if (v.generateCode() == ClassBuilder.Mode.FULL) {
mv.visitCode();
FrameMap frameMap = owner.prepareFrame(state.getTypeMapper());
@@ -443,7 +450,10 @@ public class FunctionCodegen {
int flags = ACC_PUBLIC | ACC_BRIDGE; // TODO.
final MethodVisitor mv = v.newMethod(null, flags, jvmSignature.getName(), overriden.getDescriptor(), null, null);
- if (v.generateCode()) {
+ if (v.generateCode() == ClassBuilder.Mode.STUBS) {
+ StubCodegen.generateStubCode(mv);
+ }
+ else if (v.generateCode() == ClassBuilder.Mode.FULL) {
mv.visitCode();
Type[] argTypes = overriden.getArgumentTypes();
@@ -481,7 +491,10 @@ public class FunctionCodegen {
int flags = ACC_PUBLIC | ACC_SYNTHETIC; // TODO.
final MethodVisitor mv = v.newMethod(null, flags, method.getName(), method.getDescriptor(), null, null);
- if (v.generateCode()) {
+ if (v.generateCode() == ClassBuilder.Mode.STUBS) {
+ StubCodegen.generateStubCode(mv);
+ }
+ else if (v.generateCode() == ClassBuilder.Mode.FULL) {
mv.visitCode();
Type[] argTypes = method.getArgumentTypes();
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java
index e377090ba2c..0ff3405763f 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java
@@ -272,7 +272,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
Type[] argTypes = method.getArgumentTypes();
MethodVisitor mv = v.newMethod(null, ACC_PUBLIC| ACC_BRIDGE| ACC_FINAL, bridge.getName(), method.getDescriptor(), null, null);
- if (v.generateCode()) {
+ if (v.generateCode() == ClassBuilder.Mode.STUBS) {
+ StubCodegen.generateStubCode(mv);
+ }
+ else if (v.generateCode() == ClassBuilder.Mode.FULL) {
mv.visitCode();
InstructionAdapter iv = new InstructionAdapter(mv);
@@ -300,7 +303,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
Method originalMethod = originalSignature.getJvmMethodSignature().getAsmMethod();
MethodVisitor mv = v.newMethod(null, ACC_PUBLIC | ACC_BRIDGE | ACC_FINAL, method.getName(), method.getDescriptor(), null, null);
PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature.getPropertyTypeKotlinSignature(), originalSignature.getJvmMethodSignature().getKotlinTypeParameter());
- if (v.generateCode()) {
+ if (v.generateCode() == ClassBuilder.Mode.STUBS) {
+ StubCodegen.generateStubCode(mv);
+ }
+ else if (v.generateCode() == ClassBuilder.Mode.FULL) {
mv.visitCode();
InstructionAdapter iv = new InstructionAdapter(mv);
@@ -323,7 +329,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
Method originalMethod = originalSignature2.getJvmMethodSignature().getAsmMethod();
MethodVisitor mv = v.newMethod(null, ACC_PUBLIC | ACC_BRIDGE | ACC_FINAL, method.getName(), method.getDescriptor(), null, null);
PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature2.getPropertyTypeKotlinSignature(), originalSignature2.getJvmMethodSignature().getKotlinTypeParameter());
- if (v.generateCode()) {
+ if (v.generateCode() == ClassBuilder.Mode.STUBS) {
+ StubCodegen.generateStubCode(mv);
+ }
+ else if (v.generateCode() == ClassBuilder.Mode.FULL) {
mv.visitCode();
InstructionAdapter iv = new InstructionAdapter(mv);
@@ -482,8 +491,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
int flags = ACC_PUBLIC; // TODO
final MethodVisitor mv = v.newMethod(myClass, flags, constructorMethod.getName(), constructorMethod.getAsmMethod().getDescriptor(), constructorMethod.getGenericsSignature(), null);
- if (!v.generateCode()) return;
-
+ if (v.generateCode() == ClassBuilder.Mode.SIGNATURES) return;
+
AnnotationVisitor jetConstructorVisitor = mv.visitAnnotation(JvmStdlibNames.JET_CONSTRUCTOR.getDescriptor(), true);
if (constructorDescriptor == null) {
jetConstructorVisitor.visit(JvmStdlibNames.JET_CONSTRUCTOR_HIDDEN_FIELD, true);
@@ -509,6 +518,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
}
+ if (v.generateCode() == ClassBuilder.Mode.STUBS) {
+ StubCodegen.generateStubCode(mv);
+ return;
+ }
+
mv.visitCode();
List paramDescrs = constructorDescriptor != null
@@ -678,7 +692,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
Method functionOriginal = typeMapper.mapSignature(fun.getName(), fun.getOriginal()).getAsmMethod();
final MethodVisitor mv = v.newMethod(myClass, flags, function.getName(), function.getDescriptor(), null, null);
- if (v.generateCode()) {
+ if (v.generateCode() == ClassBuilder.Mode.STUBS) {
+ StubCodegen.generateStubCode(mv);
+ }
+ else if (v.generateCode() == ClassBuilder.Mode.FULL) {
mv.visitCode();
codegen.generateThisOrOuter(descriptor);
@@ -813,7 +830,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
CallableMethod method = typeMapper.mapToCallableMethod(constructorDescriptor, kind, typeMapper.hasThis0(constructorDescriptor.getContainingDeclaration()));
int flags = ACC_PUBLIC; // TODO
final MethodVisitor mv = v.newMethod(constructor, flags, "", method.getSignature().getAsmMethod().getDescriptor(), null, null);
- if (v.generateCode()) {
+ if (v.generateCode() == ClassBuilder.Mode.STUBS) {
+ StubCodegen.generateStubCode(mv);
+ }
+ else if (v.generateCode() == ClassBuilder.Mode.FULL) {
mv.visitCode();
ConstructorFrameMap frameMap = new ConstructorFrameMap(method, constructorDescriptor, typeMapper.hasThis0(constructorDescriptor.getContainingDeclaration()));
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java
index d417ad19eb5..6f1c1c255c1 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java
@@ -89,7 +89,7 @@ public class NamespaceCodegen {
private void generateStaticInitializers(JetFile namespace) {
MethodVisitor mv = v.newMethod(namespace, ACC_PUBLIC | ACC_STATIC, "", "()V", null, null);
- if (v.generateCode()) {
+ if (v.generateCode() == ClassBuilder.Mode.FULL) {
mv.visitCode();
FrameMap frameMap = new FrameMap();
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java
index 5710b95ee5e..375fbca4fd3 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java
@@ -169,24 +169,28 @@ public class PropertyCodegen {
AnnotationCodegen.forMethod(mv).genAnnotations(propertyDescriptor.getGetter(), state.getTypeMapper());
}
- if (v.generateCode() && (!isTrait || kind instanceof OwnerKind.DelegateKind)) {
+ if (v.generateCode() != ClassBuilder.Mode.SIGNATURES && (!isTrait || kind instanceof OwnerKind.DelegateKind)) {
mv.visitCode();
- InstructionAdapter iv = new InstructionAdapter(mv);
- if (kind != OwnerKind.NAMESPACE) {
- iv.load(0, JetTypeMapper.TYPE_OBJECT);
+ if (v.generateCode() == ClassBuilder.Mode.STUBS) {
+ StubCodegen.generateStubThrow(mv);
+ } else {
+ InstructionAdapter iv = new InstructionAdapter(mv);
+ if (kind != OwnerKind.NAMESPACE) {
+ iv.load(0, JetTypeMapper.TYPE_OBJECT);
+ }
+ final Type type = state.getTypeMapper().mapType(propertyDescriptor.getType());
+ if (kind instanceof OwnerKind.DelegateKind) {
+ OwnerKind.DelegateKind dk = (OwnerKind.DelegateKind) kind;
+ dk.getDelegate().put(JetTypeMapper.TYPE_OBJECT, iv);
+ iv.invokeinterface(dk.getOwnerClass(), getterName, descriptor);
+ }
+ else {
+ iv.visitFieldInsn(kind == OwnerKind.NAMESPACE ? Opcodes.GETSTATIC : Opcodes.GETFIELD,
+ state.getTypeMapper().getOwner(propertyDescriptor, kind), propertyDescriptor.getName(),
+ type.getDescriptor());
+ }
+ iv.areturn(type);
}
- final Type type = state.getTypeMapper().mapType(propertyDescriptor.getType());
- if (kind instanceof OwnerKind.DelegateKind) {
- OwnerKind.DelegateKind dk = (OwnerKind.DelegateKind) kind;
- dk.getDelegate().put(JetTypeMapper.TYPE_OBJECT, iv);
- iv.invokeinterface(dk.getOwnerClass(), getterName, descriptor);
- }
- else {
- iv.visitFieldInsn(kind == OwnerKind.NAMESPACE ? Opcodes.GETSTATIC : Opcodes.GETFIELD,
- state.getTypeMapper().getOwner(propertyDescriptor, kind), propertyDescriptor.getName(),
- type.getDescriptor());
- }
- iv.areturn(type);
FunctionCodegen.endVisit(mv, "getter", origin);
}
}
@@ -233,32 +237,36 @@ public class PropertyCodegen {
AnnotationCodegen.forMethod(mv).genAnnotations(propertyDescriptor.getSetter(), state.getTypeMapper());
}
- if (v.generateCode() && (!isTrait || kind instanceof OwnerKind.DelegateKind)) {
+ if (v.generateCode() != ClassBuilder.Mode.SIGNATURES && (!isTrait || kind instanceof OwnerKind.DelegateKind)) {
mv.visitCode();
- InstructionAdapter iv = new InstructionAdapter(mv);
- final Type type = state.getTypeMapper().mapType(propertyDescriptor.getType());
- int paramCode = 0;
- if (kind != OwnerKind.NAMESPACE) {
- iv.load(0, JetTypeMapper.TYPE_OBJECT);
- paramCode = 1;
- }
+ if (v.generateCode() == ClassBuilder.Mode.STUBS) {
+ StubCodegen.generateStubThrow(mv);
+ } else {
+ InstructionAdapter iv = new InstructionAdapter(mv);
+ final Type type = state.getTypeMapper().mapType(propertyDescriptor.getType());
+ int paramCode = 0;
+ if (kind != OwnerKind.NAMESPACE) {
+ iv.load(0, JetTypeMapper.TYPE_OBJECT);
+ paramCode = 1;
+ }
- if (kind instanceof OwnerKind.DelegateKind) {
- OwnerKind.DelegateKind dk = (OwnerKind.DelegateKind) kind;
- iv.load(0, JetTypeMapper.TYPE_OBJECT);
- dk.getDelegate().put(JetTypeMapper.TYPE_OBJECT, iv);
+ if (kind instanceof OwnerKind.DelegateKind) {
+ OwnerKind.DelegateKind dk = (OwnerKind.DelegateKind) kind;
+ iv.load(0, JetTypeMapper.TYPE_OBJECT);
+ dk.getDelegate().put(JetTypeMapper.TYPE_OBJECT, iv);
- iv.load(paramCode, type);
- iv.invokeinterface(dk.getOwnerClass(), setterName(propertyDescriptor.getName()), descriptor);
- }
- else {
- iv.load(paramCode, type);
- iv.visitFieldInsn(kind == OwnerKind.NAMESPACE ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD,
- state.getTypeMapper().getOwner(propertyDescriptor, kind), propertyDescriptor.getName(),
- type.getDescriptor());
- }
+ iv.load(paramCode, type);
+ iv.invokeinterface(dk.getOwnerClass(), setterName(propertyDescriptor.getName()), descriptor);
+ }
+ else {
+ iv.load(paramCode, type);
+ iv.visitFieldInsn(kind == OwnerKind.NAMESPACE ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD,
+ state.getTypeMapper().getOwner(propertyDescriptor, kind), propertyDescriptor.getName(),
+ type.getDescriptor());
+ }
- iv.visitInsn(Opcodes.RETURN);
+ iv.visitInsn(Opcodes.RETURN);
+ }
FunctionCodegen.endVisit(mv, "setter", origin);
mv.visitEnd();
}
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/StubCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/StubCodegen.java
new file mode 100644
index 00000000000..d6a1ac94f95
--- /dev/null
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/StubCodegen.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.codegen;
+
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.commons.InstructionAdapter;
+
+/**
+ * @author Stepan Koltsov
+ */
+public class StubCodegen {
+ public static void generateStubThrow(MethodVisitor mv) {
+ new InstructionAdapter(mv).anew(Type.getObjectType("java/lang/RuntimeException"));
+ new InstructionAdapter(mv).dup();
+ new InstructionAdapter(mv).aconst("Stubs are for compiler only, do not add them to runtime classpath");
+ new InstructionAdapter(mv).invokespecial("java/lang/RuntimeException", "", "(Ljava/lang/String;)V");
+ new InstructionAdapter(mv).athrow();
+ }
+
+ public static void generateStubCode(MethodVisitor mv) {
+ mv.visitCode();
+ generateStubThrow(mv);
+ mv.visitMaxs(-1, -1);
+ mv.visitEnd();
+ }
+}
diff --git a/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java
index 7c550694bb6..62d0e459c6b 100644
--- a/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java
+++ b/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java
@@ -69,8 +69,8 @@ public class KotlinCompiler {
@Argument(value = "help", alias = "h", description = "show help")
public boolean help;
- @Argument(value = "ignoreErrors", description = "Emit byte code even if there are compilation errors (not recommended)")
- public boolean ignoreErrors;
+ @Argument(value = "stubs", description = "Compile stubs: ignore function bodies")
+ public boolean stubs;
@Argument(value = "transformNamesToJava", description = "Transform Kotlin file names to *.java. This option is needed for compiling kotlinized Java library headers")
public boolean transformNamesToJava;
@@ -119,14 +119,10 @@ public class KotlinCompiler {
CompileEnvironment environment = new CompileEnvironment(arguments.transformNamesToJava ? ANY_EXTENSION_TO_JAVA : FileNameTransformer.IDENTITY);
try {
- environment.setIgnoreErrors(arguments.ignoreErrors);
- if (arguments.ignoreErrors) {
- // To avoid outputting error messages
- environment.setErrorStream(new PrintStream(new ByteArrayOutputStream()));
- }
- else {
- environment.setErrorStream(errStream);
- }
+ environment.setIgnoreErrors(false);
+ environment.setErrorStream(errStream);
+
+ environment.setStubs(arguments.stubs);
if (arguments.docOutputDir != null) {
KDocLoader factory = new KDocLoader(arguments.docOutputDir);
diff --git a/compiler/cli/src/org/jetbrains/jet/compiler/CompileEnvironment.java b/compiler/cli/src/org/jetbrains/jet/compiler/CompileEnvironment.java
index 95ba252fc8d..a1dd8251b17 100644
--- a/compiler/cli/src/org/jetbrains/jet/compiler/CompileEnvironment.java
+++ b/compiler/cli/src/org/jetbrains/jet/compiler/CompileEnvironment.java
@@ -60,6 +60,7 @@ public class CompileEnvironment {
private URL myStdlib;
private boolean ignoreErrors = false;
+ private boolean stubs = false;
public CompileEnvironment() {
this(FileNameTransformer.IDENTITY);
@@ -83,6 +84,10 @@ public class CompileEnvironment {
this.ignoreErrors = ignoreErrors;
}
+ public void setStubs(boolean stubs) {
+ this.stubs = stubs;
+ }
+
public void dispose() {
Disposer.dispose(myRootDisposable);
}
@@ -229,6 +234,7 @@ public class CompileEnvironment {
public ClassFileFactory compileModule(Module moduleBuilder, String directory) {
CompileSession moduleCompileSession = new CompileSession(myEnvironment);
+ moduleCompileSession.setStubs(stubs);
if (moduleBuilder.getSourceFiles().isEmpty()) {
throw new CompileEnvironmentException("No source files where defined");
@@ -349,6 +355,8 @@ public class CompileEnvironment {
public boolean compileBunchOfSources(String sourceFileOrDir, String jar, String outputDir, boolean includeRuntime) {
CompileSession session = new CompileSession(myEnvironment, myFileNameTransformer);
+ session.setStubs(stubs);
+
session.addSources(sourceFileOrDir);
String mainClass = null;
diff --git a/compiler/cli/src/org/jetbrains/jet/compiler/CompileSession.java b/compiler/cli/src/org/jetbrains/jet/compiler/CompileSession.java
index 804730b40f6..641376b40b4 100644
--- a/compiler/cli/src/org/jetbrains/jet/compiler/CompileSession.java
+++ b/compiler/cli/src/org/jetbrains/jet/compiler/CompileSession.java
@@ -16,6 +16,7 @@
package org.jetbrains.jet.compiler;
+import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
@@ -56,6 +57,7 @@ public class CompileSession {
private final List mySourceFiles = new ArrayList();
private final FileNameTransformer myFileNameTransformer;
private List myErrors = new ArrayList();
+ private boolean stubs = false;
public BindingContext getMyBindingContext() {
return myBindingContext;
@@ -71,7 +73,11 @@ public class CompileSession {
myEnvironment = environment;
myFileNameTransformer = fileNameTransformer;
}
-
+
+ public void setStubs(boolean stubs) {
+ this.stubs = stubs;
+ }
+
public void addSources(String path) {
if(path == null)
return;
@@ -172,8 +178,10 @@ public class CompileSession {
}
private void analyzeAndReportSemanticErrors(ErrorCollector errorCollector) {
+ Predicate filesToAnalyzeCompletely =
+ stubs ? Predicates.alwaysFalse() : Predicates.alwaysTrue();
myBindingContext = AnalyzerFacade.analyzeFilesWithJavaIntegration(
- myEnvironment.getProject(), mySourceFiles, Predicates.alwaysTrue(), JetControlFlowDataTraceFactory.EMPTY);
+ myEnvironment.getProject(), mySourceFiles, filesToAnalyzeCompletely, JetControlFlowDataTraceFactory.EMPTY);
for (Diagnostic diagnostic : myBindingContext.getDiagnostics()) {
errorCollector.report(diagnostic);
@@ -197,7 +205,7 @@ public class CompileSession {
@NotNull
public ClassFileFactory generate() {
Project project = myEnvironment.getProject();
- GenerationState generationState = new GenerationState(project, ClassBuilderFactory.BINARIES, myFileNameTransformer);
+ GenerationState generationState = new GenerationState(project, ClassBuilderFactories.binaries(stubs), myFileNameTransformer);
generationState.compileCorrectFiles(myBindingContext, mySourceFiles, CompilationErrorHandler.THROW_EXCEPTION, true);
ClassFileFactory answer = generationState.getFactory();
diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/StubClassBuilder.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/StubClassBuilder.java
index 7360c136ffa..3939934acdd 100644
--- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/StubClassBuilder.java
+++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/StubClassBuilder.java
@@ -109,7 +109,7 @@ public class StubClassBuilder extends ClassBuilder {
}
@Override
- public boolean generateCode() {
- return false;
+ public Mode generateCode() {
+ return Mode.SIGNATURES;
}
}
diff --git a/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java b/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java
index 73b78acc40c..9fefc9e5cc5 100644
--- a/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java
+++ b/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java
@@ -116,7 +116,7 @@ public abstract class CodegenTestCase extends JetLiteFixture {
}
protected String generateToText() {
- GenerationState state = new GenerationState(getProject(), ClassBuilderFactory.TEXT);
+ GenerationState state = new GenerationState(getProject(), ClassBuilderFactories.TEXT);
AnalyzingUtils.checkForSyntacticErrors(myFile);
state.compile(myFile);
@@ -159,7 +159,7 @@ public abstract class CodegenTestCase extends JetLiteFixture {
@NotNull
protected ClassFileFactory generateClassesInFile() {
try {
- GenerationState state = new GenerationState(getProject(), ClassBuilderFactory.BINARIES);
+ GenerationState state = new GenerationState(getProject(), ClassBuilderFactories.binaries(false));
AnalyzingUtils.checkForSyntacticErrors(myFile);
state.compile(myFile);
diff --git a/compiler/tests/org/jetbrains/jet/compiler/CompileJavaAgainstKotlinTest.java b/compiler/tests/org/jetbrains/jet/compiler/CompileJavaAgainstKotlinTest.java
index 64d036a7693..1f911cd1e9d 100644
--- a/compiler/tests/org/jetbrains/jet/compiler/CompileJavaAgainstKotlinTest.java
+++ b/compiler/tests/org/jetbrains/jet/compiler/CompileJavaAgainstKotlinTest.java
@@ -26,7 +26,7 @@ import junit.framework.Test;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.JetTestCaseBuilder;
import org.jetbrains.jet.JetTestUtils;
-import org.jetbrains.jet.codegen.ClassBuilderFactory;
+import org.jetbrains.jet.codegen.ClassBuilderFactories;
import org.jetbrains.jet.codegen.ClassFileFactory;
import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.lang.psi.JetFile;
@@ -78,7 +78,7 @@ public class CompileJavaAgainstKotlinTest extends TestCaseWithTmpdir {
virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET);
JetFile psiFile = (JetFile) ((PsiFileFactoryImpl) PsiFileFactory.getInstance(jetCoreEnvironment.getProject())).trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false);
- GenerationState state = new GenerationState(jetCoreEnvironment.getProject(), ClassBuilderFactory.BINARIES);
+ GenerationState state = new GenerationState(jetCoreEnvironment.getProject(), ClassBuilderFactories.binaries(false));
AnalyzingUtils.checkForSyntacticErrors(psiFile);
state.compile(psiFile);
diff --git a/compiler/tests/org/jetbrains/jet/compiler/CompileKotlinAgainstKotlinTest.java b/compiler/tests/org/jetbrains/jet/compiler/CompileKotlinAgainstKotlinTest.java
index d2d955d41e1..0b3e3ef1af6 100644
--- a/compiler/tests/org/jetbrains/jet/compiler/CompileKotlinAgainstKotlinTest.java
+++ b/compiler/tests/org/jetbrains/jet/compiler/CompileKotlinAgainstKotlinTest.java
@@ -27,6 +27,7 @@ import junit.framework.Test;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.JetTestCaseBuilder;
import org.jetbrains.jet.JetTestUtils;
+import org.jetbrains.jet.codegen.ClassBuilderFactories;
import org.jetbrains.jet.codegen.ClassBuilderFactory;
import org.jetbrains.jet.codegen.ClassFileFactory;
import org.jetbrains.jet.codegen.GenerationState;
@@ -92,7 +93,7 @@ public class CompileKotlinAgainstKotlinTest extends TestCaseWithTmpdir {
virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET);
JetFile psiFile = (JetFile) ((PsiFileFactoryImpl) PsiFileFactory.getInstance(jetCoreEnvironment.getProject())).trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false);
- GenerationState state = new GenerationState(jetCoreEnvironment.getProject(), ClassBuilderFactory.BINARIES);
+ GenerationState state = new GenerationState(jetCoreEnvironment.getProject(), ClassBuilderFactories.binaries(false));
AnalyzingUtils.checkForSyntacticErrors(psiFile);
state.compile(psiFile);
@@ -115,7 +116,7 @@ public class CompileKotlinAgainstKotlinTest extends TestCaseWithTmpdir {
virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET);
JetFile psiFile = (JetFile) ((PsiFileFactoryImpl) PsiFileFactory.getInstance(jetCoreEnvironment.getProject())).trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false);
- GenerationState state = new GenerationState(jetCoreEnvironment.getProject(), ClassBuilderFactory.BINARIES);
+ GenerationState state = new GenerationState(jetCoreEnvironment.getProject(), ClassBuilderFactories.binaries(false));
AnalyzingUtils.checkForSyntacticErrors(psiFile);
state.compile(psiFile);
diff --git a/compiler/tests/org/jetbrains/jet/compiler/ReadKotlinBinaryClassTest.java b/compiler/tests/org/jetbrains/jet/compiler/ReadKotlinBinaryClassTest.java
index 9f6180041bd..39b3fc5668a 100644
--- a/compiler/tests/org/jetbrains/jet/compiler/ReadKotlinBinaryClassTest.java
+++ b/compiler/tests/org/jetbrains/jet/compiler/ReadKotlinBinaryClassTest.java
@@ -26,7 +26,7 @@ import junit.framework.Test;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.JetTestCaseBuilder;
import org.jetbrains.jet.JetTestUtils;
-import org.jetbrains.jet.codegen.ClassBuilderFactory;
+import org.jetbrains.jet.codegen.ClassBuilderFactories;
import org.jetbrains.jet.codegen.ClassFileFactory;
import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.lang.JetSemanticServices;
@@ -70,7 +70,7 @@ public class ReadKotlinBinaryClassTest extends TestCaseWithTmpdir {
virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET);
JetFile psiFile = (JetFile) ((PsiFileFactoryImpl) PsiFileFactory.getInstance(jetCoreEnvironment.getProject())).trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false);
- GenerationState state = new GenerationState(jetCoreEnvironment.getProject(), ClassBuilderFactory.BINARIES);
+ GenerationState state = new GenerationState(jetCoreEnvironment.getProject(), ClassBuilderFactories.binaries(false));
AnalyzingUtils.checkForSyntacticErrors(psiFile);
BindingContext bindingContext = state.compile(psiFile);
diff --git a/compiler/tests/org/jetbrains/jet/compiler/WriteSignatureTest.java b/compiler/tests/org/jetbrains/jet/compiler/WriteSignatureTest.java
index 26ca9910cf6..d943b1a9eec 100644
--- a/compiler/tests/org/jetbrains/jet/compiler/WriteSignatureTest.java
+++ b/compiler/tests/org/jetbrains/jet/compiler/WriteSignatureTest.java
@@ -29,6 +29,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.JetTestCaseBuilder;
import org.jetbrains.jet.JetTestUtils;
+import org.jetbrains.jet.codegen.ClassBuilderFactories;
import org.jetbrains.jet.codegen.ClassBuilderFactory;
import org.jetbrains.jet.codegen.ClassFileFactory;
import org.jetbrains.jet.codegen.GenerationState;
@@ -83,7 +84,7 @@ public class WriteSignatureTest extends TestCaseWithTmpdir {
virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET);
JetFile psiFile = (JetFile) ((PsiFileFactoryImpl) PsiFileFactory.getInstance(jetCoreEnvironment.getProject())).trySetupPsiForFile(virtualFile, JetLanguage.INSTANCE, true, false);
- GenerationState state = new GenerationState(jetCoreEnvironment.getProject(), ClassBuilderFactory.BINARIES);
+ GenerationState state = new GenerationState(jetCoreEnvironment.getProject(), ClassBuilderFactories.binaries(false));
AnalyzingUtils.checkForSyntacticErrors(psiFile);
state.compile(psiFile);
diff --git a/idea/src/org/jetbrains/jet/plugin/internal/codewindow/BytecodeToolwindow.java b/idea/src/org/jetbrains/jet/plugin/internal/codewindow/BytecodeToolwindow.java
index 2c5fdaf5244..7995caf3c78 100644
--- a/idea/src/org/jetbrains/jet/plugin/internal/codewindow/BytecodeToolwindow.java
+++ b/idea/src/org/jetbrains/jet/plugin/internal/codewindow/BytecodeToolwindow.java
@@ -36,6 +36,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.util.Alarm;
+import org.jetbrains.jet.codegen.ClassBuilderFactories;
import org.jetbrains.jet.codegen.ClassBuilderFactory;
import org.jetbrains.jet.codegen.ClassFileFactory;
import org.jetbrains.jet.codegen.CompilationErrorHandler;
@@ -200,7 +201,7 @@ public class BytecodeToolwindow extends JPanel implements Disposable {
}
protected String generateToText(JetFile file) {
- GenerationState state = new GenerationState(myProject, ClassBuilderFactory.TEXT);
+ GenerationState state = new GenerationState(myProject, ClassBuilderFactories.TEXT);
try {
BindingContext binding = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(file);
AnalyzingUtils.throwExceptionOnErrors(binding);
diff --git a/jdk-headers/src/java/util/AbstractCollection.kt b/jdk-headers/src/java/util/AbstractCollection.kt
index 8c84b380549..6b9b8100d3c 100644
--- a/jdk-headers/src/java/util/AbstractCollection.kt
+++ b/jdk-headers/src/java/util/AbstractCollection.kt
@@ -1,5 +1,5 @@
package java.util
-abstract public open class AbstractCollection protected () : java.util.Collection {
+abstract public open class AbstractCollection protected () : java.lang.Object(), java.util.Collection {
abstract override public fun iterator() : java.util.Iterator
abstract override public fun size() : Int
override public fun isEmpty() : Boolean {}
@@ -14,4 +14,4 @@ abstract public open class AbstractCollection protected () : java.util
override public fun retainAll(c : java.util.Collection<*>) : Boolean {}
override public fun clear() : Unit {}
//override public fun toString() : java.lang.String {}
-}
\ No newline at end of file
+}
diff --git a/jdk-headers/src/java/util/AbstractMap.kt b/jdk-headers/src/java/util/AbstractMap.kt
index 5ff3e33ce63..4bc7a494184 100644
--- a/jdk-headers/src/java/util/AbstractMap.kt
+++ b/jdk-headers/src/java/util/AbstractMap.kt
@@ -1,6 +1,6 @@
package java.util
-abstract public open class AbstractMap protected () : java.util.Map {
+abstract public open class AbstractMap protected () : java.lang.Object(), java.util.Map {
override public fun size() : Int {}
override public fun isEmpty() : Boolean {}
override public fun containsValue(value : Any?) : Boolean {}
@@ -16,4 +16,4 @@ abstract public open class AbstractMap protected () : java.u
//override public fun equals(o : Any?) : Boolean
//override public fun hashCode() : Int
//override public fun toString() : java.lang.String?
-}
\ No newline at end of file
+}
diff --git a/jdk-headers/src/java/util/ArrayList.kt b/jdk-headers/src/java/util/ArrayList.kt
index 5c4c1e8ddb4..288168f5142 100644
--- a/jdk-headers/src/java/util/ArrayList.kt
+++ b/jdk-headers/src/java/util/ArrayList.kt
@@ -34,4 +34,4 @@ public open class ArrayList(c : java.util.Collection) : java.ut
// return __
// }
// }
-}
\ No newline at end of file
+}