Do not map generic signature if it's unnecessary

This commit is contained in:
Denis Zharkov
2016-02-23 18:55:52 +03:00
parent 5690d58fd0
commit d66b9a08dd
20 changed files with 392 additions and 175 deletions
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.codegen.binding.CalculatedClosure;
import org.jetbrains.kotlin.codegen.context.ClosureContext;
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil;
import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension;
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter;
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
@@ -131,7 +132,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
@Override
protected void generateDeclaration() {
BothSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.CLASS);
JvmSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.CLASS);
if (samType != null) {
typeMapper.writeFormalTypeParameters(samType.getType().getConstructor().getParameters(), sw);
}
@@ -177,8 +178,8 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
}
generateBridge(
typeMapper.mapSignature(erasedInterfaceFunction).getAsmMethod(),
typeMapper.mapSignature(funDescriptor).getAsmMethod()
typeMapper.mapAsmMethod(erasedInterfaceFunction),
typeMapper.mapAsmMethod(funDescriptor)
);
functionCodegen.generateMethod(JvmDeclarationOriginKt.OtherOrigin(element, funDescriptor), funDescriptor, strategy);
@@ -334,7 +335,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
if (generateBody) {
mv.visitCode();
InstructionAdapter iv = new InstructionAdapter(mv);
Method method = typeMapper.mapSignature(descriptor.getOriginal()).getAsmMethod();
Method method = typeMapper.mapAsmMethod(descriptor.getOriginal());
iv.aconst(method.getName() + method.getDescriptor());
iv.areturn(JAVA_STRING_TYPE);
FunctionCodegen.endVisit(iv, "function reference getSignature", element);
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.resolve.OverrideResolver
import org.jetbrains.kotlin.resolve.OverridingStrategy
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
@@ -239,7 +240,7 @@ class CollectionStubMethodGenerator(
return KotlinTypeImpl.create(Annotations.EMPTY, classDescriptor, false, typeArguments)
}
private fun FunctionDescriptor.signature(): JvmMethodSignature = typeMapper.mapSignature(this)
private fun FunctionDescriptor.signature(): JvmMethodSignature = typeMapper.mapSignatureWithGeneric(this, OwnerKind.IMPLEMENTATION)
private fun generateMethodStub(signature: JvmMethodSignature, synthetic: Boolean) {
// TODO: investigate if it makes sense to generate abstract stubs in traits
@@ -120,7 +120,7 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
val isStatic = AsmUtil.isStaticMethod(contextKind, functionDescriptor)
val flags = AsmUtil.getVisibilityAccessFlag(functionDescriptor) or (if (isStatic) Opcodes.ACC_STATIC else 0)
val remainingParameters = getRemainingParameters(functionDescriptor.original, substituteCount)
val signature = typeMapper.mapSignature(functionDescriptor, contextKind, remainingParameters)
val signature = typeMapper.mapSignature(functionDescriptor, contextKind, remainingParameters, false)
val mv = classBuilder.newMethod(OtherOrigin(methodElement, functionDescriptor), flags,
signature.asmMethod.name,
signature.asmMethod.descriptor,
@@ -43,6 +43,7 @@ import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethod;
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicPropertyGetter;
import org.jetbrains.kotlin.codegen.pseudoInsns.PseudoInsnsKt;
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter;
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
@@ -79,7 +80,6 @@ import org.jetbrains.kotlin.resolve.inline.InlineUtil;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
import org.jetbrains.kotlin.resolve.scopes.receivers.*;
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor;
import org.jetbrains.kotlin.types.KotlinType;
@@ -92,6 +92,7 @@ import org.jetbrains.org.objectweb.asm.MethodVisitor;
import org.jetbrains.org.objectweb.asm.Opcodes;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import org.jetbrains.org.objectweb.asm.commons.Method;
import java.util.*;
@@ -1485,8 +1486,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
assert constructors.size() == 1 : "Unexpected number of constructors for class: " + classDescriptor + " " + constructors;
ConstructorDescriptor constructorDescriptor = CollectionsKt.single(constructors);
JvmMethodSignature constructor = typeMapper.mapSignature(SamCodegenUtil.resolveSamAdapter(constructorDescriptor));
v.invokespecial(type.getInternalName(), "<init>", constructor.getAsmMethod().getDescriptor(), false);
Method constructor = typeMapper.mapAsmMethod(SamCodegenUtil.resolveSamAdapter(constructorDescriptor));
v.invokespecial(type.getInternalName(), "<init>", constructor.getDescriptor(), false);
return Unit.INSTANCE;
}
});
@@ -2520,7 +2521,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
if (typeParameterAndReificationArgument == null) {
KotlinType approximatedType = CapturedTypeApproximationKt.approximateCapturedTypes(entry.getValue()).getUpper();
// type is not generic
BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.TYPE);
JvmSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.TYPE);
Type asmType = typeMapper.mapTypeParameter(approximatedType, signatureWriter);
mappings.addParameterMappingToType(
@@ -152,7 +152,7 @@ public class FunctionCodegen {
return;
}
JvmMethodSignature jvmSignature = typeMapper.mapSignature(functionDescriptor, contextKind);
JvmMethodSignature jvmSignature = typeMapper.mapSignatureWithGeneric(functionDescriptor, contextKind);
Method asmMethod = jvmSignature.getAsmMethod();
int flags = getMethodAsmFlags(functionDescriptor, contextKind);
@@ -180,7 +180,7 @@ public class FunctionCodegen {
generateMethodAnnotations(functionDescriptor, asmMethod, mv);
generateParameterAnnotations(functionDescriptor, mv, typeMapper.mapSignature(functionDescriptor));
generateParameterAnnotations(functionDescriptor, mv, typeMapper.mapSignatureSkipGeneric(functionDescriptor));
generateBridges(functionDescriptor);
@@ -212,10 +212,10 @@ public class FunctionCodegen {
// native @JvmStatic foo() in companion object should delegate to the static native function moved to the outer class
mv.visitCode();
FunctionDescriptor staticFunctionDescriptor = JvmStaticGenerator.createStaticFunctionDescriptor(functionDescriptor);
JvmMethodSignature jvmMethodSignature =
typeMapper.mapSignature(memberCodegen.getContext().accessibleDescriptor(staticFunctionDescriptor, null));
Method accessorMethod =
typeMapper.mapAsmMethod(memberCodegen.getContext().accessibleDescriptor(staticFunctionDescriptor, null));
Type owningType = typeMapper.mapClass((ClassifierDescriptor) staticFunctionDescriptor.getContainingDeclaration());
generateDelegateToMethodBody(false, mv, jvmMethodSignature.getAsmMethod(), owningType.getInternalName());
generateDelegateToMethodBody(false, mv, accessorMethod, owningType.getInternalName());
}
endVisit(mv, null, origin.getElement());
@@ -582,7 +582,7 @@ public class FunctionCodegen {
CallableDescriptor overridden = SpecialBuiltinMembers.getOverriddenBuiltinReflectingJvmDescriptor(descriptor);
assert overridden != null;
Method method = typeMapper.mapSignature(descriptor).getAsmMethod();
Method method = typeMapper.mapAsmMethod(descriptor);
int flags = ACC_ABSTRACT | getVisibilityAccessFlag(descriptor);
v.newMethod(JvmDeclarationOriginKt.OtherOrigin(overridden), flags, method.getName(), method.getDescriptor(), null, null);
}
@@ -594,7 +594,7 @@ public class FunctionCodegen {
return new Function1<FunctionDescriptor, Method>() {
@Override
public Method invoke(FunctionDescriptor descriptor) {
return typeMapper.mapSignature(descriptor).getAsmMethod();
return typeMapper.mapAsmMethod(descriptor);
}
};
}
@@ -708,7 +708,7 @@ public class FunctionCodegen {
@NotNull Method defaultMethod
) {
GenerationState state = parentCodegen.state;
JvmMethodSignature signature = state.getTypeMapper().mapSignature(functionDescriptor, methodContext.getContextKind());
JvmMethodSignature signature = state.getTypeMapper().mapSignatureWithGeneric(functionDescriptor, methodContext.getContextKind());
boolean isStatic = isStaticMethod(methodContext.getContextKind(), functionDescriptor);
FrameMap frameMap = createFrameMap(state, functionDescriptor, signature, isStatic);
@@ -978,7 +978,7 @@ public class FunctionCodegen {
@NotNull MemberCodegen<?> parentCodegen
) {
Method delegateToMethod = typeMapper.mapToCallableMethod(delegatedTo, /* superCall = */ false).getAsmMethod();
Method delegateMethod = typeMapper.mapSignature(delegateFunction).getAsmMethod();
Method delegateMethod = typeMapper.mapAsmMethod(delegateFunction);
Type[] argTypes = delegateMethod.getArgumentTypes();
Type[] originalArgTypes = delegateToMethod.getArgumentTypes();
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension;
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil;
import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension;
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
@@ -297,7 +298,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
@NotNull
private JvmClassSignature signature() {
BothSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.CLASS);
JvmSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.CLASS);
typeMapper.writeFormalTypeParameters(descriptor.getDeclaredTypeParameters(), sw);
@@ -657,7 +658,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
else {
//noinspection ConstantConditions
Method method = typeMapper.mapSignature(propertyDescriptor.getGetter()).getAsmMethod();
Method method = typeMapper.mapAsmMethod(propertyDescriptor.getGetter());
iv.invokevirtual(classAsmType.getInternalName(), method.getName(), method.getDescriptor(), false);
return method.getReturnType();
}
@@ -726,7 +727,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
parameterIndex += type.getSize();
}
Method constructorAsmMethod = typeMapper.mapSignature(constructor).getAsmMethod();
Method constructorAsmMethod = typeMapper.mapAsmMethod(constructor);
iv.invokespecial(thisDescriptorType.getInternalName(), "<init>", constructorAsmMethod.getDescriptor(), false);
iv.areturn(thisDescriptorType);
@@ -1342,7 +1343,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
ClassDescriptor containingTrait = (ClassDescriptor) containingDeclaration;
Type traitImplType = typeMapper.mapDefaultImpls(containingTrait);
Method traitMethod = typeMapper.mapSignature(traitFun.getOriginal(), OwnerKind.DEFAULT_IMPLS).getAsmMethod();
Method traitMethod = typeMapper.mapAsmMethod(traitFun.getOriginal(), OwnerKind.DEFAULT_IMPLS);
Type[] argTypes = signature.getAsmMethod().getArgumentTypes();
Type[] originalArgTypes = traitMethod.getArgumentTypes();
@@ -318,7 +318,7 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
@Nullable
private Method computeEnclosingMethod(@NotNull CodegenContext context) {
if (context instanceof MethodContext) {
Method method = typeMapper.mapSignature(((MethodContext) context).getFunctionDescriptor()).getAsmMethod();
Method method = typeMapper.mapAsmMethod(((MethodContext) context).getFunctionDescriptor());
if (!method.getName().equals("<clinit>")) {
return method;
}
@@ -174,7 +174,7 @@ class PropertyReferenceCodegen(
initialize(property.type)
}
val method = state.typeMapper.mapSignature(getter).asmMethod
val method = state.typeMapper.mapAsmMethod(getter)
return method.name + method.descriptor
}
@@ -116,7 +116,7 @@ public class InlineCodegen extends CallGenerator {
PsiElement element = DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor);
context = (MethodContext) getContext(functionDescriptor, state, element != null ? (KtFile) element.getContainingFile() : null);
jvmSignature = typeMapper.mapSignature(functionDescriptor, context.getContextKind());
jvmSignature = typeMapper.mapSignatureWithGeneric(functionDescriptor, context.getContextKind());
// TODO: implement AS_FUNCTION inline strategy
this.asFunctionInline = false;
@@ -331,7 +331,7 @@ public class InlineCodegen extends CallGenerator {
parentCodegen = ((FakeMemberCodegen) parentCodegen).delegate;
}
JvmMethodSignature signature = typeMapper.mapSignature(context.getFunctionDescriptor(), context.getContextKind());
JvmMethodSignature signature = typeMapper.mapSignatureSkipGeneric(context.getFunctionDescriptor(), context.getContextKind());
return new InlineCallSiteInfo(parentCodegen.getClassName(), signature.getAsmMethod().getName(), signature.getAsmMethod().getDescriptor());
}
@@ -349,7 +349,7 @@ public class InlineCodegen extends CallGenerator {
MethodContext context = parentContext.intoClosure(descriptor, codegen, typeMapper).intoInlinedLambda(descriptor, info.isCrossInline);
JvmMethodSignature jvmMethodSignature = typeMapper.mapSignature(descriptor);
JvmMethodSignature jvmMethodSignature = typeMapper.mapSignatureSkipGeneric(descriptor);
Method asmMethod = jvmMethodSignature.getAsmMethod();
MethodNode methodNode = new MethodNode(InlineCodegenUtil.API, getMethodAsmFlags(descriptor, context.getContextKind()), asmMethod.getName(), asmMethod.getDescriptor(), jvmMethodSignature.getGenericsSignature(), null);
@@ -46,7 +46,7 @@ class InlineCodegenForDefaultBody(
DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor)?.containingFile as? KtFile
)
private val jvmSignature = state.typeMapper.mapSignature(functionDescriptor, context.contextKind)
private val jvmSignature = state.typeMapper.mapSignatureWithGeneric(functionDescriptor, context.contextKind)
init {
assert(InlineUtil.isInline(function)) {
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.Method;
import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode;
import java.util.ArrayList;
@@ -148,15 +149,15 @@ public class LambdaInfo implements CapturedParamOwner, LabelOwner {
@NotNull
public List<Type> getInvokeParamsWithoutCaptured() {
Type[] types = typeMapper.mapSignature(functionDescriptor).getAsmMethod().getArgumentTypes();
Type[] types = typeMapper.mapAsmMethod(functionDescriptor).getArgumentTypes();
return Arrays.asList(types);
}
@NotNull
public Parameters addAllParameters(FieldRemapper remapper) {
JvmMethodSignature signature = typeMapper.mapSignature(getFunctionDescriptor());
Method asmMethod = typeMapper.mapAsmMethod(getFunctionDescriptor());
ParametersBuilder builder =
ParametersBuilder.initializeBuilderFrom(AsmTypes.OBJECT_TYPE, signature.getAsmMethod().getDescriptor(), this);
ParametersBuilder.initializeBuilderFrom(AsmTypes.OBJECT_TYPE, asmMethod.getDescriptor(), this);
for (CapturedParamDesc info : getCapturedVars()) {
CapturedParamInfo field = remapper.findField(new FieldInsnNode(0, info.getContainingLambdaName(), info.getFieldName(), ""));
@@ -260,8 +260,8 @@ public class MethodInliner {
//return value boxing/unboxing
Method bridge =
typeMapper.mapSignature(ClosureCodegen.getErasedInvokeFunction(info.getFunctionDescriptor())).getAsmMethod();
Method delegate = typeMapper.mapSignature(info.getFunctionDescriptor()).getAsmMethod();
typeMapper.mapAsmMethod(ClosureCodegen.getErasedInvokeFunction(info.getFunctionDescriptor()));
Method delegate = typeMapper.mapAsmMethod(info.getFunctionDescriptor());
StackValue.onStack(delegate.getReturnType()).put(bridge.getReturnType(), this);
setLambdaInlining(false);
addInlineMarker(this, false);
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2016 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.
@@ -19,21 +19,15 @@ package org.jetbrains.kotlin.codegen.signature;
import com.intellij.util.containers.Stack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
import org.jetbrains.kotlin.types.Variance;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.Method;
import org.jetbrains.org.objectweb.asm.signature.SignatureVisitor;
import org.jetbrains.org.objectweb.asm.signature.SignatureWriter;
import org.jetbrains.org.objectweb.asm.util.CheckSignatureAdapter;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.types.Variance;
import java.util.ArrayList;
import java.util.List;
public class BothSignatureWriter {
public class BothSignatureWriter extends JvmSignatureWriter {
public enum Mode {
METHOD(CheckSignatureAdapter.METHOD_SIGNATURE),
CLASS(CheckSignatureAdapter.CLASS_SIGNATURE),
@@ -49,18 +43,8 @@ public class BothSignatureWriter {
private final SignatureWriter signatureWriter = new SignatureWriter();
private final SignatureVisitor signatureVisitor;
private final List<JvmMethodParameterSignature> kotlinParameterTypes = new ArrayList<JvmMethodParameterSignature>();
private int jvmCurrentTypeArrayLevel;
private Type jvmCurrentType;
private Type jvmReturnType;
private JvmMethodParameterKind currentParameterKind;
private boolean generic = false;
private int currentSignatureSize = 0;
public BothSignatureWriter(@NotNull Mode mode) {
this.signatureVisitor = new CheckSignatureAdapter(mode.asmType, signatureWriter);
}
@@ -82,64 +66,49 @@ public class BothSignatureWriter {
/**
* Shortcut
*/
@Override
public void writeAsmType(Type asmType) {
switch (asmType.getSort()) {
case Type.OBJECT:
writeClassBegin(asmType);
writeClassEnd();
return;
case Type.ARRAY:
writeArrayType();
writeAsmType(asmType.getElementType());
writeArrayEnd();
return;
default:
signatureVisitor().visitBaseType(asmType.getDescriptor().charAt(0));
writeAsmType0(asmType);
if (asmType.getSort() != Type.OBJECT && asmType.getSort() != Type.ARRAY) {
signatureVisitor().visitBaseType(asmType.getDescriptor().charAt(0));
}
super.writeAsmType(asmType);
}
private String makeArrayPrefix() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < jvmCurrentTypeArrayLevel; ++i) {
sb.append('[');
}
return sb.toString();
}
private void writeAsmType0(Type type) {
if (jvmCurrentType == null) {
jvmCurrentType = Type.getType(makeArrayPrefix() + type.getDescriptor());
}
}
@Override
public void writeClassBegin(Type asmType) {
signatureVisitor().visitClassType(asmType.getInternalName());
writeAsmType0(asmType);
super.writeClassBegin(asmType);
}
@Override
public void writeOuterClassBegin(Type resultingAsmType, String outerInternalName) {
signatureVisitor().visitClassType(outerInternalName);
writeAsmType0(resultingAsmType);
super.writeOuterClassBegin(resultingAsmType, outerInternalName);
}
@Override
public void writeInnerClass(String name) {
signatureVisitor().visitInnerClassType(name);
super.writeInnerClass(name);
}
@Override
public void writeClassEnd() {
signatureVisitor().visitEnd();
super.writeClassEnd();
}
@Override
public void writeArrayType() {
push(signatureVisitor().visitArrayType());
if (jvmCurrentType == null) {
++jvmCurrentTypeArrayLevel;
}
super.writeArrayType();
}
@Override
public void writeArrayEnd() {
pop();
super.writeArrayEnd();
}
private static char toJvmVariance(@NotNull Variance variance) {
@@ -151,56 +120,70 @@ public class BothSignatureWriter {
}
}
@Override
public void writeTypeArgument(@NotNull Variance projectionKind) {
push(signatureVisitor().visitTypeArgument(toJvmVariance(projectionKind)));
generic = true;
super.writeTypeArgument(projectionKind);
}
@Override
public void writeUnboundedWildcard() {
signatureVisitor().visitTypeArgument();
generic = true;
super.writeUnboundedWildcard();
}
@Override
public void writeTypeArgumentEnd() {
pop();
super.writeTypeArgumentEnd();
}
@Override
public void writeTypeVariable(Name name, Type asmType) {
signatureVisitor().visitTypeVariable(name.asString());
generic = true;
writeAsmType0(asmType);
super.writeTypeVariable(name, asmType);
}
@Override
public void writeFormalTypeParameter(String name) {
signatureVisitor().visitFormalTypeParameter(name);
generic = true;
super.writeFormalTypeParameter(name);
}
@Override
public void writeClassBound() {
push(signatureVisitor().visitClassBound());
super.writeClassBound();
}
@Override
public void writeClassBoundEnd() {
pop();
super.writeClassBoundEnd();
}
@Override
public void writeInterfaceBound() {
push(signatureVisitor().visitInterfaceBound());
super.writeInterfaceBound();
}
@Override
public void writeInterfaceBoundEnd() {
pop();
super.writeInterfaceBoundEnd();
}
@Override
public void writeParametersStart() {
// hacks
jvmCurrentType = null;
jvmCurrentTypeArrayLevel = 0;
super.writeParametersStart();
}
@Override
public void writeParameterType(JvmMethodParameterKind parameterKind) {
// This magic mimics the behavior of javac that enum constructor have these synthetic parameters in erased signature, but doesn't
// have them in generic signature. IDEA, javac and their friends rely on this behavior.
@@ -213,67 +196,60 @@ public class BothSignatureWriter {
else {
push(signatureVisitor().visitParameterType());
}
this.currentParameterKind = parameterKind;
super.writeParameterType(parameterKind);
}
@Override
public void writeParameterTypeEnd() {
pop();
kotlinParameterTypes.add(new JvmMethodParameterSignature(jvmCurrentType, currentParameterKind));
currentSignatureSize += jvmCurrentType.getSize();
currentParameterKind = null;
jvmCurrentType = null;
jvmCurrentTypeArrayLevel = 0;
super.writeParameterTypeEnd();
}
@Override
public void writeReturnType() {
push(signatureVisitor().visitReturnType());
super.writeReturnType();
}
@Override
public void writeReturnTypeEnd() {
pop();
jvmReturnType = jvmCurrentType;
jvmCurrentType = null;
jvmCurrentTypeArrayLevel = 0;
super.writeReturnTypeEnd();
}
@Override
public void writeSuperclass() {
push(signatureVisitor().visitSuperclass());
super.writeSuperclass();
}
@Override
public void writeSuperclassEnd() {
pop();
super.writeSuperclassEnd();
}
@Override
public void writeInterface() {
push(signatureVisitor().visitInterface());
super.writeInterface();
}
@Override
public void writeInterfaceEnd() {
pop();
super.writeInterfaceEnd();
}
@Override
@Nullable
public String makeJavaGenericSignature() {
return generic ? signatureWriter.toString() : null;
}
@NotNull
public JvmMethodSignature makeJvmMethodSignature(@NotNull String name, boolean skipGenericSignature) {
List<Type> types = new ArrayList<Type>(kotlinParameterTypes.size());
for (JvmMethodParameterSignature parameter : kotlinParameterTypes) {
types.add(parameter.getAsmType());
}
Method asmMethod = new Method(name, jvmReturnType, types.toArray(new Type[types.size()]));
return new JvmMethodSignature(asmMethod, !skipGenericSignature ? makeJavaGenericSignature() : null, kotlinParameterTypes);
}
public int getCurrentSignatureSize() {
return currentSignatureSize;
@Override
public boolean skipGenericSignature() {
return false;
}
@Override
@@ -0,0 +1,196 @@
/*
* Copyright 2010-2015 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.kotlin.codegen.signature;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
import org.jetbrains.kotlin.types.Variance;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.Method;
import java.util.ArrayList;
import java.util.List;
public class JvmSignatureWriter {
private final List<JvmMethodParameterSignature> kotlinParameterTypes = new ArrayList<JvmMethodParameterSignature>();
private int jvmCurrentTypeArrayLevel;
private Type jvmCurrentType;
private Type jvmReturnType;
private JvmMethodParameterKind currentParameterKind;
private int currentSignatureSize = 0;
/**
* Shortcut
*/
public void writeAsmType(Type asmType) {
switch (asmType.getSort()) {
case Type.OBJECT:
writeClassBegin(asmType);
writeClassEnd();
return;
case Type.ARRAY:
writeArrayType();
writeAsmType(asmType.getElementType());
writeArrayEnd();
return;
default:
writeAsmType0(asmType);
}
}
private String makeArrayPrefix() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < jvmCurrentTypeArrayLevel; ++i) {
sb.append('[');
}
return sb.toString();
}
protected void writeAsmType0(Type type) {
if (jvmCurrentType == null) {
jvmCurrentType = Type.getType(makeArrayPrefix() + type.getDescriptor());
}
}
public void writeClassBegin(Type asmType) {
writeAsmType0(asmType);
}
public void writeOuterClassBegin(Type resultingAsmType, String outerInternalName) {
writeAsmType0(resultingAsmType);
}
public void writeInnerClass(String name) {
}
public void writeClassEnd() {
}
public void writeArrayType() {
if (jvmCurrentType == null) {
++jvmCurrentTypeArrayLevel;
}
}
public void writeArrayEnd() {
}
public void writeTypeArgument(@NotNull Variance projectionKind) {
}
public void writeUnboundedWildcard() {
}
public void writeTypeArgumentEnd() {
}
public void writeTypeVariable(Name name, Type asmType) {
writeAsmType0(asmType);
}
public void writeFormalTypeParameter(String name) {
}
public void writeClassBound() {
}
public void writeClassBoundEnd() {
}
public void writeInterfaceBound() {
}
public void writeInterfaceBoundEnd() {
}
public void writeParametersStart() {
// hacks
jvmCurrentType = null;
jvmCurrentTypeArrayLevel = 0;
}
public void writeParameterType(JvmMethodParameterKind parameterKind) {
currentParameterKind = parameterKind;
}
public void writeParameterTypeEnd() {
kotlinParameterTypes.add(new JvmMethodParameterSignature(jvmCurrentType, currentParameterKind));
currentSignatureSize += jvmCurrentType.getSize();
currentParameterKind = null;
jvmCurrentType = null;
jvmCurrentTypeArrayLevel = 0;
}
public void writeReturnType() {
}
public void writeReturnTypeEnd() {
jvmReturnType = jvmCurrentType;
jvmCurrentType = null;
jvmCurrentTypeArrayLevel = 0;
}
public void writeSuperclass() {
}
public void writeSuperclassEnd() {
}
public void writeInterface() {
}
public void writeInterfaceEnd() {
}
@Nullable
public String makeJavaGenericSignature() {
return null;
}
@NotNull
public JvmMethodSignature makeJvmMethodSignature(@NotNull String name) {
List<Type> types = new ArrayList<Type>(kotlinParameterTypes.size());
for (JvmMethodParameterSignature parameter : kotlinParameterTypes) {
types.add(parameter.getAsmType());
}
Method asmMethod = new Method(name, jvmReturnType, types.toArray(new Type[types.size()]));
return new JvmMethodSignature(asmMethod, makeJavaGenericSignature(), kotlinParameterTypes);
}
public int getCurrentSignatureSize() {
return currentSignatureSize;
}
public boolean skipGenericSignature() {
return true;
}
@Override
public String toString() {
return "empty";
}
}
@@ -30,5 +30,5 @@ class KotlinToJvmSignatureMapperImpl : KotlinToJvmSignatureMapper {
private val typeMapper = JetTypeMapper(BindingContext.EMPTY, ClassBuilderMode.LIGHT_CLASSES, NoResolveFileClassesProvider, null,
IncompatibleClassTracker.DoNothing, JvmAbi.DEFAULT_MODULE_NAME)
override fun mapToJvmMethodSignature(function: FunctionDescriptor) = typeMapper.mapSignature(function)
override fun mapToJvmMethodSignature(function: FunctionDescriptor) = typeMapper.mapAsmMethod(function)
}
@@ -192,8 +192,8 @@ class BuilderFactoryForDuplicateSignatureDiagnostics(
}
private fun FunctionDescriptor.asRawSignature() =
with(typeMapper.mapSignature(this)) {
RawSignature(asmMethod.name!!, asmMethod.descriptor!!, MemberKind.METHOD)
with(typeMapper.mapAsmMethod(this)) {
RawSignature(name, descriptor, MemberKind.METHOD)
}
private fun isOrOverridesSamAdapter(descriptor: CallableMemberDescriptor): Boolean {
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
import org.jetbrains.kotlin.codegen.binding.MutableClosure;
import org.jetbrains.kotlin.codegen.binding.PsiCodegenPredictor;
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.fileClasses.FileClasses;
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil;
@@ -322,7 +323,7 @@ public class JetTypeMapper {
}
@NotNull
private Type mapReturnType(@NotNull CallableDescriptor descriptor, @Nullable BothSignatureWriter sw) {
private Type mapReturnType(@NotNull CallableDescriptor descriptor, @Nullable JvmSignatureWriter sw) {
KotlinType returnType = descriptor.getReturnType();
assert returnType != null : "Function has no return type: " + descriptor;
@@ -346,8 +347,12 @@ public class JetTypeMapper {
}
@NotNull
private Type mapReturnType(@NotNull CallableDescriptor descriptor, @Nullable BothSignatureWriter sw, @NotNull KotlinType returnType) {
private Type mapReturnType(@NotNull CallableDescriptor descriptor, @Nullable JvmSignatureWriter sw, @NotNull KotlinType returnType) {
boolean isAnnotationMethod = DescriptorUtils.isAnnotationClass(descriptor.getContainingDeclaration());
if (sw == null || sw.skipGenericSignature()) {
return mapType(returnType, sw, TypeMappingMode.getModeForReturnTypeNoGeneric(isAnnotationMethod));
}
TypeMappingMode typeMappingModeFromAnnotation =
TypeMappingUtil.extractTypeMappingModeFromAnnotation(descriptor, returnType, isAnnotationMethod);
if (typeMappingModeFromAnnotation != null) {
@@ -367,12 +372,12 @@ public class JetTypeMapper {
}
@NotNull
public Type mapSupertype(@NotNull KotlinType jetType, @Nullable BothSignatureWriter signatureVisitor) {
public Type mapSupertype(@NotNull KotlinType jetType, @Nullable JvmSignatureWriter signatureVisitor) {
return mapType(jetType, signatureVisitor, TypeMappingMode.SUPER_TYPE);
}
@NotNull
public Type mapTypeParameter(@NotNull KotlinType jetType, @Nullable BothSignatureWriter signatureVisitor) {
public Type mapTypeParameter(@NotNull KotlinType jetType, @Nullable JvmSignatureWriter signatureVisitor) {
return mapType(jetType, signatureVisitor, TypeMappingMode.GENERIC_ARGUMENT);
}
@@ -394,11 +399,11 @@ public class JetTypeMapper {
@NotNull
public JvmMethodSignature mapAnnotationParameterSignature(@NotNull PropertyDescriptor descriptor) {
BothSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD);
JvmSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD);
sw.writeReturnType();
mapType(descriptor.getType(), sw, TypeMappingMode.VALUE_FOR_ANNOTATION);
sw.writeReturnTypeEnd();
return sw.makeJvmMethodSignature(descriptor.getName().asString(), false);
return sw.makeJvmMethodSignature(descriptor.getName().asString());
}
@NotNull
@@ -409,7 +414,7 @@ public class JetTypeMapper {
@NotNull
private Type mapType(
@NotNull KotlinType jetType,
@Nullable BothSignatureWriter signatureVisitor,
@Nullable JvmSignatureWriter signatureVisitor,
@NotNull TypeMappingMode mode
) {
Type builtinType = mapBuiltinType(jetType);
@@ -595,7 +600,7 @@ public class JetTypeMapper {
private void writeGenericType(
@NotNull KotlinType type,
@NotNull Type asmType,
@Nullable BothSignatureWriter signatureVisitor,
@Nullable JvmSignatureWriter signatureVisitor,
@NotNull TypeMappingMode mode
) {
if (signatureVisitor != null) {
@@ -606,7 +611,7 @@ public class JetTypeMapper {
// In<Nothing, Foo> == In<*, Foo> -> In<?, Foo>
// In<Nothing, Nothing> -> In
// Inv<in Nothing, Foo> -> Inv
if (hasNothingInNonContravariantPosition(type) || type.getArguments().isEmpty()) {
if (signatureVisitor.skipGenericSignature() || hasNothingInNonContravariantPosition(type) || type.getArguments().isEmpty()) {
signatureVisitor.writeAsmType(asmType);
return;
}
@@ -654,7 +659,7 @@ public class JetTypeMapper {
}
private void writeGenericArguments(
@NotNull BothSignatureWriter signatureVisitor,
@NotNull JvmSignatureWriter signatureVisitor,
@NotNull List<? extends TypeProjection> arguments,
@NotNull List<? extends TypeParameterDescriptor> parameters,
@NotNull TypeMappingMode mode
@@ -742,7 +747,7 @@ public class JetTypeMapper {
@NotNull
public CallableMethod mapToCallableMethod(@NotNull FunctionDescriptor descriptor, boolean superCall) {
if (descriptor instanceof ConstructorDescriptor) {
JvmMethodSignature method = mapSignature(descriptor);
JvmMethodSignature method = mapSignatureSkipGeneric(descriptor);
Type owner = mapClass(((ConstructorDescriptor) descriptor).getContainingDeclaration());
String defaultImplDesc = mapDefaultMethod(descriptor, OwnerKind.IMPLEMENTATION).getDescriptor();
return new CallableMethod(owner, owner, defaultImplDesc, method, INVOKESPECIAL, null, null, null);
@@ -778,12 +783,12 @@ public class JetTypeMapper {
thisClass = mapClass(currentOwner);
if (declarationOwner instanceof JavaClassDescriptor) {
invokeOpcode = INVOKESPECIAL;
signature = mapSignature(functionDescriptor);
signature = mapSignatureSkipGeneric(functionDescriptor);
owner = thisClass;
}
else {
invokeOpcode = INVOKESTATIC;
signature = mapSignature(descriptor.getOriginal(), OwnerKind.DEFAULT_IMPLS);
signature = mapSignatureSkipGeneric(descriptor.getOriginal(), OwnerKind.DEFAULT_IMPLS);
owner = mapDefaultImpls(currentOwner);
}
}
@@ -809,7 +814,7 @@ public class JetTypeMapper {
? overriddenSpecialBuiltinFunction.getOriginal()
: functionDescriptor.getOriginal();
signature = mapSignature(functionToCall);
signature = mapSignatureSkipGeneric(functionToCall);
ClassDescriptor receiver = (currentIsInterface && !originalIsInterface) || currentOwner instanceof FunctionClassDescriptor
? declarationOwner
@@ -819,7 +824,7 @@ public class JetTypeMapper {
}
}
else {
signature = mapSignature(functionDescriptor.getOriginal());
signature = mapSignatureSkipGeneric(functionDescriptor.getOriginal());
owner = mapOwner(functionDescriptor);
ownerForDefaultImpl = owner;
baseMethodDescriptor = functionDescriptor;
@@ -975,39 +980,68 @@ public class JetTypeMapper {
}
@NotNull
public JvmMethodSignature mapSignature(@NotNull FunctionDescriptor descriptor) {
return mapSignature(descriptor, OwnerKind.IMPLEMENTATION);
public Method mapAsmMethod(@NotNull FunctionDescriptor descriptor) {
return mapSignature(descriptor, true).getAsmMethod();
}
@NotNull
public JvmMethodSignature mapSignature(@NotNull FunctionDescriptor f, @NotNull OwnerKind kind) {
public Method mapAsmMethod(@NotNull FunctionDescriptor descriptor, @NotNull OwnerKind kind) {
return mapSignature(descriptor, kind, true).getAsmMethod();
}
@NotNull
private JvmMethodSignature mapSignature(@NotNull FunctionDescriptor f, boolean skipGenericSignature) {
return mapSignature(f, OwnerKind.IMPLEMENTATION, skipGenericSignature);
}
@NotNull
public JvmMethodSignature mapSignatureSkipGeneric(@NotNull FunctionDescriptor f) {
return mapSignatureSkipGeneric(f, OwnerKind.IMPLEMENTATION);
}
@NotNull
public JvmMethodSignature mapSignatureSkipGeneric(@NotNull FunctionDescriptor f, @NotNull OwnerKind kind) {
return mapSignature(f, kind, true);
}
@NotNull
public JvmMethodSignature mapSignatureWithGeneric(@NotNull FunctionDescriptor f, @NotNull OwnerKind kind) {
return mapSignature(f, kind, false);
}
@NotNull
private JvmMethodSignature mapSignature(@NotNull FunctionDescriptor f, @NotNull OwnerKind kind, boolean skipGenericSignature) {
if (f.getInitialSignatureDescriptor() != null && f != f.getInitialSignatureDescriptor()) {
// Overrides of special builtin in Kotlin classes always have special signature
if (SpecialBuiltinMembers.getOverriddenBuiltinReflectingJvmDescriptor(f) == null ||
f.getContainingDeclaration().getOriginal() instanceof JavaClassDescriptor) {
return mapSignature(f.getInitialSignatureDescriptor(), kind);
return mapSignature(f.getInitialSignatureDescriptor(), kind, skipGenericSignature);
}
}
if (f instanceof ConstructorDescriptor) {
return mapSignature(f, kind, f.getOriginal().getValueParameters());
return mapSignature(f, kind, f.getOriginal().getValueParameters(), skipGenericSignature);
}
return mapSignature(f, kind, f.getValueParameters());
return mapSignature(f, kind, f.getValueParameters(), skipGenericSignature);
}
@NotNull
public JvmMethodSignature mapSignature(
@NotNull FunctionDescriptor f,
@NotNull OwnerKind kind,
@NotNull List<ValueParameterDescriptor> valueParameters
@NotNull List<ValueParameterDescriptor> valueParameters,
boolean skipGenericSignature
) {
if (f instanceof FunctionImportedFromObject) {
return mapSignature(((FunctionImportedFromObject) f).getCallableFromObject());
return mapSignature(((FunctionImportedFromObject) f).getCallableFromObject(), kind, skipGenericSignature);
}
checkOwnerCompatibility(f);
BothSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD);
JvmSignatureWriter sw = skipGenericSignature || f instanceof AccessorForCallableDescriptor
? new JvmSignatureWriter()
: new BothSignatureWriter(BothSignatureWriter.Mode.METHOD);
if (f instanceof ConstructorDescriptor) {
sw.writeParametersStart();
@@ -1044,7 +1078,7 @@ public class JetTypeMapper {
sw.writeReturnTypeEnd();
}
JvmMethodSignature signature = sw.makeJvmMethodSignature(mapFunctionName(f), f instanceof AccessorForCallableDescriptor);
JvmMethodSignature signature = sw.makeJvmMethodSignature(mapFunctionName(f));
if (kind != OwnerKind.DEFAULT_IMPLS) {
SpecialSignatureInfo specialSignatureInfo = BuiltinMethodsWithSpecialGenericSignature.getSpecialSignatureInfo(f);
@@ -1089,7 +1123,7 @@ public class JetTypeMapper {
private boolean writeCustomParameter(
@NotNull FunctionDescriptor f,
@NotNull ValueParameterDescriptor parameter,
@NotNull BothSignatureWriter sw
@NotNull JvmSignatureWriter sw
) {
FunctionDescriptor overridden =
BuiltinMethodsWithSpecialGenericSignature.getOverriddenBuiltinFunctionWithErasedValueParametersInJava(f);
@@ -1131,7 +1165,7 @@ public class JetTypeMapper {
@NotNull
public Method mapDefaultMethod(@NotNull FunctionDescriptor functionDescriptor, @NotNull OwnerKind kind) {
Method jvmSignature = mapSignature(functionDescriptor, kind).getAsmMethod();
Method jvmSignature = mapAsmMethod(functionDescriptor, kind);
Type ownerType = mapOwner(functionDescriptor);
boolean isConstructor = isConstructor(jvmSignature);
String descriptor = getDefaultDescriptor(
@@ -1161,7 +1195,7 @@ public class JetTypeMapper {
return false;
}
private static void writeVoidReturn(@NotNull BothSignatureWriter sw) {
private static void writeVoidReturn(@NotNull JvmSignatureWriter sw) {
sw.writeReturnType();
sw.writeAsmType(Type.VOID_TYPE);
sw.writeReturnTypeEnd();
@@ -1169,7 +1203,7 @@ public class JetTypeMapper {
@Nullable
public String mapFieldSignature(@NotNull KotlinType backingFieldType, @NotNull PropertyDescriptor propertyDescriptor) {
BothSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.TYPE);
JvmSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.TYPE);
if (!propertyDescriptor.isVar()) {
mapReturnType(propertyDescriptor, sw, backingFieldType);
@@ -1184,7 +1218,7 @@ public class JetTypeMapper {
private void writeThisIfNeeded(
@NotNull CallableMemberDescriptor descriptor,
@NotNull OwnerKind kind,
@NotNull BothSignatureWriter sw
@NotNull JvmSignatureWriter sw
) {
ClassDescriptor thisType;
if (kind == OwnerKind.DEFAULT_IMPLS) {
@@ -1208,13 +1242,14 @@ public class JetTypeMapper {
return traitDescriptor;
}
public void writeFormalTypeParameters(@NotNull List<TypeParameterDescriptor> typeParameters, @NotNull BothSignatureWriter sw) {
public void writeFormalTypeParameters(@NotNull List<TypeParameterDescriptor> typeParameters, @NotNull JvmSignatureWriter sw) {
if (sw.skipGenericSignature()) return;
for (TypeParameterDescriptor typeParameter : typeParameters) {
writeFormalTypeParameter(typeParameter, sw);
}
}
private void writeFormalTypeParameter(@NotNull TypeParameterDescriptor typeParameterDescriptor, @NotNull BothSignatureWriter sw) {
private void writeFormalTypeParameter(@NotNull TypeParameterDescriptor typeParameterDescriptor, @NotNull JvmSignatureWriter sw) {
if (classBuilderMode == ClassBuilderMode.LIGHT_CLASSES && typeParameterDescriptor.getName().isSpecial()) {
// If a type parameter has no name, the code below fails, but it should recover in case of light classes
return;
@@ -1263,7 +1298,7 @@ public class JetTypeMapper {
}
private void writeParameter(
@NotNull BothSignatureWriter sw,
@NotNull JvmSignatureWriter sw,
@NotNull KotlinType type,
@Nullable CallableDescriptor callableDescriptor
) {
@@ -1271,7 +1306,7 @@ public class JetTypeMapper {
}
private void writeParameter(
@NotNull BothSignatureWriter sw,
@NotNull JvmSignatureWriter sw,
@NotNull JvmMethodParameterKind kind,
@NotNull KotlinType type,
@Nullable CallableDescriptor callableDescriptor
@@ -1284,10 +1319,15 @@ public class JetTypeMapper {
}
private void writeParameterType(
@NotNull BothSignatureWriter sw,
@NotNull JvmSignatureWriter sw,
@NotNull KotlinType type,
@Nullable CallableDescriptor callableDescriptor
) {
if (sw.skipGenericSignature()) {
mapType(type, sw, TypeMappingMode.DEFAULT);
return;
}
TypeMappingMode typeMappingMode;
TypeMappingMode typeMappingModeFromAnnotation =
@@ -1306,13 +1346,13 @@ public class JetTypeMapper {
mapType(type, sw, typeMappingMode);
}
private static void writeParameter(@NotNull BothSignatureWriter sw, @NotNull JvmMethodParameterKind kind, @NotNull Type type) {
private static void writeParameter(@NotNull JvmSignatureWriter sw, @NotNull JvmMethodParameterKind kind, @NotNull Type type) {
sw.writeParameterType(kind);
sw.writeAsmType(type);
sw.writeParameterTypeEnd();
}
private void writeAdditionalConstructorParameters(@NotNull ConstructorDescriptor descriptor, @NotNull BothSignatureWriter sw) {
private void writeAdditionalConstructorParameters(@NotNull ConstructorDescriptor descriptor, @NotNull JvmSignatureWriter sw) {
MutableClosure closure = bindingContext.get(CodegenBinding.CLOSURE, descriptor.getContainingDeclaration());
ClassDescriptor captureThis = getDispatchReceiverParameterForConstructorCall(descriptor, closure);
@@ -1368,7 +1408,7 @@ public class JetTypeMapper {
}
private void writeSuperConstructorCallParameters(
@NotNull BothSignatureWriter sw,
@NotNull JvmSignatureWriter sw,
@NotNull ConstructorDescriptor descriptor,
@NotNull ResolvedCall<ConstructorDescriptor> superCall,
boolean hasOuter
@@ -1377,7 +1417,7 @@ public class JetTypeMapper {
List<ResolvedValueArgument> valueArguments = superCall.getValueArgumentsByIndex();
assert valueArguments != null : "Failed to arrange value arguments by index: " + superDescriptor;
List<JvmMethodParameterSignature> parameters = mapSignature(superDescriptor).getValueParameters();
List<JvmMethodParameterSignature> parameters = mapSignatureSkipGeneric(superDescriptor).getValueParameters();
int params = parameters.size();
int args = valueArguments.size();
@@ -1421,7 +1461,7 @@ public class JetTypeMapper {
@NotNull
public JvmMethodSignature mapScriptSignature(@NotNull ScriptDescriptor script, @NotNull List<ScriptDescriptor> importedScripts) {
BothSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD);
JvmSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD);
sw.writeParametersStart();
@@ -1435,7 +1475,7 @@ public class JetTypeMapper {
writeVoidReturn(sw);
return sw.makeJvmMethodSignature("<init>", false);
return sw.makeJvmMethodSignature("<init>");
}
public Type getSharedVarType(DeclarationDescriptor descriptor) {
@@ -60,6 +60,11 @@ internal class TypeMappingMode private constructor(
genericArgumentMode = TypeMappingMode(isForAnnotationParameter = true, genericArgumentMode = GENERIC_ARGUMENT))
@JvmStatic
fun getModeForReturnTypeNoGeneric(
isAnnotationMethod: Boolean
) = if (isAnnotationMethod) VALUE_FOR_ANNOTATION else DEFAULT
@JvmStatic
fun getOptimalModeForValueParameter(
type: KotlinType
@@ -17,19 +17,13 @@
package org.jetbrains.kotlin.resolve.jvm.jvmSignature
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.org.objectweb.asm.commons.Method
interface KotlinToJvmSignatureMapper {
fun mapToJvmMethodSignature(function: FunctionDescriptor): JvmMethodSignature
fun mapToJvmMethodSignature(function: FunctionDescriptor): Method
}
fun erasedSignaturesEqualIgnoringReturnTypes(subFunction: JvmMethodSignature, superFunction: JvmMethodSignature): Boolean {
val subParams = subFunction.valueParameters
val superParams = superFunction.valueParameters
fun erasedSignaturesEqualIgnoringReturnTypes(subFunction: Method, superFunction: Method) =
subFunction.parametersDescriptor() == superFunction.parametersDescriptor()
if (subParams.size != superParams.size) return false
return subParams.zip(superParams).all {
p -> val (subParam, superParam) = p
subParam.asmType == superParam.asmType
}
}
private fun Method.parametersDescriptor() = descriptor.substring(1, descriptor.lastIndexOf(")"))
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.KotlinToJvmSignatureMapper;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.KotlinToJvmSignatureMapperKt;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.TypeUtils;
import org.jetbrains.org.objectweb.asm.commons.Method;
import java.util.*;
@@ -197,11 +198,11 @@ public class SignaturesPropagationData {
// TODO: Add propagation for other kotlin descriptors (KT-3621)
Name name = method.getName();
JvmMethodSignature autoSignature = SIGNATURE_MAPPER.mapToJvmMethodSignature(autoMethodDescriptor);
Method autoSignature = SIGNATURE_MAPPER.mapToJvmMethodSignature(autoMethodDescriptor);
for (KotlinType supertype : containingClass.getTypeConstructor().getSupertypes()) {
Collection<FunctionDescriptor> superFunctionCandidates = supertype.getMemberScope().getContributedFunctions(name, NoLookupLocation.WHEN_GET_SUPER_MEMBERS);
for (FunctionDescriptor candidate : superFunctionCandidates) {
JvmMethodSignature candidateSignature = SIGNATURE_MAPPER.mapToJvmMethodSignature(candidate);
Method candidateSignature = SIGNATURE_MAPPER.mapToJvmMethodSignature(candidate);
if (KotlinToJvmSignatureMapperKt.erasedSignaturesEqualIgnoringReturnTypes(autoSignature, candidateSignature)) {
superFunctions.add(candidate);
}