Extract 'doSubstitute' parameters into SubstitutionConfiguration

This commit is contained in:
Denis Zharkov
2015-11-30 18:58:30 +03:00
parent a197fc8cb8
commit e2b51f30ed
8 changed files with 222 additions and 120 deletions
@@ -157,45 +157,17 @@ class SamAdapterFunctionsScope(storageManager: StorageManager) : BaseImportingSc
}
}
override fun doSubstitute(
originalSubstitutor: TypeSubstitutor,
newOwner: DeclarationDescriptor,
newModality: Modality,
newVisibility: Visibility,
isOperator: Boolean,
isInfix: Boolean,
isExternal: Boolean,
isInline: Boolean,
isTailrec: Boolean,
hasStableParameterNames: Boolean,
hasSynthesizedParameterNames: Boolean,
original: FunctionDescriptor?,
copyOverrides: Boolean,
kind: CallableMemberDescriptor.Kind,
newValueParameterDescriptors: MutableList<ValueParameterDescriptor>,
newExtensionReceiverParameterType: KotlinType?,
newReturnType: KotlinType,
name: Name?,
preserveSource: Boolean,
signatureChange: Boolean
): FunctionDescriptor? {
val descriptor = super.doSubstitute(
originalSubstitutor, newOwner, newModality, newVisibility,
isOperator, isInfix, isExternal, isInline, isTailrec, hasStableParameterNames, hasSynthesizedParameterNames, original,
copyOverrides, kind, newValueParameterDescriptors, newExtensionReceiverParameterType, newReturnType, name,
preserveSource, signatureChange)
as MyFunctionDescriptor? ?: return null
if (original == null) {
throw UnsupportedOperationException("doSubstitute with no original should not be called for synthetic extension")
}
override fun doSubstitute(configuration: CopyConfiguration): FunctionDescriptor? {
val descriptor = super.doSubstitute(configuration) as MyFunctionDescriptor? ?: return null
val original = configuration.original
?: throw UnsupportedOperationException("doSubstitute with no original should not be called for synthetic extension")
original as MyFunctionDescriptor
assert(original.original == original) { "original in doSubstitute should have no other original" }
val substitutionMap = HashMap<TypeConstructor, TypeProjection>()
for (typeParameter in original.typeParameters) {
val typeProjection = originalSubstitutor.substitution[typeParameter.defaultType] ?: continue
val typeProjection = configuration.originalSubstitutor.substitution[typeParameter.defaultType] ?: continue
val sourceTypeParameter = original.toSourceFunctionTypeParameters!![typeParameter]!!
substitutionMap[sourceTypeParameter.typeConstructor] = typeProjection
@@ -0,0 +1,15 @@
// FILE: A.java
import java.util.*;
public interface A {
<R> void foo();
}
// FILE: B.java
public interface B extends A {}
// FILE: k.kt
class C(x: A) : A by x, B {}
@@ -0,0 +1,23 @@
package
public interface A {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract fun </*0*/ R : kotlin.Any!> foo(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface B : A {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public abstract override /*1*/ /*fake_override*/ fun </*0*/ R : kotlin.Any!> foo(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class C : A, B {
public constructor C(/*0*/ x: A)
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*2*/ /*delegation*/ fun </*0*/ R : kotlin.Any!> foo(): kotlin.Unit
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -11370,6 +11370,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/platformTypes"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("delegateByComplexInheritance.kt")
public void testDelegateByComplexInheritance() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/delegateByComplexInheritance.kt");
doTest(fileName);
}
@TestMetadata("dereference.kt")
public void testDereference() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/dereference.kt");
@@ -23,7 +23,6 @@ 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.KotlinType;
import org.jetbrains.kotlin.types.TypeSubstitutor;
import org.jetbrains.kotlin.util.OperatorChecks;
import java.util.List;
@@ -142,12 +141,13 @@ public class JavaMethodDescriptor extends SimpleFunctionDescriptorImpl implement
// 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(),
isOperator(), isInfix(), isExternal(), isInline(), isTailrec(), hasStableParameterNames(), hasSynthesizedParameterNames(),
getOriginal(), /* copyOverrides = */ true, getKind(),
enhancedValueParameters, enhancedReceiverType, enhancedReturnType,
null, /* preserveSource */false, /* signatureChange = */ false);
JavaMethodDescriptor enhancedMethod =
(JavaMethodDescriptor) newCopyBuilder()
.setValueParameters(enhancedValueParameters)
.setReturnType(enhancedReturnType)
.setExtensionReceiverType(enhancedReceiverType)
.setOriginal(getOriginal())
.build();
assert enhancedMethod != null : "null after substitution while enhancing " + toString();
return enhancedMethod;
@@ -147,10 +147,14 @@ public class ConstructorDescriptorImpl extends FunctionDescriptorImpl implements
@NotNull
@Override
public ConstructorDescriptor copy(DeclarationDescriptor newOwner, Modality modality, Visibility visibility, Kind kind, boolean copyOverrides) {
//noinspection ConstantConditions
return (ConstructorDescriptor) doSubstitute(
TypeSubstitutor.EMPTY, newOwner, modality, visibility,
isOperator(), isInfix(), isExternal(), isInline(), isTailrec(), hasStableParameterNames(), hasSynthesizedParameterNames(),
null, copyOverrides, kind
newCopyBuilder()
.setOwner(newOwner)
.setModality(modality)
.setVisibility(visibility)
.setKind(kind)
.setCopyOverrides(copyOverrides)
);
}
}
@@ -261,34 +261,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
if (originalSubstitutor.isEmpty()) {
return this;
}
return doSubstitute(originalSubstitutor, getContainingDeclaration(), modality, visibility,
isOperator, isInfix, isExternal, isInline, isTailrec,
hasStableParameterNames, hasSynthesizedParameterNames,
getOriginal(), true, getKind());
}
@Nullable
protected FunctionDescriptor doSubstitute(@NotNull TypeSubstitutor originalSubstitutor,
@NotNull DeclarationDescriptor newOwner,
@NotNull Modality newModality,
@NotNull Visibility newVisibility,
boolean isOperator,
boolean isInfix,
boolean isExternal,
boolean isInline,
boolean isTailrec,
boolean hasStableParameterNames,
boolean hasSynthesizedParameterNames,
@Nullable FunctionDescriptor original,
boolean copyOverrides,
@NotNull Kind kind
) {
return doSubstitute(originalSubstitutor,
newOwner, newModality, newVisibility, isOperator, isInfix, isExternal, isInline, isTailrec,
hasStableParameterNames, hasSynthesizedParameterNames,
original, copyOverrides, kind,
getValueParameters(), getExtensionReceiverParameterType(), getReturnType(),
null, /* preserveSource = */ false, /* signatureChange */ false);
return doSubstitute(newCopyBuilder(originalSubstitutor).setOriginal(getOriginal()));
}
@Nullable
@@ -297,41 +270,157 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
return extensionReceiverParameter.getType();
}
public class CopyConfiguration {
protected @NotNull TypeSubstitutor originalSubstitutor;
protected @NotNull DeclarationDescriptor newOwner;
protected @NotNull Modality newModality;
protected @NotNull Visibility newVisibility;
protected @Nullable FunctionDescriptor original = null;
protected @NotNull Kind kind;
protected @NotNull List<ValueParameterDescriptor> newValueParameterDescriptors;
protected @Nullable KotlinType newExtensionReceiverParameterType;
protected @NotNull KotlinType newReturnType;
protected @Nullable Name name;
protected boolean copyOverrides;
protected boolean signatureChange;
public CopyConfiguration(
@NotNull TypeSubstitutor originalSubstitutor,
@NotNull DeclarationDescriptor newOwner,
@NotNull Modality newModality,
@NotNull Visibility newVisibility,
@NotNull Kind kind,
@NotNull List<ValueParameterDescriptor> newValueParameterDescriptors,
@Nullable KotlinType newExtensionReceiverParameterType,
@NotNull KotlinType newReturnType,
@Nullable Name name
) {
this.originalSubstitutor = originalSubstitutor;
this.newOwner = newOwner;
this.newModality = newModality;
this.newVisibility = newVisibility;
this.kind = kind;
this.newValueParameterDescriptors = newValueParameterDescriptors;
this.newExtensionReceiverParameterType = newExtensionReceiverParameterType;
this.newReturnType = newReturnType;
this.name = name;
this.copyOverrides = true;
this.signatureChange = false;
}
@NotNull
protected CopyConfiguration setOwner(@NotNull DeclarationDescriptor owner) {
this.newOwner = owner;
return this;
}
@NotNull
public CopyConfiguration setModality(@NotNull Modality modality) {
this.newModality = modality;
return this;
}
@NotNull
public CopyConfiguration setVisibility(@NotNull Visibility visibility) {
this.newVisibility = visibility;
return this;
}
@NotNull
public CopyConfiguration setKind(@NotNull Kind kind) {
this.kind = kind;
return this;
}
@NotNull
public CopyConfiguration setCopyOverrides(boolean copyOverrides) {
this.copyOverrides = copyOverrides;
return this;
}
@NotNull
public CopyConfiguration setName(@NotNull Name name) {
this.name = name;
return this;
}
@NotNull
public CopyConfiguration setValueParameters(@NotNull List<ValueParameterDescriptor> parameters) {
this.newValueParameterDescriptors = parameters;
return this;
}
@NotNull
public CopyConfiguration setTypeParameters(@NotNull List<TypeParameterDescriptor> parameters) {
this.newTypeParameters = parameters;
return this;
}
public CopyConfiguration setReturnType(@NotNull KotlinType type) {
this.newReturnType = type;
return this;
}
public CopyConfiguration setExtensionReceiverType(@Nullable KotlinType type) {
this.newExtensionReceiverParameterType = type;
return this;
}
@NotNull
public CopyConfiguration setOriginal(@NotNull FunctionDescriptor original) {
this.original = original;
return this;
}
@NotNull
public CopyConfiguration setSignatureChange() {
this.signatureChange = true;
return this;
}
public FunctionDescriptor build() {
return doSubstitute(this);
}
@Nullable
public FunctionDescriptor getOriginal() {
return original;
}
@NotNull
public TypeSubstitutor getOriginalSubstitutor() {
return originalSubstitutor;
}
}
@NotNull
public CopyConfiguration newCopyBuilder() {
return newCopyBuilder(TypeSubstitutor.EMPTY);
}
@NotNull
private CopyConfiguration newCopyBuilder(@NotNull TypeSubstitutor substitutor) {
return new CopyConfiguration(
substitutor,
getContainingDeclaration(), getModality(), getVisibility(), getKind(), getValueParameters(),
getExtensionReceiverParameterType(), getReturnType(), null);
}
@Nullable
protected FunctionDescriptor doSubstitute(
@NotNull TypeSubstitutor originalSubstitutor,
@NotNull DeclarationDescriptor newOwner,
@NotNull Modality newModality,
@NotNull Visibility newVisibility,
boolean isOperator,
boolean isInfix,
boolean isExternal,
boolean isInline,
boolean isTailrec,
boolean hasStableParameterNames,
boolean hasSynthesizedParameterNames,
@Nullable FunctionDescriptor original,
boolean copyOverrides,
@NotNull Kind kind,
@NotNull List<ValueParameterDescriptor> newValueParameterDescriptors,
@Nullable KotlinType newExtensionReceiverParameterType,
@NotNull KotlinType newReturnType,
@Nullable Name name,
boolean preserveSource,
boolean signatureChange
) {
FunctionDescriptorImpl substitutedDescriptor = createSubstitutedCopy(newOwner, original, kind, name, preserveSource);
protected FunctionDescriptor doSubstitute(@NotNull CopyConfiguration configuration) {
FunctionDescriptorImpl substitutedDescriptor = createSubstitutedCopy(
configuration.newOwner, configuration.original, configuration.kind, configuration.name,
/* preserveSource = */ configuration.signatureChange);
List<TypeParameterDescriptor> originalTypeParameters = getTypeParameters();
List<TypeParameterDescriptor> substitutedTypeParameters = new ArrayList<TypeParameterDescriptor>(originalTypeParameters.size());
TypeSubstitutor substitutor = DescriptorSubstitutor.substituteTypeParameters(
originalTypeParameters, originalSubstitutor.getSubstitution(), substitutedDescriptor, substitutedTypeParameters
originalTypeParameters, configuration.originalSubstitutor.getSubstitution(), substitutedDescriptor, substitutedTypeParameters
);
KotlinType substitutedReceiverParameterType = null;
if (newExtensionReceiverParameterType != null) {
substitutedReceiverParameterType = substitutor.substitute(newExtensionReceiverParameterType, Variance.IN_VARIANCE);
if (configuration.newExtensionReceiverParameterType != null) {
substitutedReceiverParameterType = substitutor.substitute(configuration.newExtensionReceiverParameterType, Variance.IN_VARIANCE);
if (substitutedReceiverParameterType == null) {
return null;
}
@@ -356,13 +445,13 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
}
List<ValueParameterDescriptor> substitutedValueParameters = getSubstitutedValueParameters(
substitutedDescriptor, newValueParameterDescriptors, substitutor
substitutedDescriptor, configuration.newValueParameterDescriptors, substitutor
);
if (substitutedValueParameters == null) {
return null;
}
KotlinType substitutedReturnType = substitutor.substitute(newReturnType, Variance.OUT_VARIANCE);
KotlinType substitutedReturnType = substitutor.substitute(configuration.newReturnType, Variance.OUT_VARIANCE);
if (substitutedReturnType == null) {
return null;
}
@@ -373,8 +462,8 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
substitutedTypeParameters,
substitutedValueParameters,
substitutedReturnType,
newModality,
newVisibility
configuration.newModality,
configuration.newVisibility
);
substitutedDescriptor.setOperator(isOperator);
substitutedDescriptor.setInfix(isInfix);
@@ -384,13 +473,13 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
substitutedDescriptor.setHasStableParameterNames(hasStableParameterNames);
substitutedDescriptor.setHasSynthesizedParameterNames(hasSynthesizedParameterNames);
if (signatureChange || getInitialSignatureDescriptor() != null) {
if (configuration.signatureChange || getInitialSignatureDescriptor() != null) {
FunctionDescriptor initialSignature = (getInitialSignatureDescriptor() != null ? getInitialSignatureDescriptor() : this);
FunctionDescriptor initialSignatureSubstituted = initialSignature.substitute(substitutor);
substitutedDescriptor.setInitialSignatureDescriptor(initialSignatureSubstituted);
}
if (copyOverrides) {
if (configuration.copyOverrides) {
for (FunctionDescriptor overriddenFunction : overriddenFunctions) {
substitutedDescriptor.addOverriddenDescriptor(overriddenFunction.substitute(substitutor));
}
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.TypeSubstitutor;
import java.util.List;
@@ -100,33 +99,27 @@ public class SimpleFunctionDescriptorImpl extends FunctionDescriptorImpl impleme
Kind kind,
boolean copyOverrides
) {
return (SimpleFunctionDescriptorImpl) doSubstitute(
TypeSubstitutor.EMPTY, newOwner, modality, visibility,
isOperator(), isInfix(), isExternal(), isInline(), isTailrec(),
hasStableParameterNames(), hasSynthesizedParameterNames(),
null, copyOverrides, kind
);
//noinspection ConstantConditions
return (SimpleFunctionDescriptor) newCopyBuilder()
.setOwner(newOwner)
.setModality(modality)
.setVisibility(visibility)
.setKind(kind)
.setCopyOverrides(copyOverrides)
.build();
}
@NotNull
@Override
public SimpleFunctionDescriptor createRenamedCopy(@NotNull Name name) {
//noinspection ConstantConditions
return (SimpleFunctionDescriptorImpl) doSubstitute(
TypeSubstitutor.EMPTY, getContainingDeclaration(), getModality(), getVisibility(),
isOperator(), isInfix(), isExternal(), isInline(), isTailrec(), hasStableParameterNames(), hasSynthesizedParameterNames(),
null, /* copyOverrides = */ true, getKind(), getValueParameters(), getExtensionReceiverParameterType(), getReturnType(), name,
/* preserveSource = */ true, /* signatureChange = */ true);
return (SimpleFunctionDescriptor) newCopyBuilder().setName(name).setSignatureChange().build();
}
@NotNull
@Override
public SimpleFunctionDescriptor createCopyWithNewValueParameters(@NotNull List<ValueParameterDescriptor> valueParameters) {
//noinspection ConstantConditions
return (SimpleFunctionDescriptorImpl) doSubstitute(
TypeSubstitutor.EMPTY, getContainingDeclaration(), getModality(), getVisibility(),
isOperator(), isInfix(), isExternal(), isInline(), isTailrec(), hasStableParameterNames(), hasSynthesizedParameterNames(),
null, /* copyOverrides = */ true, getKind(), valueParameters, getExtensionReceiverParameterType(), getReturnType(), null,
/* preserveSource = */ true, /* signatureChange = */ true);
return (SimpleFunctionDescriptor) newCopyBuilder().setValueParameters(valueParameters).setSignatureChange().build();
}
}