FIC: Move sam related methods to ClassDescriptor, fix JVM backend part

This commit is contained in:
Mikhail Zarechenskiy
2019-11-18 11:42:25 +03:00
parent 87e79e72a9
commit 562f0e62a3
10 changed files with 88 additions and 19 deletions
@@ -72,11 +72,8 @@ public class SamType {
@NotNull
public KotlinType getKotlinFunctionType() {
ClassDescriptor descriptor = getClassDescriptor();
if (descriptor instanceof JavaClassDescriptor) {
return ((JavaClassDescriptor) descriptor).getDefaultFunctionTypeForSamInterface();
}
return null;
//noinspection ConstantConditions
return descriptor.getDefaultFunctionTypeForSamInterface();
}
@NotNull
@@ -45,4 +45,5 @@ interface LazyClassContext {
val delegationFilter: DelegationFilter
val wrappedTypeFactory: WrappedTypeFactory
val kotlinTypeChecker: NewKotlinTypeChecker
val samConversionResolver: SamConversionResolver
}
@@ -83,6 +83,7 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext {
private DelegationFilter delegationFilter;
private WrappedTypeFactory wrappedTypeFactory;
private PlatformDiagnosticSuppressor platformDiagnosticSuppressor;
private SamConversionResolver samConversionResolver;
private final SyntheticResolveExtension syntheticResolveExtension;
@@ -150,6 +151,11 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext {
this.platformDiagnosticSuppressor = platformDiagnosticSuppressor;
}
@Inject
public void setSamConversionResolver(@NotNull SamConversionResolver samConversionResolver) {
this.samConversionResolver = samConversionResolver;
}
// Only calls from injectors expected
@Deprecated
public ResolveSession(
@@ -477,4 +483,10 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext {
public NewKotlinTypeChecker getKotlinTypeChecker() {
return kotlinTypeChecker;
}
@NotNull
@Override
public SamConversionResolver getSamConversionResolver() {
return samConversionResolver;
}
}
@@ -421,6 +421,17 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
return companionObjectDescriptor.invoke();
}
@Nullable
@Override
public SimpleType getDefaultFunctionTypeForSamInterface() {
return c.getSamConversionResolver().resolveFunctionTypeIfSamInterface(this);
}
@Override
public boolean isDefinitelyNotSamInterface() {
return !isFun();
}
@NotNull
@ReadOnly
public List<ClassDescriptor> getDescriptorsForExtraCompanionObjects() {
@@ -67,7 +67,8 @@ class LocalClassifierAnalyzer(
private val languageVersionSettings: LanguageVersionSettings,
private val delegationFilter: DelegationFilter,
private val wrappedTypeFactory: WrappedTypeFactory,
private val kotlinTypeChecker: NewKotlinTypeChecker
private val kotlinTypeChecker: NewKotlinTypeChecker,
private val samConversionResolver: SamConversionResolver
) {
fun processClassOrObject(
scope: LexicalWritableScope?,
@@ -101,7 +102,8 @@ class LocalClassifierAnalyzer(
SyntheticResolveExtension.getInstance(project),
delegationFilter,
wrappedTypeFactory,
kotlinTypeChecker
kotlinTypeChecker,
samConversionResolver
),
analyzerServices
)
@@ -130,7 +132,8 @@ class LocalClassDescriptorHolder(
val syntheticResolveExtension: SyntheticResolveExtension,
val delegationFilter: DelegationFilter,
val wrappedTypeFactory: WrappedTypeFactory,
val kotlinTypeChecker: NewKotlinTypeChecker
val kotlinTypeChecker: NewKotlinTypeChecker,
val samConversionResolver: SamConversionResolver
) {
// We do not need to synchronize here, because this code is used strictly from one thread
private var classDescriptor: ClassDescriptor? = null
@@ -171,6 +174,7 @@ class LocalClassDescriptorHolder(
override val delegationFilter: DelegationFilter = this@LocalClassDescriptorHolder.delegationFilter
override val wrappedTypeFactory: WrappedTypeFactory = this@LocalClassDescriptorHolder.wrappedTypeFactory
override val kotlinTypeChecker: NewKotlinTypeChecker = this@LocalClassDescriptorHolder.kotlinTypeChecker
override val samConversionResolver: SamConversionResolver = this@LocalClassDescriptorHolder.samConversionResolver
},
containingDeclaration,
classOrObject.nameAsSafeName,
@@ -638,6 +638,14 @@ open class WrappedClassDescriptor(
override fun acceptVoid(visitor: DeclarationDescriptorVisitor<Void, Void>?) {
visitor!!.visitClassDescriptor(this, null)
}
override fun getDefaultFunctionTypeForSamInterface(): SimpleType? {
return owner.descriptor.defaultFunctionTypeForSamInterface
}
override fun isDefinitelyNotSamInterface(): Boolean {
return owner.descriptor.isDefinitelyNotSamInterface
}
}
class LazyTypeConstructor(
@@ -751,6 +759,10 @@ open class WrappedEnumEntryDescriptor(
override fun acceptVoid(visitor: DeclarationDescriptorVisitor<Void, Void>?) {
visitor!!.visitClassDescriptor(this, null)
}
override fun getDefaultFunctionTypeForSamInterface(): SimpleType? = null
override fun isDefinitelyNotSamInterface() = true
}
@@ -16,18 +16,7 @@
package org.jetbrains.kotlin.load.java.descriptors;
import org.jetbrains.annotations.Nullable;
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 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.
* But it should work much faster than the exact check.
*/
boolean isDefinitelyNotSamInterface();
}
@@ -98,4 +98,14 @@ public interface ClassDescriptor extends ClassifierDescriptorWithTypeParameters,
@NotNull
@Override
ClassDescriptor getOriginal();
// Use SingleAbstractMethodUtils.getFunctionTypeForSamInterface() where possible. This is only a fallback
@Nullable
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.
* But it should work much faster than the exact check.
*/
boolean isDefinitelyNotSamInterface();
}
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.descriptors.impl;
import kotlin.jvm.functions.Function0;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
@@ -176,4 +177,15 @@ public abstract class AbstractClassDescriptor extends ModuleAwareClassDescriptor
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitClassDescriptor(this, data);
}
@Nullable
@Override
public SimpleType getDefaultFunctionTypeForSamInterface() {
return null;
}
@Override
public boolean isDefinitelyNotSamInterface() {
return false;
}
}
@@ -308,4 +308,25 @@ public class LazySubstitutingClassDescriptor extends ModuleAwareClassDescriptor
public Collection<ClassDescriptor> getSealedSubclasses() {
return original.getSealedSubclasses();
}
@Nullable
@Override
public SimpleType getDefaultFunctionTypeForSamInterface() {
SimpleType type = original.getDefaultFunctionTypeForSamInterface();
if (type == null || originalSubstitutor.isEmpty()) return type;
TypeSubstitutor substitutor = getSubstitutor();
KotlinType substitutedType = substitutor.substitute(type, Variance.INVARIANT);
assert substitutedType instanceof SimpleType :
"Substitution for SimpleType should also be a SimpleType, but it is " + substitutedType + "\n" +
"Unsubstituted: " + type;
return (SimpleType) substitutedType;
}
@Override
public boolean isDefinitelyNotSamInterface() {
return original.isDefinitelyNotSamInterface();
}
}