Introduce synthetic scope for constructors of fun interfaces
#KT-37434 Fixed
This commit is contained in:
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
|
|||||||
import org.jetbrains.kotlin.resolve.sam.SamConversionOracle
|
import org.jetbrains.kotlin.resolve.sam.SamConversionOracle
|
||||||
import org.jetbrains.kotlin.resolve.scopes.SyntheticScope
|
import org.jetbrains.kotlin.resolve.scopes.SyntheticScope
|
||||||
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
|
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.synthetic.FunInterfaceConstructorsSyntheticScope
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
|
|
||||||
class JavaSyntheticScopes(
|
class JavaSyntheticScopes(
|
||||||
@@ -69,7 +70,10 @@ class JavaSyntheticScopes(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
scopes = listOf(javaSyntheticPropertiesScope, samAdapterFunctionsScope) + scopesFromExtensions
|
val funInterfaceConstructorsScopes =
|
||||||
|
FunInterfaceConstructorsSyntheticScope(storageManager, lookupTracker, samConventionResolver, samConversionOracle)
|
||||||
|
|
||||||
|
scopes = listOf(javaSyntheticPropertiesScope, samAdapterFunctionsScope, funInterfaceConstructorsScopes) + scopesFromExtensions
|
||||||
|
|
||||||
if (samConversionPerArgumentIsEnabled) {
|
if (samConversionPerArgumentIsEnabled) {
|
||||||
val forceEnabledSamAdapterFunctionsScope = SamAdapterFunctionsScope(
|
val forceEnabledSamAdapterFunctionsScope = SamAdapterFunctionsScope(
|
||||||
|
|||||||
+4
-4
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.incremental.record
|
|||||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassConstructorDescriptor
|
import org.jetbrains.kotlin.load.java.descriptors.JavaClassConstructorDescriptor
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
|
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
|
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
|
||||||
|
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaClassDescriptor
|
||||||
import org.jetbrains.kotlin.load.java.sam.JavaSingleAbstractMethodUtils
|
import org.jetbrains.kotlin.load.java.sam.JavaSingleAbstractMethodUtils
|
||||||
import org.jetbrains.kotlin.load.java.sam.SamAdapterDescriptor
|
import org.jetbrains.kotlin.load.java.sam.SamAdapterDescriptor
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -71,7 +72,7 @@ class SamAdapterFunctionsScope(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val samConstructorForClassifier =
|
private val samConstructorForClassifier =
|
||||||
storageManager.createMemoizedFunction<ClassDescriptor, SamConstructorDescriptor> { classifier ->
|
storageManager.createMemoizedFunction<JavaClassDescriptor, SamConstructorDescriptor> { classifier ->
|
||||||
createSamConstructorFunction(classifier.containingDeclaration, classifier, samResolver, samConversionOracle)
|
createSamConstructorFunction(classifier.containingDeclaration, classifier, samResolver, samConversionOracle)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -257,15 +258,14 @@ class SamAdapterFunctionsScope(
|
|||||||
return getTypeAliasSamConstructor(classifier)
|
return getTypeAliasSamConstructor(classifier)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (classifier !is ClassDescriptor) return null
|
if (classifier !is LazyJavaClassDescriptor || classifier.defaultFunctionTypeForSamInterface == null) return null
|
||||||
if (!JavaSingleAbstractMethodUtils.isSamClassDescriptor(classifier)) return null
|
|
||||||
|
|
||||||
return samConstructorForClassifier(classifier)
|
return samConstructorForClassifier(classifier)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getTypeAliasSamConstructor(classifier: TypeAliasDescriptor): SamConstructorDescriptor? {
|
private fun getTypeAliasSamConstructor(classifier: TypeAliasDescriptor): SamConstructorDescriptor? {
|
||||||
val classDescriptor = classifier.classDescriptor ?: return null
|
val classDescriptor = classifier.classDescriptor ?: return null
|
||||||
if (!JavaSingleAbstractMethodUtils.isSamClassDescriptor(classDescriptor)) return null
|
if (classDescriptor !is LazyJavaClassDescriptor || classDescriptor.defaultFunctionTypeForSamInterface == null) return null
|
||||||
|
|
||||||
return createTypeAliasSamConstructorFunction(
|
return createTypeAliasSamConstructorFunction(
|
||||||
classifier, samConstructorForClassifier(classDescriptor), samResolver, samConversionOracle
|
classifier, samConstructorForClassifier(classDescriptor), samResolver, samConversionOracle
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
fun interface Foo<T> {
|
||||||
|
fun invoke(): T
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
Foo { }
|
||||||
|
Foo<Unit> { }
|
||||||
|
Foo<String> <!TYPE_MISMATCH!>{ }<!>
|
||||||
|
Foo<String> { "" }
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun test(): kotlin.Unit
|
||||||
|
|
||||||
|
public fun interface Foo</*0*/ T> {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public abstract fun invoke(): T
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
@@ -10,4 +10,5 @@ fun foo(k: KRunnable) = k.invoke()
|
|||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
foo { "OK" }
|
foo { "OK" }
|
||||||
|
foo(KRunnable { "OK "})
|
||||||
}
|
}
|
||||||
@@ -10,4 +10,5 @@ fun foo(k: KRunnable) = k.invoke()
|
|||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
foo { "OK" }
|
foo { "OK" }
|
||||||
|
foo(KRunnable { "OK " })
|
||||||
}
|
}
|
||||||
@@ -10,4 +10,5 @@ fun foo(k: KRunnable) = k.invoke()
|
|||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
foo { "OK" }
|
foo { "OK" }
|
||||||
|
foo(KRunnable { "OK " })
|
||||||
}
|
}
|
||||||
+5
@@ -28,6 +28,11 @@ public class DiagnosticsTestWithJsStdLibGenerated extends AbstractDiagnosticsTes
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJsStdLib"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithJsStdLib"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("funConstructorCallJS.kt")
|
||||||
|
public void testFunConstructorCallJS() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/testsWithJsStdLib/funConstructorCallJS.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("implementingFunction.kt")
|
@TestMetadata("implementingFunction.kt")
|
||||||
public void testImplementingFunction() throws Exception {
|
public void testImplementingFunction() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/testsWithJsStdLib/implementingFunction.kt");
|
runTest("compiler/testData/diagnostics/testsWithJsStdLib/implementingFunction.kt");
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.synthetic.FunInterfaceConstructorsScopeProvider
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
|
|
||||||
@@ -96,7 +97,7 @@ interface SyntheticScope {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@DefaultImplementation(impl = SyntheticScopes.Empty::class)
|
@DefaultImplementation(impl = FunInterfaceConstructorsScopeProvider::class)
|
||||||
interface SyntheticScopes {
|
interface SyntheticScopes {
|
||||||
val scopes: Collection<SyntheticScope>
|
val scopes: Collection<SyntheticScope>
|
||||||
|
|
||||||
|
|||||||
+80
@@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.resolve.scopes.synthetic
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||||
|
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||||
|
import org.jetbrains.kotlin.incremental.record
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.resolve.sam.*
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.ResolutionScope
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.SyntheticScope
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
|
||||||
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
|
|
||||||
|
class FunInterfaceConstructorsScopeProvider(
|
||||||
|
storageManager: StorageManager,
|
||||||
|
lookupTracker: LookupTracker,
|
||||||
|
samResolver: SamConversionResolver,
|
||||||
|
samConversionOracle: SamConversionOracle
|
||||||
|
) : SyntheticScopes {
|
||||||
|
override val scopes: Collection<SyntheticScope> = listOf(
|
||||||
|
FunInterfaceConstructorsSyntheticScope(storageManager, lookupTracker, samResolver, samConversionOracle)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
class FunInterfaceConstructorsSyntheticScope(
|
||||||
|
storageManager: StorageManager,
|
||||||
|
private val lookupTracker: LookupTracker,
|
||||||
|
private val samResolver: SamConversionResolver,
|
||||||
|
private val samConversionOracle: SamConversionOracle
|
||||||
|
) : SyntheticScope.Default() {
|
||||||
|
|
||||||
|
private val samConstructorForClassifier =
|
||||||
|
storageManager.createMemoizedFunction<ClassDescriptor, SamConstructorDescriptor> { classifier ->
|
||||||
|
createSamConstructorFunction(classifier.containingDeclaration, classifier, samResolver, samConversionOracle)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getSyntheticConstructors(scope: ResolutionScope, name: Name, location: LookupLocation): Collection<FunctionDescriptor> {
|
||||||
|
val classifier = scope.getContributedClassifier(name, location) ?: return emptyList()
|
||||||
|
recordSamLookupsToClassifier(classifier, location)
|
||||||
|
|
||||||
|
return listOfNotNull(getSamConstructor(classifier))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getSyntheticConstructors(scope: ResolutionScope): Collection<FunctionDescriptor> {
|
||||||
|
val classifiers = scope.getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS).filterIsInstance<ClassifierDescriptor>()
|
||||||
|
|
||||||
|
return classifiers.mapNotNull { getSamConstructor(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getSamConstructor(classifier: ClassifierDescriptor): SamConstructorDescriptor? {
|
||||||
|
if (classifier is TypeAliasDescriptor) {
|
||||||
|
return getTypeAliasSamConstructor(classifier)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (classifier !is ClassDescriptor) return null
|
||||||
|
if (!classifier.isFun) return null
|
||||||
|
|
||||||
|
return samConstructorForClassifier(classifier)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getTypeAliasSamConstructor(classifier: TypeAliasDescriptor): SamConstructorDescriptor? {
|
||||||
|
val classDescriptor = classifier.classDescriptor ?: return null
|
||||||
|
if (!classDescriptor.isFun) return null
|
||||||
|
|
||||||
|
return createTypeAliasSamConstructorFunction(
|
||||||
|
classifier, samConstructorForClassifier(classDescriptor), samResolver, samConversionOracle
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun recordSamLookupsToClassifier(classifier: ClassifierDescriptor, location: LookupLocation) {
|
||||||
|
if (classifier !is ClassDescriptor || !classifier.isFun) return
|
||||||
|
lookupTracker.record(location, classifier, SAM_LOOKUP_NAME)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user