diff --git a/compiler/testData/loadJava/compiledJava/kotlinSignature/MethodWithMappedClasses.txt b/compiler/testData/loadJava/compiledJava/kotlinSignature/MethodWithMappedClasses.txt index af3fde71cba..ff5ea05cdd9 100644 --- a/compiler/testData/loadJava/compiledJava/kotlinSignature/MethodWithMappedClasses.txt +++ b/compiler/testData/loadJava/compiledJava/kotlinSignature/MethodWithMappedClasses.txt @@ -2,5 +2,5 @@ package test public open class MethodWithMappedClasses { public constructor MethodWithMappedClasses() - public open fun copy(/*0*/ dest: kotlin.(Mutable)List!, /*1*/ src: kotlin.(Mutable)List!): kotlin.Unit + public open fun copy(/*0*/ dest: (kotlin.MutableList..kotlin.List<*>?), /*1*/ src: kotlin.(Mutable)List!): kotlin.Unit } diff --git a/compiler/testData/loadJava/compiledJava/kotlinSignature/MethodWithTypeParameters.txt b/compiler/testData/loadJava/compiledJava/kotlinSignature/MethodWithTypeParameters.txt index 8a999647cfc..8c2a3a0006c 100644 --- a/compiler/testData/loadJava/compiledJava/kotlinSignature/MethodWithTypeParameters.txt +++ b/compiler/testData/loadJava/compiledJava/kotlinSignature/MethodWithTypeParameters.txt @@ -2,5 +2,5 @@ package test public open class MethodWithTypeParameters { public constructor MethodWithTypeParameters() - public open fun foo(/*0*/ a: A!, /*1*/ b: (kotlin.MutableList..kotlin.List?), /*2*/ c: kotlin.(Mutable)List!): kotlin.Unit where B : kotlin.(Mutable)List! + public open fun foo(/*0*/ a: A!, /*1*/ b: (kotlin.MutableList..kotlin.List?), /*2*/ c: (kotlin.MutableList..kotlin.List<*>?)): kotlin.Unit where B : kotlin.(Mutable)List! } diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaConstructorDescriptor.java b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaConstructorDescriptor.java index 44090e6b210..4343f749847 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaConstructorDescriptor.java +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaConstructorDescriptor.java @@ -101,6 +101,7 @@ public class JavaConstructorDescriptor extends ConstructorDescriptorImpl impleme @NotNull JetType enhancedReturnType ) { JavaConstructorDescriptor enhanced = createSubstitutedCopy(getContainingDeclaration(), getOriginal(), getKind()); + // We do not use doSubstitute here as in JavaMethodDescriptor.enhance because type parameters of constructor belongs to class enhanced.initialize( enhancedReceiverType, getDispatchReceiverParameter(), diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaMethodDescriptor.java b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaMethodDescriptor.java index e999b400cd5..e9f9b2aa4b8 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaMethodDescriptor.java +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaMethodDescriptor.java @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations; import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.types.JetType; +import org.jetbrains.kotlin.types.TypeSubstitutor; import java.util.List; @@ -100,16 +101,20 @@ public class JavaMethodDescriptor extends SimpleFunctionDescriptorImpl implement @NotNull List enhancedValueParametersTypes, @NotNull JetType enhancedReturnType ) { - JavaMethodDescriptor enhancedMethod = createSubstitutedCopy(getContainingDeclaration(), getOriginal(), getKind()); - enhancedMethod.initialize( - enhancedReceiverType, - getDispatchReceiverParameter(), - getTypeParameters(), - DescriptorsPackage.createEnhancedValueParameters(enhancedValueParametersTypes, getValueParameters(), enhancedMethod), - enhancedReturnType, - getModality(), - getVisibility() + List enhancedValueParameters = + DescriptorsPackage.createEnhancedValueParameters(enhancedValueParametersTypes, getValueParameters(), this); + + // We use `doSubstitute` here because it does exactly what we need: + // 1. creates full copy of descriptor + // 2. copies method's type parameters (with new containing declaration) and properly substitute to them in value parameters, return type and etc. + JavaMethodDescriptor enhancedMethod = (JavaMethodDescriptor) doSubstitute( + TypeSubstitutor.EMPTY, getContainingDeclaration(), getModality(), getVisibility(), getOriginal(), + /* copyOverrides = */ false, getKind(), + enhancedValueParameters, enhancedReceiverType, enhancedReturnType ); + + assert enhancedMethod != null : "null after substitution while enhancing " + toString(); + for (FunctionDescriptor overridden : getOverriddenDescriptors()) { enhancedMethod.addOverriddenDescriptor(overridden); } diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/FunctionDescriptorImpl.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/FunctionDescriptorImpl.java index 3ce0941e14b..dfb6b614f3e 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/FunctionDescriptorImpl.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/FunctionDescriptorImpl.java @@ -197,6 +197,31 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo @Nullable FunctionDescriptor original, boolean copyOverrides, @NotNull Kind kind + ) { + return doSubstitute(originalSubstitutor, + newOwner, newModality, newVisibility, original, copyOverrides, kind, + getValueParameters(), getExtensionReceiverParameterType(), getReturnType() + ); + } + + @Nullable + protected JetType getExtensionReceiverParameterType() { + if (extensionReceiverParameter == null) return null; + return extensionReceiverParameter.getType(); + } + + + @Nullable + protected FunctionDescriptor doSubstitute(@NotNull TypeSubstitutor originalSubstitutor, + @NotNull DeclarationDescriptor newOwner, + @NotNull Modality newModality, + @NotNull Visibility newVisibility, + @Nullable FunctionDescriptor original, + boolean copyOverrides, + @NotNull Kind kind, + @NotNull List newValueParameterDescriptors, + @Nullable JetType newExtensionReceiverParameterType, + @NotNull JetType newReturnType ) { FunctionDescriptorImpl substitutedDescriptor = createSubstitutedCopy(newOwner, original, kind); @@ -207,8 +232,8 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo ); JetType substitutedReceiverParameterType = null; - if (extensionReceiverParameter != null) { - substitutedReceiverParameterType = substitutor.substitute(getExtensionReceiverParameter().getType(), Variance.IN_VARIANCE); + if (newExtensionReceiverParameterType != null) { + substitutedReceiverParameterType = substitutor.substitute(newExtensionReceiverParameterType, Variance.IN_VARIANCE); if (substitutedReceiverParameterType == null) { return null; } @@ -232,12 +257,14 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo } } - List substitutedValueParameters = getSubstitutedValueParameters(substitutedDescriptor, this, substitutor); + List substitutedValueParameters = getSubstitutedValueParameters( + substitutedDescriptor, newValueParameterDescriptors, substitutor + ); if (substitutedValueParameters == null) { return null; } - JetType substitutedReturnType = substitutor.substitute(getReturnType(), Variance.OUT_VARIANCE); + JetType substitutedReturnType = substitutor.substitute(newReturnType, Variance.OUT_VARIANCE); if (substitutedReturnType == null) { return null; } @@ -272,9 +299,12 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo } @Nullable - public static List getSubstitutedValueParameters(FunctionDescriptor substitutedDescriptor, @NotNull FunctionDescriptor functionDescriptor, @NotNull TypeSubstitutor substitutor) { + public static List getSubstitutedValueParameters( + FunctionDescriptor substitutedDescriptor, + @NotNull List unsubstitutedValueParameters, + @NotNull TypeSubstitutor substitutor + ) { List result = new ArrayList(); - List unsubstitutedValueParameters = functionDescriptor.getValueParameters(); for (ValueParameterDescriptor unsubstitutedValueParameter : unsubstitutedValueParameters) { // TODO : Lazy? JetType substitutedType = substitutor.substitute(unsubstitutedValueParameter.getType(), Variance.IN_VARIANCE); diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/PropertyDescriptorImpl.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/PropertyDescriptorImpl.java index b03a1c84f8b..546b9a39ef7 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/PropertyDescriptorImpl.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/PropertyDescriptorImpl.java @@ -255,7 +255,9 @@ public class PropertyDescriptorImpl extends VariableDescriptorImpl implements Pr setter.hasBody(), setter.isDefault(), kind, original == null ? null : original.getSetter(), SourceElement.NO_SOURCE ); if (newSetter != null) { - List substitutedValueParameters = FunctionDescriptorImpl.getSubstitutedValueParameters(newSetter, setter, substitutor); + List substitutedValueParameters = FunctionDescriptorImpl.getSubstitutedValueParameters( + newSetter, setter.getValueParameters(), substitutor + ); if (substitutedValueParameters == null) { // The setter is projected out, e.g. in this case: // trait Tr { var v: T }