diff --git a/.idea/inspectionProfiles/idea_default.xml b/.idea/inspectionProfiles/idea_default.xml
index 6c2f8ad45ac..23bae163cd7 100644
--- a/.idea/inspectionProfiles/idea_default.xml
+++ b/.idea/inspectionProfiles/idea_default.xml
@@ -410,9 +410,6 @@
-
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java
index ef8bff01e48..f6c1e85d8f2 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java
@@ -425,19 +425,178 @@ public class FunctionCodegen {
) {
DeclarationDescriptor contextClass = owner.getContextDescriptor().getContainingDeclaration();
- if (kind != OwnerKind.TRAIT_IMPL) {
- // we don't generate defaults for traits but do for traitImpl
- if (contextClass instanceof ClassDescriptor) {
- PsiElement psiElement = BindingContextUtils.descriptorToDeclaration(state.getBindingContext(), contextClass);
- if (psiElement instanceof JetClass) {
- JetClass element = (JetClass) psiElement;
- if (element.isTrait()) {
- return;
- }
+ if (kind != OwnerKind.TRAIT_IMPL &&
+ contextClass instanceof ClassDescriptor &&
+ ((ClassDescriptor) contextClass).getKind() == ClassKind.TRAIT) {
+ return;
+ }
+
+ boolean needed = isDefaultNeeded(functionDescriptor);
+
+ if (!needed) {
+ return;
+ }
+
+ ReceiverDescriptor receiverParameter = functionDescriptor.getReceiverParameter();
+ boolean hasReceiver = receiverParameter.exists();
+ boolean isStatic = kind == OwnerKind.NAMESPACE || kind instanceof OwnerKind.StaticDelegateKind;
+
+ if (kind == OwnerKind.TRAIT_IMPL) {
+ String correctedDescr = "(" + jvmSignature.getDescriptor().substring(jvmSignature.getDescriptor().indexOf(";") + 1);
+ jvmSignature = new Method(jvmSignature.getName(), correctedDescr);
+ }
+
+ int flags = ACC_PUBLIC | ACC_SYNTHETIC; // TODO.
+
+ JvmClassName ownerInternalName;
+ if (contextClass instanceof NamespaceDescriptor) {
+ ownerInternalName = NamespaceCodegen.getJVMClassNameForKotlinNs(DescriptorUtils.getFQName(contextClass).toSafe());
+ }
+ else {
+ ownerInternalName = JvmClassName.byType(state.getInjector().getJetTypeMapper()
+ .mapType(((ClassDescriptor) contextClass).getDefaultType(),
+ MapTypeMode.IMPL));
+ }
+
+ String descriptor = jvmSignature.getDescriptor().replace(")", "I)");
+ boolean isConstructor = "".equals(jvmSignature.getName());
+ if (!isStatic && !isConstructor) {
+ descriptor = descriptor.replace("(", "(" + ownerInternalName.getDescriptor());
+ }
+ 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 (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
+ StubCodegen.generateStubCode(mv);
+ }
+ else if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
+ generateDefaultImpl(owner, state, jvmSignature, functionDescriptor, kind, receiverParameter, hasReceiver, isStatic,
+ ownerInternalName,
+ isConstructor, mv, iv);
+ }
+ }
+
+ private static void generateDefaultImpl(
+ CodegenContexts.MethodContext owner,
+ GenerationState state,
+ Method jvmSignature,
+ FunctionDescriptor functionDescriptor,
+ OwnerKind kind,
+ ReceiverDescriptor receiverParameter,
+ boolean hasReceiver,
+ boolean aStatic,
+ JvmClassName ownerInternalName,
+ boolean constructor,
+ MethodVisitor mv,
+ InstructionAdapter iv
+ ) {
+ mv.visitCode();
+
+ FrameMap frameMap = owner.prepareFrame(state.getInjector().getJetTypeMapper());
+
+ if (kind instanceof OwnerKind.StaticDelegateKind) {
+ frameMap.leaveTemp(JetTypeMapper.TYPE_OBJECT);
+ }
+
+ ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, jvmSignature.getReturnType(), owner, state);
+
+ int var = 0;
+ if (!aStatic) {
+ var++;
+ }
+
+ Type receiverType;
+ if (hasReceiver) {
+ receiverType = state.getInjector().getJetTypeMapper().mapType(receiverParameter.getType(), MapTypeMode.VALUE);
+ var += receiverType.getSize();
+ }
+ else {
+ receiverType = Type.DOUBLE_TYPE;
+ }
+
+ Type[] argTypes = jvmSignature.getArgumentTypes();
+ List paramDescrs = functionDescriptor.getValueParameters();
+ for (int i = 0; i < paramDescrs.size(); i++) {
+ Type argType = argTypes[i + (hasReceiver ? 1 : 0)];
+ int size = argType.getSize();
+ frameMap.enter(paramDescrs.get(i), argType);
+ var += size;
+ }
+
+ int maskIndex = var;
+
+ var = 0;
+ if (!aStatic) {
+ mv.visitVarInsn(ALOAD, var++);
+ }
+
+ if (hasReceiver) {
+ iv.load(var, receiverType);
+ var += receiverType.getSize();
+ }
+
+ int extra = hasReceiver ? 1 : 0;
+
+ for (int index = 0; index < paramDescrs.size(); index++) {
+ ValueParameterDescriptor parameterDescriptor = paramDescrs.get(index);
+
+ Type t = argTypes[extra + index];
+
+ if (frameMap.getIndex(parameterDescriptor) < 0) {
+ frameMap.enter(parameterDescriptor, t);
+ }
+
+ if (parameterDescriptor.declaresDefaultValue()) {
+ iv.load(maskIndex, Type.INT_TYPE);
+ iv.iconst(1 << index);
+ iv.and(Type.INT_TYPE);
+ Label loadArg = new Label();
+ iv.ifeq(loadArg);
+
+ JetParameter jetParameter =
+ (JetParameter) BindingContextUtils.descriptorToDeclaration(state.getBindingContext(), parameterDescriptor);
+ assert jetParameter != null;
+ codegen.gen(jetParameter.getDefaultValue(), t);
+
+ int ind = frameMap.getIndex(parameterDescriptor);
+ iv.store(ind, t);
+
+ iv.mark(loadArg);
+ }
+
+ iv.load(var, t);
+ var += t.getSize();
+ }
+
+ final String internalName = ownerInternalName.getInternalName();
+ final String jvmSignatureName = jvmSignature.getName();
+ final String jvmSignatureDescriptor = jvmSignature.getDescriptor();
+ if (!aStatic) {
+ if (kind == OwnerKind.TRAIT_IMPL) {
+ iv.invokeinterface(internalName, jvmSignatureName, jvmSignatureDescriptor);
+ }
+ else {
+ if (!constructor) {
+ iv.invokevirtual(internalName, jvmSignatureName, jvmSignatureDescriptor);
+ }
+ else {
+ iv.invokespecial(internalName, jvmSignatureName, jvmSignatureDescriptor);
}
}
}
+ else {
+ iv.invokestatic(internalName, jvmSignatureName, jvmSignatureDescriptor);
+ }
+ iv.areturn(jvmSignature.getReturnType());
+
+ endVisit(mv, "default method",
+ BindingContextUtils.callableDescriptorToDeclaration(state.getBindingContext(), functionDescriptor));
+ mv.visitEnd();
+ }
+
+ private static boolean isDefaultNeeded(FunctionDescriptor functionDescriptor) {
boolean needed = false;
if (functionDescriptor != null) {
for (ValueParameterDescriptor parameterDescriptor : functionDescriptor.getValueParameters()) {
@@ -447,144 +606,7 @@ public class FunctionCodegen {
}
}
}
-
- if (needed) {
- ReceiverDescriptor receiverParameter = functionDescriptor.getReceiverParameter();
- boolean hasReceiver = receiverParameter.exists();
- boolean isStatic = kind == OwnerKind.NAMESPACE || kind instanceof OwnerKind.StaticDelegateKind;
-
- if (kind == OwnerKind.TRAIT_IMPL) {
- String correctedDescr = "(" + jvmSignature.getDescriptor().substring(jvmSignature.getDescriptor().indexOf(";") + 1);
- jvmSignature = new Method(jvmSignature.getName(), correctedDescr);
- }
-
- int flags = ACC_PUBLIC | ACC_SYNTHETIC; // TODO.
-
- JvmClassName ownerInternalName;
- if (contextClass instanceof NamespaceDescriptor) {
- ownerInternalName = NamespaceCodegen.getJVMClassNameForKotlinNs(DescriptorUtils.getFQName(contextClass).toSafe());
- }
- else {
- ownerInternalName = JvmClassName.byType(state.getInjector().getJetTypeMapper()
- .mapType(((ClassDescriptor) contextClass).getDefaultType(),
- MapTypeMode.IMPL));
- }
-
- String descriptor = jvmSignature.getDescriptor().replace(")", "I)");
- boolean isConstructor = "".equals(jvmSignature.getName());
- if (!isStatic && !isConstructor) {
- descriptor = descriptor.replace("(", "(" + ownerInternalName.getDescriptor());
- }
- 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 (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
- StubCodegen.generateStubCode(mv);
- }
- else if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
- mv.visitCode();
-
- FrameMap frameMap = owner.prepareFrame(state.getInjector().getJetTypeMapper());
-
- if (kind instanceof OwnerKind.StaticDelegateKind) {
- frameMap.leaveTemp(JetTypeMapper.TYPE_OBJECT);
- }
-
- ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, jvmSignature.getReturnType(), owner, state);
-
- int var = 0;
- if (!isStatic) {
- var++;
- }
-
- Type receiverType;
- if (hasReceiver) {
- receiverType = state.getInjector().getJetTypeMapper().mapType(receiverParameter.getType(), MapTypeMode.VALUE);
- var += receiverType.getSize();
- }
- else {
- receiverType = Type.DOUBLE_TYPE;
- }
-
- Type[] argTypes = jvmSignature.getArgumentTypes();
- List paramDescrs = functionDescriptor.getValueParameters();
- for (int i = 0; i < paramDescrs.size(); i++) {
- Type argType = argTypes[i + (hasReceiver ? 1 : 0)];
- int size = argType.getSize();
- frameMap.enter(paramDescrs.get(i), argType);
- var += size;
- }
-
- int maskIndex = var;
-
- var = 0;
- if (!isStatic) {
- mv.visitVarInsn(ALOAD, var++);
- }
-
- if (hasReceiver) {
- iv.load(var, receiverType);
- var += receiverType.getSize();
- }
-
- int extra = hasReceiver ? 1 : 0;
-
- for (int index = 0; index < paramDescrs.size(); index++) {
- ValueParameterDescriptor parameterDescriptor = paramDescrs.get(index);
-
- Type t = argTypes[extra + index];
-
- if (frameMap.getIndex(parameterDescriptor) < 0) {
- frameMap.enter(parameterDescriptor, t);
- }
-
- if (parameterDescriptor.declaresDefaultValue()) {
- iv.load(maskIndex, Type.INT_TYPE);
- iv.iconst(1 << index);
- iv.and(Type.INT_TYPE);
- Label loadArg = new Label();
- iv.ifeq(loadArg);
-
- JetParameter jetParameter =
- (JetParameter) BindingContextUtils.descriptorToDeclaration(state.getBindingContext(), parameterDescriptor);
- assert jetParameter != null;
- codegen.gen(jetParameter.getDefaultValue(), t);
-
- int ind = frameMap.getIndex(parameterDescriptor);
- iv.store(ind, t);
-
- iv.mark(loadArg);
- }
-
- iv.load(var, t);
- var += t.getSize();
- }
-
- if (!isStatic) {
- if (kind == OwnerKind.TRAIT_IMPL) {
- iv.invokeinterface(ownerInternalName.getInternalName(), jvmSignature.getName(), jvmSignature.getDescriptor());
- }
- else {
- if (!isConstructor) {
- iv.invokevirtual(ownerInternalName.getInternalName(), jvmSignature.getName(), jvmSignature.getDescriptor());
- }
- else {
- iv.invokespecial(ownerInternalName.getInternalName(), jvmSignature.getName(), jvmSignature.getDescriptor());
- }
- }
- }
- else {
- iv.invokestatic(ownerInternalName.getInternalName(), jvmSignature.getName(), jvmSignature.getDescriptor());
- }
-
- iv.areturn(jvmSignature.getReturnType());
-
- endVisit(mv, "default method",
- BindingContextUtils.callableDescriptorToDeclaration(state.getBindingContext(), functionDescriptor));
- mv.visitEnd();
- }
- }
+ return needed;
}
private static boolean differentMethods(Method method, Method overridden) {