From 6f180416b1df11ae7a66dd878cc81af9709f607b Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Wed, 9 Aug 2017 16:47:28 +0300 Subject: [PATCH] Pass SamConversionResolver explicitly cause it should be call site module-local --- .../org/jetbrains/kotlin/codegen/SamType.java | 2 +- .../java/sam/SingleAbstractMethodUtils.java | 66 +++++++++++++------ .../kotlin/synthetic/JavaSyntheticScopes.kt | 6 +- .../synthetic/SamAdapterFunctionsScope.kt | 24 ++++--- .../java/descriptors/JavaClassDescriptor.java | 3 +- .../descriptors/LazyJavaClassDescriptor.kt | 2 +- .../RedundantSamConstructorInspection.kt | 5 +- .../KotlinChangeSignatureUsageProcessor.kt | 2 +- 8 files changed, 69 insertions(+), 41 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/SamType.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/SamType.java index 3f961111231..6214f1f70d8 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/SamType.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/SamType.java @@ -50,7 +50,7 @@ public class SamType { @NotNull public KotlinType getKotlinFunctionType() { //noinspection ConstantConditions - return getJavaClassDescriptor().getFunctionTypeForSamInterface(); + return getJavaClassDescriptor().getDefaultFunctionTypeForSamInterface(); } @NotNull diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/sam/SingleAbstractMethodUtils.java b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/sam/SingleAbstractMethodUtils.java index dcc7eeb8244..1e0342a69d6 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/sam/SingleAbstractMethodUtils.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/sam/SingleAbstractMethodUtils.java @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations; import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl; import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl; import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl; +import org.jetbrains.kotlin.load.java.components.SamConversionResolver; import org.jetbrains.kotlin.load.java.descriptors.JavaClassConstructorDescriptor; import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor; import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor; @@ -57,29 +58,41 @@ public class SingleAbstractMethodUtils { } @Nullable - public static KotlinType getFunctionTypeForSamType(@NotNull KotlinType samType) { + public static SimpleType getFunctionTypeForSamInterface( + @NotNull JavaClassDescriptor clazz, + @Nullable SamConversionResolver samResolver + ) { + if (samResolver == null) { + return clazz.getDefaultFunctionTypeForSamInterface(); + } + + return samResolver.resolveFunctionTypeIfSamInterface(clazz); + } + + @Nullable + public static KotlinType getFunctionTypeForSamType(@NotNull KotlinType samType, @Nullable SamConversionResolver samResolver) { UnwrappedType unwrappedType = samType.unwrap(); if (unwrappedType instanceof FlexibleType) { - SimpleType lower = getFunctionTypeForSamType(((FlexibleType) unwrappedType).getLowerBound()); - SimpleType upper = getFunctionTypeForSamType(((FlexibleType) unwrappedType).getUpperBound()); + SimpleType lower = getFunctionTypeForSamType(((FlexibleType) unwrappedType).getLowerBound(), samResolver); + SimpleType upper = getFunctionTypeForSamType(((FlexibleType) unwrappedType).getUpperBound(), samResolver); assert (lower == null) == (upper == null) : "Illegal flexible type: " + unwrappedType; if (upper == null) return null; return KotlinTypeFactory.flexibleType(lower, upper); } else { - return getFunctionTypeForSamType((SimpleType) unwrappedType); + return getFunctionTypeForSamType((SimpleType) unwrappedType, samResolver); } } @Nullable - private static SimpleType getFunctionTypeForSamType(@NotNull SimpleType samType) { + private static SimpleType getFunctionTypeForSamType(@NotNull SimpleType samType, @Nullable SamConversionResolver samResolver) { // e.g. samType == Comparator? ClassifierDescriptor classifier = samType.getConstructor().getDeclarationDescriptor(); if (classifier instanceof JavaClassDescriptor) { // Function2 - SimpleType functionTypeDefault = ((JavaClassDescriptor) classifier).getFunctionTypeForSamInterface(); + SimpleType functionTypeDefault = getFunctionTypeForSamInterface((JavaClassDescriptor) classifier, samResolver); if (functionTypeDefault != null) { SimpleType noProjectionsSamType = SingleAbstractMethodUtilsKt.nonProjectionParametrization(samType); @@ -157,7 +170,8 @@ public class SingleAbstractMethodUtils { @NotNull public static SamConstructorDescriptor createSamConstructorFunction( @NotNull DeclarationDescriptor owner, - @NotNull JavaClassDescriptor samInterface + @NotNull JavaClassDescriptor samInterface, + @NotNull SamConversionResolver samResolver ) { assert getSingleAbstractMethodOrNull(samInterface) != null : samInterface; @@ -165,7 +179,7 @@ public class SingleAbstractMethodUtils { List samTypeParameters = samInterface.getTypeConstructor().getParameters(); SimpleType unsubstitutedSamType = samInterface.getDefaultType(); - initializeSamConstructorDescriptor(samInterface, result, samTypeParameters, unsubstitutedSamType); + initializeSamConstructorDescriptor(samInterface, result, samTypeParameters, unsubstitutedSamType, samResolver); return result; } @@ -174,11 +188,12 @@ public class SingleAbstractMethodUtils { @NotNull JavaClassDescriptor samInterface, @NotNull SimpleFunctionDescriptorImpl samConstructor, @NotNull List samTypeParameters, - @NotNull KotlinType unsubstitutedSamType + @NotNull KotlinType unsubstitutedSamType, + @NotNull SamConversionResolver samResolver ) { TypeParameters typeParameters = recreateAndInitializeTypeParameters(samTypeParameters, samConstructor); - KotlinType parameterTypeUnsubstituted = getFunctionTypeForSamType(unsubstitutedSamType); + KotlinType parameterTypeUnsubstituted = getFunctionTypeForSamType(unsubstitutedSamType, samResolver); assert parameterTypeUnsubstituted != null : "couldn't get function type for SAM type " + unsubstitutedSamType; KotlinType parameterType = typeParameters.substitutor.substitute(parameterTypeUnsubstituted, Variance.IN_VARIANCE); assert parameterType != null : "couldn't substitute type: " + parameterTypeUnsubstituted + @@ -207,20 +222,21 @@ public class SingleAbstractMethodUtils { public static SamConstructorDescriptor createTypeAliasSamConstructorFunction( @NotNull TypeAliasDescriptor typeAliasDescriptor, - @NotNull SamConstructorDescriptor underlyingSamConstructor + @NotNull SamConstructorDescriptor underlyingSamConstructor, + @NotNull SamConversionResolver samResolver ) { SamTypeAliasConstructorDescriptorImpl result = new SamTypeAliasConstructorDescriptorImpl(typeAliasDescriptor, underlyingSamConstructor); JavaClassDescriptor samInterface = underlyingSamConstructor.getBaseDescriptorForSynthetic(); List samTypeParameters = typeAliasDescriptor.getTypeConstructor().getParameters(); SimpleType unsubstitutedSamType = typeAliasDescriptor.getExpandedType(); - initializeSamConstructorDescriptor(samInterface, result, samTypeParameters, unsubstitutedSamType); + initializeSamConstructorDescriptor(samInterface, result, samTypeParameters, unsubstitutedSamType, samResolver); return result; } public static boolean isSamType(@NotNull KotlinType type) { - return getFunctionTypeForSamType(type) != null; + return getFunctionTypeForSamType(type, null) != null; } public static boolean isSamAdapterNecessary(@NotNull FunctionDescriptor fun) { @@ -233,7 +249,10 @@ public class SingleAbstractMethodUtils { } @NotNull - public static SamAdapterDescriptor createSamAdapterFunction(@NotNull JavaMethodDescriptor original) { + public static SamAdapterDescriptor createSamAdapterFunction( + @NotNull JavaMethodDescriptor original, + @NotNull SamConversionResolver samResolver + ) { SamAdapterFunctionDescriptor result = new SamAdapterFunctionDescriptor(original); return initSamAdapter(original, result, new FunctionInitializer() { @Override @@ -252,11 +271,14 @@ public class SingleAbstractMethodUtils { original.getVisibility() ); } - }); + }, samResolver); } @NotNull - public static SamAdapterDescriptor createSamAdapterConstructor(@NotNull JavaClassConstructorDescriptor original) { + public static SamAdapterDescriptor createSamAdapterConstructor( + @NotNull JavaClassConstructorDescriptor original, + @NotNull SamConversionResolver samResolver + ) { SamAdapterClassConstructorDescriptor result = new SamAdapterClassConstructorDescriptor(original); return initSamAdapter(original, result, new FunctionInitializer() { @Override @@ -268,14 +290,15 @@ public class SingleAbstractMethodUtils { result.initialize(valueParameters, original.getVisibility()); result.setReturnType(returnType); } - }); + }, samResolver); } @NotNull private static SamAdapterDescriptor initSamAdapter( @NotNull F original, @NotNull SamAdapterDescriptor adapter, - @NotNull FunctionInitializer initializer + @NotNull FunctionInitializer initializer, + @NotNull SamConversionResolver samResolver ) { TypeParameters typeParameters = recreateAndInitializeTypeParameters(original.getTypeParameters(), adapter); @@ -288,7 +311,7 @@ public class SingleAbstractMethodUtils { ", substitutor = " + substitutor; - List valueParameters = createValueParametersForSamAdapter(original, adapter, substitutor); + List valueParameters = createValueParametersForSamAdapter(original, adapter, substitutor, samResolver); initializer.initialize(typeParameters.descriptors, valueParameters, returnType); @@ -298,13 +321,14 @@ public class SingleAbstractMethodUtils { public static List createValueParametersForSamAdapter( @NotNull FunctionDescriptor original, @NotNull FunctionDescriptor samAdapter, - @NotNull TypeSubstitutor substitutor + @NotNull TypeSubstitutor substitutor, + @NotNull SamConversionResolver samResolver ) { List originalValueParameters = original.getValueParameters(); List valueParameters = new ArrayList<>(originalValueParameters.size()); for (ValueParameterDescriptor originalParam : originalValueParameters) { KotlinType originalType = originalParam.getType(); - KotlinType functionType = getFunctionTypeForSamType(originalType); + KotlinType functionType = getFunctionTypeForSamType(originalType, samResolver); KotlinType newTypeUnsubstituted = functionType != null ? functionType : originalType; KotlinType newType = substitutor.substitute(newTypeUnsubstituted, Variance.IN_VARIANCE); assert newType != null : "couldn't substitute type: " + newTypeUnsubstituted + ", substitutor = " + substitutor; diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/JavaSyntheticScopes.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/JavaSyntheticScopes.kt index 43cdb0fc6cd..4baf193cd43 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/JavaSyntheticScopes.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/JavaSyntheticScopes.kt @@ -18,16 +18,18 @@ package org.jetbrains.kotlin.synthetic import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.incremental.components.LookupTracker +import org.jetbrains.kotlin.load.java.components.SamConversionResolver import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes import org.jetbrains.kotlin.storage.StorageManager class JavaSyntheticScopes( storageManager: StorageManager, lookupTracker: LookupTracker, - languageVersionSettings: LanguageVersionSettings + languageVersionSettings: LanguageVersionSettings, + samConventionResolver: SamConversionResolver ): SyntheticScopes { override val scopes = listOf( JavaSyntheticPropertiesScope(storageManager, lookupTracker), - SamAdapterFunctionsScope(storageManager, languageVersionSettings) + SamAdapterFunctionsScope(storageManager, languageVersionSettings, samConventionResolver) ) } diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SamAdapterFunctionsScope.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SamAdapterFunctionsScope.kt index d2244f2254b..ddb01337536 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SamAdapterFunctionsScope.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SamAdapterFunctionsScope.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptorImpl import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor import org.jetbrains.kotlin.incremental.components.LookupLocation +import org.jetbrains.kotlin.load.java.components.SamConversionResolver import org.jetbrains.kotlin.load.java.descriptors.JavaClassConstructorDescriptor import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor @@ -49,7 +50,8 @@ interface SamAdapterExtensionFunctionDescriptor : FunctionDescriptor, SyntheticM class SamAdapterFunctionsScope( storageManager: StorageManager, - private val languageVersionSettings: LanguageVersionSettings + private val languageVersionSettings: LanguageVersionSettings, + private val samResolver: SamConversionResolver ) : SyntheticScope { private val extensionForFunction = storageManager.createMemoizedFunctionWithNullableValues { function -> extensionForFunctionNotCached(function) @@ -57,17 +59,17 @@ class SamAdapterFunctionsScope( private val samAdapterForStaticFunction = storageManager.createMemoizedFunction> { function -> - SingleAbstractMethodUtils.createSamAdapterFunction(function) + SingleAbstractMethodUtils.createSamAdapterFunction(function, samResolver) } private val samConstructorForClassifier = storageManager.createMemoizedFunction { classifier -> - SingleAbstractMethodUtils.createSamConstructorFunction(classifier.containingDeclaration, classifier) + SingleAbstractMethodUtils.createSamConstructorFunction(classifier.containingDeclaration, classifier, samResolver) } private val samConstructorForJavaConstructor = storageManager.createMemoizedFunction { constructor -> - SingleAbstractMethodUtils.createSamAdapterConstructor(constructor) as ClassConstructorDescriptor + SingleAbstractMethodUtils.createSamAdapterConstructor(constructor, samResolver) as ClassConstructorDescriptor } private val samConstructorForTypeAliasConstructor = @@ -82,7 +84,7 @@ class SamAdapterFunctionsScope( if (!SingleAbstractMethodUtils.isSamAdapterNecessary(function)) return null if (function.returnType == null) return null if (function.isHiddenInResolution(languageVersionSettings)) return null - return MyFunctionDescriptor.create(function) + return MyFunctionDescriptor.create(function, samResolver) } override fun getSyntheticMemberFunctions(receiverTypes: Collection, name: Name, location: LookupLocation): Collection { @@ -199,15 +201,16 @@ class SamAdapterFunctionsScope( return getTypeAliasSamConstructor(classifier) } - if (classifier !is LazyJavaClassDescriptor || classifier.functionTypeForSamInterface == null) return null + if (classifier !is LazyJavaClassDescriptor || classifier.defaultFunctionTypeForSamInterface == null) return null return samConstructorForClassifier(classifier) } private fun getTypeAliasSamConstructor(classifier: TypeAliasDescriptor): SamConstructorDescriptor? { val classDescriptor = classifier.classDescriptor ?: return null - if (classDescriptor !is LazyJavaClassDescriptor || classDescriptor.functionTypeForSamInterface == null) return null + if (classDescriptor !is LazyJavaClassDescriptor || classDescriptor.defaultFunctionTypeForSamInterface == null) return null - return SingleAbstractMethodUtils.createTypeAliasSamConstructorFunction(classifier, samConstructorForClassifier(classDescriptor)) + return SingleAbstractMethodUtils.createTypeAliasSamConstructorFunction( + classifier, samConstructorForClassifier(classDescriptor), samResolver) } private class MyFunctionDescriptor( @@ -227,7 +230,7 @@ class SamAdapterFunctionsScope( } companion object { - fun create(sourceFunction: FunctionDescriptor): MyFunctionDescriptor { + fun create(sourceFunction: FunctionDescriptor, samResolver: SamConversionResolver): MyFunctionDescriptor { val descriptor = MyFunctionDescriptor(sourceFunction.containingDeclaration, null, sourceFunction.annotations, @@ -243,7 +246,8 @@ class SamAdapterFunctionsScope( val typeSubstitutor = DescriptorSubstitutor.substituteTypeParameters(sourceTypeParams, TypeSubstitution.EMPTY, descriptor, typeParameters) val returnType = typeSubstitutor.safeSubstitute(sourceFunction.returnType!!, Variance.INVARIANT) - val valueParameters = SingleAbstractMethodUtils.createValueParametersForSamAdapter(sourceFunction, descriptor, typeSubstitutor) + val valueParameters = SingleAbstractMethodUtils.createValueParametersForSamAdapter( + sourceFunction, descriptor, typeSubstitutor, samResolver) val visibility = syntheticVisibility(sourceFunction, isUsedForExtension = false) diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaClassDescriptor.java b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaClassDescriptor.java index c8f9e978446..6d769cc868d 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaClassDescriptor.java +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/descriptors/JavaClassDescriptor.java @@ -21,8 +21,9 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor; import org.jetbrains.kotlin.types.SimpleType; public interface JavaClassDescriptor extends ClassDescriptor { + // Use SingleAbstractMethodUtils.getFunctionTypeForSamInterface() where possible. This is only a fallback @Nullable - SimpleType getFunctionTypeForSamInterface(); + SimpleType getDefaultFunctionTypeForSamInterface(); /** * May return false even in case when the class is not SAM interface, but returns true only if it's definitely not a SAM. diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassDescriptor.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassDescriptor.kt index 78abae9a9aa..b36671ebf5c 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassDescriptor.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaClassDescriptor.kt @@ -135,7 +135,7 @@ class LazyJavaClassDescriptor( override fun getDeclaredTypeParameters() = declaredParameters() - override fun getFunctionTypeForSamInterface(): SimpleType? = c.components.samConversionResolver.resolveFunctionTypeIfSamInterface(this) + override fun getDefaultFunctionTypeForSamInterface(): SimpleType? = c.components.samConversionResolver.resolveFunctionTypeIfSamInterface(this) override fun isDefinitelyNotSamInterface(): Boolean { if (kind != ClassKind.INTERFACE) return true diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantSamConstructorInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantSamConstructorInspection.kt index 88b1ef4e765..5d319e323ce 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantSamConstructorInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantSamConstructorInspection.kt @@ -232,10 +232,7 @@ class RedundantSamConstructorInspection : AbstractKotlinInspection() { val samAdapterOriginalFunction = SamCodegenUtil.getOriginalIfSamAdapter(samAdapter)?.original if (samAdapterOriginalFunction != originalFunction) return false - val parametersWithSamTypeCount = originalFunction.valueParameters.count { - SingleAbstractMethodUtils.getFunctionTypeForSamType(it.type) != null - } - + val parametersWithSamTypeCount = originalFunction.valueParameters.count { SingleAbstractMethodUtils.isSamType(it.type) } return parametersWithSamTypeCount == samConstructorsCount } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/KotlinChangeSignatureUsageProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/KotlinChangeSignatureUsageProcessor.kt index 1e864e6fad8..85976ed85ec 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/KotlinChangeSignatureUsageProcessor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/KotlinChangeSignatureUsageProcessor.kt @@ -399,7 +399,7 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor { if (method.containingClass == null) return val containingDescriptor = method.getJavaMethodDescriptor()?.containingDeclaration as? JavaClassDescriptor ?: return - if (containingDescriptor.functionTypeForSamInterface == null) return + if (containingDescriptor.defaultFunctionTypeForSamInterface == null) return val samClass = method.containingClass ?: return for (ref in ReferencesSearch.search(samClass)) {