KotlinCompiler -stubs option
* do not fail on errors * do not analyze function bodies * generate "throw new RuntimeException()" in bytecode
This commit is contained in:
@@ -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,"<clinit>", "()V", null, null);
|
||||
if (v.generateCode()) {
|
||||
if (v.generateCode() == ClassBuilder.Mode.FULL) {
|
||||
mv.visitCode();
|
||||
|
||||
InstructionAdapter v = new InstructionAdapter(mv);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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("<init>", Type.VOID_TYPE, argTypes);
|
||||
final MethodVisitor mv = cv.newMethod(fun, ACC_PUBLIC, "<init>", 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);
|
||||
|
||||
|
||||
@@ -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 ? "<init>" : 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();
|
||||
|
||||
@@ -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<ValueParameterDescriptor> 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, "<init>", 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()));
|
||||
|
||||
@@ -89,7 +89,7 @@ public class NamespaceCodegen {
|
||||
|
||||
private void generateStaticInitializers(JetFile namespace) {
|
||||
MethodVisitor mv = v.newMethod(namespace, ACC_PUBLIC | ACC_STATIC, "<clinit>", "()V", null, null);
|
||||
if (v.generateCode()) {
|
||||
if (v.generateCode() == ClassBuilder.Mode.FULL) {
|
||||
mv.visitCode();
|
||||
|
||||
FrameMap frameMap = new FrameMap();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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", "<init>", "(Ljava/lang/String;)V");
|
||||
new InstructionAdapter(mv).athrow();
|
||||
}
|
||||
|
||||
public static void generateStubCode(MethodVisitor mv) {
|
||||
mv.visitCode();
|
||||
generateStubThrow(mv);
|
||||
mv.visitMaxs(-1, -1);
|
||||
mv.visitEnd();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user