Rename SmartCastUtils -> SmartCastManager and make it a component

This commit is contained in:
Pavel V. Talanov
2015-07-28 16:17:52 +03:00
parent da025475a8
commit 84ebc7a0f8
8 changed files with 45 additions and 39 deletions
@@ -42,10 +42,7 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus.*
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastUtils.canBeSmartCast
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastUtils.getSmartCastVariantsExcludingReceiver
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastUtils.isSubTypeBySmartCastIgnoringNullability
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastUtils.recordSmartCastIfNecessary
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastManager
import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionTask
import org.jetbrains.kotlin.resolve.calls.tasks.isSynthesizedInvoke
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
@@ -66,7 +63,8 @@ public class CandidateResolver(
private val genericCandidateResolver: GenericCandidateResolver,
private val reflectionTypes: ReflectionTypes,
private val modifiersChecker: ModifiersChecker,
private val additionalTypeCheckers: Iterable<AdditionalTypeChecker>
private val additionalTypeCheckers: Iterable<AdditionalTypeChecker>,
private val smartCastManager: SmartCastManager
){
public fun <D : CallableDescriptor, F : D> performResolutionForCandidateCall(
@@ -372,7 +370,7 @@ public class CandidateResolver(
actualType: JetType,
context: ResolutionContext<*>): JetType? {
val receiverToCast = ExpressionReceiver(JetPsiUtil.safeDeparenthesize(expression, false), actualType)
val variants = getSmartCastVariantsExcludingReceiver(context, receiverToCast)
val variants = smartCastManager.getSmartCastVariantsExcludingReceiver(context, receiverToCast)
for (possibleType in variants) {
if (JetTypeChecker.DEFAULT.isSubtypeOf(possibleType, expectedType)) {
return possibleType
@@ -401,7 +399,7 @@ public class CandidateResolver(
val erasedReceiverType = getErasedReceiverType(receiverParameterDescriptor, candidateDescriptor)
if (!isSubTypeBySmartCastIgnoringNullability(receiverArgument, erasedReceiverType, this)) {
if (!smartCastManager.isSubTypeBySmartCastIgnoringNullability(receiverArgument, erasedReceiverType, this)) {
RECEIVER_TYPE_ERROR
} else {
SUCCESS
@@ -441,13 +439,13 @@ public class CandidateResolver(
if (TypeUtils.dependsOnTypeParameters(receiverParameter.getType(), candidateDescriptor.getTypeParameters())) return SUCCESS
val safeAccess = isExplicitReceiver && !implicitInvokeCheck && candidateCall.getCall().isExplicitSafeCall()
val isSubtypeBySmartCast = isSubTypeBySmartCastIgnoringNullability(
val isSubtypeBySmartCast = smartCastManager.isSubTypeBySmartCastIgnoringNullability(
receiverArgument, receiverParameter.getType(), this)
if (!isSubtypeBySmartCast) {
tracing.wrongReceiverType(trace, receiverParameter, receiverArgument)
return OTHER_ERROR
}
if (!recordSmartCastIfNecessary(receiverArgument, receiverParameter.getType(), this, safeAccess)) {
if (!smartCastManager.recordSmartCastIfNecessary(receiverArgument, receiverParameter.getType(), this, safeAccess)) {
return OTHER_ERROR
}
@@ -455,7 +453,7 @@ public class CandidateResolver(
val bindingContext = trace.getBindingContext()
if (!safeAccess && !receiverParameter.getType().isMarkedNullable() && receiverArgumentType.isMarkedNullable()) {
if (!canBeSmartCast(receiverParameter, receiverArgument, this)) {
if (!smartCastManager.canBeSmartCast(receiverParameter, receiverArgument, this)) {
tracing.unsafeCall(trace, receiverArgumentType, implicitInvokeCheck)
return UNSAFE_CALL_ERROR
}
@@ -46,12 +46,13 @@ import java.util.Set;
import static org.jetbrains.kotlin.diagnostics.Errors.SMARTCAST_IMPOSSIBLE;
import static org.jetbrains.kotlin.resolve.BindingContext.SMARTCAST;
public class SmartCastUtils {
public class SmartCastManager {
private SmartCastUtils() {}
public SmartCastManager() {
}
@NotNull
public static List<JetType> getSmartCastVariants(
public List<JetType> getSmartCastVariants(
@NotNull ReceiverValue receiverToCast,
@NotNull ResolutionContext context
) {
@@ -59,7 +60,7 @@ public class SmartCastUtils {
}
@NotNull
public static List<JetType> getSmartCastVariants(
public List<JetType> getSmartCastVariants(
@NotNull ReceiverValue receiverToCast,
@NotNull BindingContext bindingContext,
@NotNull DeclarationDescriptor containingDeclarationOrModule,
@@ -72,7 +73,7 @@ public class SmartCastUtils {
}
@NotNull
public static List<JetType> getSmartCastVariantsWithLessSpecificExcluded(
public List<JetType> getSmartCastVariantsWithLessSpecificExcluded(
@NotNull ReceiverValue receiverToCast,
@NotNull BindingContext bindingContext,
@NotNull DeclarationDescriptor containingDeclarationOrModule,
@@ -97,7 +98,7 @@ public class SmartCastUtils {
* @return variants @param receiverToCast may be cast to according to context dataFlowInfo, receiverToCast itself is NOT included
*/
@NotNull
public static Collection<JetType> getSmartCastVariantsExcludingReceiver(
public Collection<JetType> getSmartCastVariantsExcludingReceiver(
@NotNull ResolutionContext context,
@NotNull ReceiverValue receiverToCast
) {
@@ -111,7 +112,7 @@ public class SmartCastUtils {
* @return variants @param receiverToCast may be cast to according to @param dataFlowInfo, @param receiverToCast itself is NOT included
*/
@NotNull
public static Collection<JetType> getSmartCastVariantsExcludingReceiver(
public Collection<JetType> getSmartCastVariantsExcludingReceiver(
@NotNull BindingContext bindingContext,
@NotNull DeclarationDescriptor containingDeclarationOrModule,
@NotNull DataFlowInfo dataFlowInfo,
@@ -131,7 +132,7 @@ public class SmartCastUtils {
return Collections.emptyList();
}
public static boolean isSubTypeBySmartCastIgnoringNullability(
public boolean isSubTypeBySmartCastIgnoringNullability(
@NotNull ReceiverValue receiverArgument,
@NotNull JetType receiverParameterType,
@NotNull ResolutionContext context
@@ -141,7 +142,7 @@ public class SmartCastUtils {
}
@Nullable
private static JetType getSmartCastSubType(
private JetType getSmartCastSubType(
@NotNull JetType receiverParameterType,
@NotNull Collection<JetType> smartCastTypes
) {
@@ -161,7 +162,7 @@ public class SmartCastUtils {
}
// Returns false when we need smart cast but cannot do it, otherwise true
public static boolean recordSmartCastIfNecessary(
public boolean recordSmartCastIfNecessary(
@NotNull ReceiverValue receiver,
@NotNull JetType receiverParameterType,
@NotNull ResolutionContext context,
@@ -184,7 +185,7 @@ public class SmartCastUtils {
return recordCastOrError(expression, smartCastSubType, context.trace, dataFlowValue.isPredictable(), true);
}
public static boolean recordCastOrError(
public boolean recordCastOrError(
@NotNull JetExpression expression,
@NotNull JetType type,
@NotNull BindingTrace trace,
@@ -205,7 +206,7 @@ public class SmartCastUtils {
return canBeCast;
}
public static boolean canBeSmartCast(
public boolean canBeSmartCast(
@NotNull ReceiverParameterDescriptor receiverParameter,
@NotNull ReceiverValue receiver,
@NotNull ResolutionContext context) {
@@ -26,7 +26,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isOrOverridesSynthesized
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastUtils
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastManager
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.BOTH_RECEIVERS
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.DISPATCH_RECEIVER
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.EXTENSION_RECEIVER
@@ -47,7 +47,10 @@ import org.jetbrains.kotlin.types.checker.JetTypeChecker
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
import org.jetbrains.kotlin.types.isDynamic
public class TaskPrioritizer(private val storageManager: StorageManager) {
public class TaskPrioritizer(
private val storageManager: StorageManager,
private val smartCastManager: SmartCastManager
) {
public fun <D : CallableDescriptor> splitLexicallyLocalDescriptors(
allDescriptors: Collection<ResolutionCandidate<D>>,
@@ -130,10 +133,11 @@ public class TaskPrioritizer(private val storageManager: StorageManager) {
addCandidatesForNoReceiver(implicitReceivers, c)
}
private class ReceiverWithTypes(
private inner class ReceiverWithTypes(
val value: ReceiverValue,
private val context: ResolutionContext<*>) {
val types: Collection<JetType> by lazy { SmartCastUtils.getSmartCastVariants(value, context) }
private val context: ResolutionContext<*>
) {
val types: Collection<JetType> by lazy { smartCastManager.getSmartCastVariants(value, context) }
}
private fun <D : CallableDescriptor, F : D> addCandidatesForExplicitReceiver(
@@ -31,7 +31,7 @@ import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext;
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue;
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory;
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastUtils;
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastManager;
import org.jetbrains.kotlin.resolve.constants.*;
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
import org.jetbrains.kotlin.types.JetType;
@@ -51,15 +51,18 @@ public class DataFlowAnalyzer {
private final Iterable<AdditionalTypeChecker> additionalTypeCheckers;
private final ConstantExpressionEvaluator constantExpressionEvaluator;
private final KotlinBuiltIns builtIns;
private final SmartCastManager smartCastManager;
public DataFlowAnalyzer(
@NotNull Iterable<AdditionalTypeChecker> additionalTypeCheckers,
@NotNull ConstantExpressionEvaluator constantExpressionEvaluator,
@NotNull KotlinBuiltIns builtIns
@NotNull KotlinBuiltIns builtIns,
@NotNull SmartCastManager smartCastManager
) {
this.additionalTypeCheckers = additionalTypeCheckers;
this.constantExpressionEvaluator = constantExpressionEvaluator;
this.builtIns = builtIns;
this.smartCastManager = smartCastManager;
}
@NotNull
@@ -218,7 +221,7 @@ public class DataFlowAnalyzer {
for (JetType possibleType : c.dataFlowInfo.getPossibleTypes(dataFlowValue)) {
if (JetTypeChecker.DEFAULT.isSubtypeOf(possibleType, c.expectedType)) {
SmartCastUtils.recordCastOrError(expression, possibleType, c.trace, dataFlowValue.isPredictable(), false);
smartCastManager.recordCastOrError(expression, possibleType, c.trace, dataFlowValue.isPredictable(), false);
return possibleType;
}
}
@@ -29,7 +29,7 @@ import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfo
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastUtils
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastManager
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
import org.jetbrains.kotlin.resolve.scopes.*
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
@@ -108,7 +108,7 @@ public class ReferenceVariantsHelper(
val dataFlowInfo = context.getDataFlowInfo(expression)
val implicitReceiverTypes = resolutionScope.getImplicitReceiversWithInstance().flatMap {
SmartCastUtils.getSmartCastVariantsWithLessSpecificExcluded(it.value, context, containingDeclaration, dataFlowInfo)
SmartCastManager().getSmartCastVariantsWithLessSpecificExcluded(it.value, context, containingDeclaration, dataFlowInfo)
}.toSet()
val pair = getExplicitReceiverData(expression)
@@ -127,7 +127,7 @@ public class ReferenceVariantsHelper(
context.getType(receiverExpression)
if (expressionType != null && !expressionType.isError()) {
val receiverValue = ExpressionReceiver(receiverExpression, expressionType)
val explicitReceiverTypes = SmartCastUtils.getSmartCastVariantsWithLessSpecificExcluded(receiverValue, context, containingDeclaration, dataFlowInfo)
val explicitReceiverTypes = SmartCastManager().getSmartCastVariantsWithLessSpecificExcluded(receiverValue, context, containingDeclaration, dataFlowInfo)
descriptors.processAll(implicitReceiverTypes, explicitReceiverTypes, resolutionScope, callType, kindFilter, nameFilter)
}
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.psi.JetPsiUtil
import org.jetbrains.kotlin.psi.JetThisExpression
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastUtils
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastManager
import org.jetbrains.kotlin.resolve.scopes.JetScope
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
@@ -84,7 +84,7 @@ public fun CallableDescriptor.substituteExtensionIfCallable(
): Collection<CallableDescriptor> {
if (!receiver.exists()) return listOf()
var types = SmartCastUtils.getSmartCastVariants(receiver, bindingContext, containingDeclarationOrModule, dataFlowInfo)
var types = SmartCastManager().getSmartCastVariants(receiver, bindingContext, containingDeclarationOrModule, dataFlowInfo)
return substituteExtensionIfCallable(types, callType)
}
@@ -45,8 +45,8 @@ import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import org.jetbrains.kotlin.psi.psiUtil.prevLeaf
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfo
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastManager
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastUtils
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
@@ -146,7 +146,7 @@ abstract class CompletionSession(protected val configuration: CompletionSessionC
var receiverTypes = receiversData.receivers.flatMap { receiverValue ->
val dataFlowValue = DataFlowValueFactory.createDataFlowValue(receiverValue, bindingContext, moduleDescriptor)
if (dataFlowValue.isPredictable) { // we don't include smart cast receiver types for "unpredictable" receiver value to mark members grayed
SmartCastUtils.getSmartCastVariantsWithLessSpecificExcluded(receiverValue, bindingContext, moduleDescriptor, dataFlowInfo)
SmartCastManager().getSmartCastVariantsWithLessSpecificExcluded(receiverValue, bindingContext, moduleDescriptor, dataFlowInfo)
}
else {
listOf(receiverValue.type)
@@ -36,7 +36,7 @@ import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.resolve.QualifiedExpressionResolver.LookupMode
import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfo
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastUtils
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastManager
import org.jetbrains.kotlin.resolve.lazy.ResolveSessionUtils
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
@@ -114,7 +114,7 @@ public class KotlinIndicesHelper(
private fun possibleReceiverTypeNames(receiverValues: Collection<ReceiverValue>, dataFlowInfo: DataFlowInfo, bindingContext: BindingContext): Set<String> {
val result = HashSet<String>()
for (receiverValue in receiverValues) {
for (type in SmartCastUtils.getSmartCastVariants(receiverValue, bindingContext, moduleDescriptor, dataFlowInfo)) {
for (type in SmartCastManager().getSmartCastVariants(receiverValue, bindingContext, moduleDescriptor, dataFlowInfo)) {
result.addTypeNames(type)
}
}