Green code.

This commit is contained in:
Evgeny Gerashchenko
2013-06-14 15:01:25 +04:00
parent 9668360df3
commit 63c17bd0b2
4 changed files with 59 additions and 51 deletions
@@ -178,8 +178,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
return new InstructionAdapter(methodVisitor) {
@Override
public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
super.visitLocalVariable(name, desc, signature, start, end,
index);
super.visitLocalVariable(name, desc, signature, start, end, index);
localVariableNames.add(name);
}
};
@@ -195,7 +194,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
if (provided instanceof CallableDescriptor) {
provided = ((CallableDescriptor) provided).getReceiverParameter().getType().getConstructor().getDeclarationDescriptor();
ReceiverParameterDescriptor receiverParameter = ((CallableDescriptor) provided).getReceiverParameter();
assert receiverParameter != null : receiverParameter;
provided = receiverParameter.getType().getConstructor().getDeclarationDescriptor();
}
assert provided instanceof ClassDescriptor;
@@ -318,8 +319,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
return labelTarget;
}
assert descriptor instanceof ClassDescriptor : "Don't know how to generate super-call to not a class";
ClassDescriptor target = getParentContextSubclassOf((ClassDescriptor) descriptor, context).getThisDescriptor();
return target;
return getParentContextSubclassOf((ClassDescriptor) descriptor, context).getThisDescriptor();
}
@NotNull
@@ -1608,7 +1608,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
assert descriptor != null;
DeclarationDescriptor container = descriptor.getContainingDeclaration();
if (descriptor instanceof VariableDescriptor) {
VariableDescriptor variableDescriptor = (VariableDescriptor) descriptor;
@@ -1757,7 +1756,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
JetTypeMapper typeMapper = state.getTypeMapper();
DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration();
assert containingDeclaration != null;
boolean isBackingFieldInAnotherClass = AsmUtil.isPropertyWithBackingFieldInOuterClass(propertyDescriptor);
boolean isStatic = containingDeclaration instanceof NamespaceDescriptor || isBackingFieldInAnotherClass;
@@ -1787,7 +1785,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
if (!skipPropertyAccessors) {
//noinspection ConstantConditions
if (couldUseDirectAccessToProperty(propertyDescriptor, true, isInsideClass, isDelegatedProperty)) {
callableGetter = null;
}
@@ -1803,22 +1800,24 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
propertyDescriptor = accessiblePropertyDescriptor(propertyDescriptor);
if (propertyDescriptor.getGetter() != null) {
callableGetter = typeMapper
.mapToCallableMethod(propertyDescriptor.getGetter(), isSuper || MethodKind.SYNTHETIC_ACCESSOR == methodKind,
isInsideClass, isInsideModule, OwnerKind.IMPLEMENTATION);
PropertyGetterDescriptor getter = propertyDescriptor.getGetter();
if (getter != null) {
callableGetter = typeMapper.mapToCallableMethod(
getter, isSuper || MethodKind.SYNTHETIC_ACCESSOR == methodKind, isInsideClass, isInsideModule,
OwnerKind.IMPLEMENTATION);
}
}
if (propertyDescriptor.isVar()) {
if (propertyDescriptor.getSetter() != null) {
PropertySetterDescriptor setter = propertyDescriptor.getSetter();
if (setter != null) {
if (couldUseDirectAccessToProperty(propertyDescriptor, false, isInsideClass, isDelegatedProperty)) {
callableSetter = null;
}
else {
callableSetter = typeMapper
.mapToCallableMethod(propertyDescriptor.getSetter(), isSuper || MethodKind.SYNTHETIC_ACCESSOR == methodKind,
isInsideClass, isInsideModule, OwnerKind.IMPLEMENTATION);
callableSetter = typeMapper.mapToCallableMethod(
setter, isSuper || MethodKind.SYNTHETIC_ACCESSOR == methodKind, isInsideClass, isInsideModule,
OwnerKind.IMPLEMENTATION);
}
}
}
@@ -2031,8 +2030,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
private static CodegenContext getParentContextSubclassOf(ClassDescriptor descriptor, CodegenContext context) {
CodegenContext c = context;
while (true) {
if ((c instanceof ClassContext || c instanceof AnonymousClassContext) &&
DescriptorUtils.isSubclass(c.getThisDescriptor(), descriptor)) {
if (c instanceof ClassContext && DescriptorUtils.isSubclass(c.getThisDescriptor(), descriptor)) {
return c;
}
c = c.getParentContext();
@@ -2316,6 +2314,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
JetType samAdapterType = originalOfSamAdapter.getValueParameters().get(valueParameter.getIndex()).getType();
if (SingleAbstractMethodUtils.isSamType(samAdapterType)) {
ClassDescriptorFromJvmBytecode samInterface = (ClassDescriptorFromJvmBytecode) samAdapterType.getConstructor().getDeclarationDescriptor();
assert samInterface != null;
genSamInterfaceValue(argumentExpression, samInterface);
continue;
@@ -2443,8 +2442,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
JvmClassName closureSuperClass = JvmClassName.byType(typeMapper.mapType(kFunctionImpl));
ClosureCodegen closureCodegen = new ClosureCodegen(state, expression, functionDescriptor, null, closureSuperClass, context, this,
new FunctionGenerationStrategy.CodegenBased(state, functionDescriptor) {
new FunctionGenerationStrategy.CodegenBased<CallableDescriptor>(state, functionDescriptor) {
@NotNull
@Override
public ExpressionCodegen initializeExpressionCodegen(
JvmMethodSignature signature, MethodContext context, MethodVisitor mv,
@@ -2459,9 +2459,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
@Override
public void doGenerateBody(ExpressionCodegen codegen, JvmMethodSignature signature) {
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
/*
Here we need to put the arguments from our locals to the stack and invoke the referenced method. Since invokation
Here we need to put the arguments from our locals to the stack and invoke the referenced method. Since invocation
of methods is highly dependent on expressions, we create a fake call expression. Then we create a new instance of
ExpressionCodegen and, in order for it to generate code correctly, we save to its 'tempVariables' field every
argument of our fake expression, pointing it to the corresponding index in our locals. This way generation of
@@ -2504,7 +2504,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
Type returnType = codegen.returnType;
if (referencedFunction instanceof ConstructorDescriptor) {
if (returnType.getSort() == Type.ARRAY) {
codegen.generateNewArray(fakeExpression, referencedFunction.getReturnType());
JetType returnJetType = referencedFunction.getReturnType();
assert returnJetType != null;
codegen.generateNewArray(fakeExpression, returnJetType);
result = StackValue.onStack(returnType);
}
else {
@@ -2654,6 +2656,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
else {
DeclarationDescriptor op = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference());
assert op instanceof FunctionDescriptor : String.valueOf(op);
Callable callable = resolveToCallable((FunctionDescriptor) op, false);
if (callable instanceof IntrinsicMethod) {
IntrinsicMethod intrinsic = (IntrinsicMethod) callable;
@@ -2877,6 +2880,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
private StackValue generateAugmentedAssignment(JetBinaryExpression expression) {
DeclarationDescriptor op = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference());
assert op instanceof FunctionDescriptor : String.valueOf(op);
Callable callable = resolveToCallable((FunctionDescriptor) op, false);
JetExpression lhs = expression.getLeft();
@@ -2982,6 +2986,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
DeclarationDescriptor op = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference());
assert op instanceof FunctionDescriptor : String.valueOf(op);
Callable callable = resolveToCallable((FunctionDescriptor) op, false);
if (callable instanceof IntrinsicMethod) {
IntrinsicMethod intrinsic = (IntrinsicMethod) callable;
@@ -29,7 +29,7 @@ import org.jetbrains.jet.lang.psi.JetDeclarationWithBody;
import java.util.ArrayList;
import java.util.Collection;
public abstract class FunctionGenerationStrategy<T extends CallableDescriptor> {
public abstract class FunctionGenerationStrategy {
private final Collection<String> localVariableNames = new ArrayList<String>();
@@ -77,12 +77,12 @@ public abstract class FunctionGenerationStrategy<T extends CallableDescriptor> {
}
@Override
public void doGenerateBody(ExpressionCodegen codegen, JvmMethodSignature signature) {
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
codegen.returnExpression(declaration.getBodyExpression());
}
}
public abstract static class CodegenBased<T extends CallableDescriptor> extends FunctionGenerationStrategy<T> {
public abstract static class CodegenBased<T extends CallableDescriptor> extends FunctionGenerationStrategy {
protected final GenerationState state;
@@ -21,6 +21,7 @@ import com.google.common.collect.Sets;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiElement;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.AnnotationVisitor;
@@ -108,7 +109,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
boolean isAbstract = false;
boolean isInterface = false;
boolean isFinal = false;
boolean isStatic = false;
boolean isStatic;
boolean isAnnotation = false;
boolean isEnum = false;
@@ -196,7 +197,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
signature.getName(),
signature.getJavaGenericSignature(),
signature.getSuperclassName(),
interfaces.toArray(new String[interfaces.size()])
ArrayUtil.toStringArray(interfaces)
);
v.visitSource(myClass.getContainingFile().getName(), null);
@@ -839,7 +840,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
functionCodegen.generateMethod(null, typeMapper.mapSignature(bridge), false, bridge,
new FunctionGenerationStrategy.CodegenBased<FunctionDescriptor>(state, bridge) {
@Override
public void doGenerateBody(ExpressionCodegen codegen, JvmMethodSignature signature) {
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
generateMethodCallTo(original, codegen.v);
codegen.v.areturn(signature.getAsmMethod().getReturnType());
@@ -856,7 +857,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
functionCodegen.generateMethod(null, typeMapper.mapGetterSignature(bridge, OwnerKind.IMPLEMENTATION), false, getter,
new FunctionGenerationStrategy.CodegenBased<PropertyGetterDescriptor>(state, getter) {
@Override
public void doGenerateBody(ExpressionCodegen codegen, JvmMethodSignature signature) {
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
InstructionAdapter iv = codegen.v;
boolean forceField = AsmUtil.isPropertyWithBackingFieldInOuterClass(original) && !isClassObject(bridge.getContainingDeclaration());
StackValue property = codegen.intermediateValueForProperty(original, forceField, null, MethodKind.SYNTHETIC_ACCESSOR);
@@ -876,7 +877,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
functionCodegen.generateMethod(null, typeMapper.mapSetterSignature(bridge, OwnerKind.IMPLEMENTATION), false, setter,
new FunctionGenerationStrategy.CodegenBased<PropertySetterDescriptor>(state, setter) {
@Override
public void doGenerateBody(ExpressionCodegen codegen, JvmMethodSignature signature) {
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
boolean forceField = AsmUtil.isPropertyWithBackingFieldInOuterClass(original) && !isClassObject(bridge.getContainingDeclaration());
StackValue property = codegen.intermediateValueForProperty(original, forceField, null, MethodKind.SYNTHETIC_ACCESSOR);
InstructionAdapter iv = codegen.v;
@@ -941,7 +942,15 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
ClassDescriptor fieldTypeDescriptor = hasClassObject ? descriptor.getClassObjectDescriptor() : descriptor;
assert fieldTypeDescriptor != null;
StackValue.Field field = StackValue.singleton(fieldTypeDescriptor, typeMapper);
JetClassOrObject original = hasClassObject ? ((JetClass) myClass).getClassObject().getObjectDeclaration() : myClass;
JetClassOrObject original;
if (hasClassObject) {
JetClassObject classObject = ((JetClass) myClass).getClassObject();
assert classObject != null : myClass.getText();
original = classObject.getObjectDeclaration();
}
else {
original = myClass;
}
v.newField(original, ACC_PUBLIC | ACC_STATIC | ACC_FINAL, field.name, field.type.getDescriptor(), null, null);
@@ -1018,9 +1027,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
lookupConstructorExpressionsInClosureIfPresent(constructorContext);
}
final JvmMethodSignature constructorSignature = typeMapper.mapConstructorSignature(constructorDescriptor, closure);
assert constructorDescriptor != null;
final JvmMethodSignature constructorSignature = typeMapper.mapConstructorSignature(constructorDescriptor, closure);
functionCodegen.generateMethod(null, constructorSignature, true, constructorDescriptor, constructorContext,
new FunctionGenerationStrategy.CodegenBased<ConstructorDescriptor>(state, constructorDescriptor) {
@@ -1032,7 +1040,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
@Override
public void doGenerateBody(ExpressionCodegen codegen, JvmMethodSignature signature) {
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
generatePrimaryConstructorImpl(callableDescriptor, codegen, closure);
}
}
@@ -1060,7 +1068,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
InstructionAdapter iv = codegen.v;
JvmClassName classname = JvmClassName.byType(classAsmType);
JvmClassName className = JvmClassName.byType(classAsmType);
if (superCall == null) {
genSimpleSuperCall(iv);
@@ -1087,7 +1095,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
if (specifier instanceof JetDelegatorByExpressionSpecifier) {
genCallToDelegatorByExpressionSpecifier(iv, codegen, classAsmType, classname, n++, specifier);
genCallToDelegatorByExpressionSpecifier(iv, codegen, classAsmType, className, n++, specifier);
}
}
@@ -1154,7 +1162,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
InstructionAdapter iv,
ExpressionCodegen codegen,
Type classType,
JvmClassName classname,
JvmClassName className,
int n,
JetDelegationSpecifier specifier
) {
@@ -1185,14 +1193,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
assert superClassDescriptor != null;
Type superTypeAsmType = typeMapper.mapType(superType, JetTypeMapperMode.IMPL);
StackValue field;
if (propertyDescriptor != null &&
!propertyDescriptor.isVar() &&
Boolean.TRUE.equals(bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor))) {
// final property with backing field
field = StackValue.field(typeMapper.mapType(propertyDescriptor.getType()), classname,
field = StackValue.field(typeMapper.mapType(propertyDescriptor.getType()), className,
propertyDescriptor.getName().asString(), false);
}
else {
@@ -1205,7 +1211,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
v.newField(specifier, ACC_PRIVATE|ACC_FINAL|ACC_SYNTHETIC, delegateField, fieldDesc, /*TODO*/null, null);
field = StackValue.field(fieldType, classname, delegateField, false);
field = StackValue.field(fieldType, className, delegateField, false);
field.store(fieldType, iv);
}
@@ -1232,6 +1238,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
constructorContext.lookupInContext(descriptor, null, state, true);
} else if (isLocalNamedFun(descriptor)) {
assert descriptor != null;
MutableClassDescriptor classDescriptor =
(MutableClassDescriptor) constructorContext.getParentContext().getContextDescriptor();
@@ -1494,14 +1501,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
private static int findFirstSuperArgument(CallableMethod method) {
List<JvmMethodParameterSignature> types = method.getSignature().getKotlinParameterTypes();
if (types != null) {
int i = 0;
for (JvmMethodParameterSignature type : types) {
if (type.getKind() == JvmMethodParameterKind.SUPER_CALL_PARAM) {
return i + 1; // because of this
}
i += type.getAsmType().getSize();
int i = 0;
for (JvmMethodParameterSignature type : types) {
if (type.getKind() == JvmMethodParameterKind.SUPER_CALL_PARAM) {
return i + 1; // because of this
}
i += type.getAsmType().getSize();
}
return -1;
}
@@ -1738,7 +1743,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
private List<Pair<CallableMemberDescriptor, CallableMemberDescriptor>> getTraitImplementations(@NotNull ClassDescriptor classDescriptor) {
List<Pair<CallableMemberDescriptor, CallableMemberDescriptor>> r = Lists.newArrayList();
root:
for (DeclarationDescriptor decl : classDescriptor.getDefaultType().getMemberScope().getAllDescriptors()) {
if (!(decl instanceof CallableMemberDescriptor)) {
continue;
@@ -1769,7 +1773,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
continue;
}
assert count == 1 : "Ambiguous overriden declaration: " + callableMemberDescriptor.getName();
assert count == 1 : "Ambiguous overridden declaration: " + callableMemberDescriptor.getName();
Collection<JetType> superTypesOfSuperClass =
@@ -25,7 +25,6 @@ public interface VariableDescriptor extends CallableDescriptor {
JetType getType();
@Override
@SuppressWarnings({"NullableProblems"})
@NotNull
DeclarationDescriptor getContainingDeclaration();