Get rid of passing typeChecker from the call hierarchy
This commit is contained in:
+1
-2
@@ -51,7 +51,6 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.TypeUtils.DONT_CARE
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
import org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils.ResolveConstruct
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
|
||||
|
||||
@@ -255,7 +254,7 @@ class GenericCandidateResolver(
|
||||
val possibleTypes = context.dataFlowInfo.getCollectedTypes(dataFlowValue)
|
||||
if (possibleTypes.isEmpty()) return type
|
||||
|
||||
return TypeIntersector.intersectTypes(KotlinTypeChecker.DEFAULT, possibleTypes + type)
|
||||
return TypeIntersector.intersectTypes(possibleTypes + type)
|
||||
}
|
||||
|
||||
fun <D : CallableDescriptor> completeTypeInferenceDependentOnFunctionArgumentsForCall(context: CallCandidateResolutionContext<D>) {
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -124,7 +124,7 @@ class TypeBoundsImpl(override val typeVariable: TypeVariable) : TypeBounds {
|
||||
|
||||
val upperBounds = filterBounds(bounds, TypeBounds.BoundKind.UPPER_BOUND, values)
|
||||
if (upperBounds.isNotEmpty()) {
|
||||
val intersectionOfUpperBounds = TypeIntersector.intersectTypes(KotlinTypeChecker.DEFAULT, upperBounds)
|
||||
val intersectionOfUpperBounds = TypeIntersector.intersectTypes(upperBounds)
|
||||
if (intersectionOfUpperBounds != null && tryPossibleAnswer(bounds, intersectionOfUpperBounds)) {
|
||||
return setOf(intersectionOfUpperBounds)
|
||||
}
|
||||
|
||||
+4
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,9 +21,9 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Errors.SMARTCAST_IMPOSSIBLE
|
||||
import org.jetbrains.kotlin.psi.Call
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.ValueArgument
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.IMPLICIT_RECEIVER_SMARTCAST
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.SMARTCAST
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver
|
||||
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext
|
||||
@@ -32,7 +32,6 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeIntersector
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
import java.util.*
|
||||
|
||||
class SmartCastManager {
|
||||
@@ -100,7 +99,7 @@ class SmartCastManager {
|
||||
.distinct()
|
||||
if (subTypes.isEmpty()) return null
|
||||
|
||||
val intersection = TypeIntersector.intersectTypes(KotlinTypeChecker.DEFAULT, subTypes)
|
||||
val intersection = TypeIntersector.intersectTypes(subTypes)
|
||||
if (intersection == null || !intersection.constructor.isDenotable) {
|
||||
return receiverParameterType
|
||||
}
|
||||
|
||||
@@ -203,28 +203,26 @@ object CastDiagnosticsUtil {
|
||||
expression: KtBinaryExpressionWithTypeRHS,
|
||||
context: ExpressionTypingContext,
|
||||
targetType: KotlinType,
|
||||
actualType: KotlinType,
|
||||
typeChecker: KotlinTypeChecker
|
||||
actualType: KotlinType
|
||||
): Boolean {
|
||||
// Here: x as? Type <=> x as Type?
|
||||
val refinedTargetType = if (KtPsiUtil.isSafeCast(expression)) TypeUtils.makeNullable(targetType) else targetType
|
||||
val possibleTypes = DataFlowAnalyzer.getAllPossibleTypes(expression.left, actualType, context)
|
||||
return isRefinementUseless(possibleTypes, refinedTargetType, typeChecker, shouldCheckForExactType(expression, context.expectedType))
|
||||
return isRefinementUseless(possibleTypes, refinedTargetType, shouldCheckForExactType(expression, context.expectedType))
|
||||
}
|
||||
|
||||
// It is a warning "useless cast" for `as` and a warning "redundant is" for `is`
|
||||
fun isRefinementUseless(
|
||||
possibleTypes: Collection<KotlinType>,
|
||||
targetType: KotlinType,
|
||||
typeChecker: KotlinTypeChecker,
|
||||
shouldCheckForExactType: Boolean
|
||||
): Boolean {
|
||||
val intersectedType = TypeIntersector.intersectTypes(typeChecker, possibleTypes.map { it.upperIfFlexible() }) ?: return false
|
||||
val intersectedType = TypeIntersector.intersectTypes(possibleTypes.map { it.upperIfFlexible() }) ?: return false
|
||||
|
||||
return if (shouldCheckForExactType)
|
||||
isExactTypeCast(intersectedType, targetType)
|
||||
else
|
||||
isUpcast(intersectedType, targetType, typeChecker)
|
||||
isUpcast(intersectedType, targetType)
|
||||
}
|
||||
|
||||
private fun shouldCheckForExactType(expression: KtBinaryExpressionWithTypeRHS, expectedType: KotlinType): Boolean {
|
||||
@@ -241,8 +239,8 @@ object CastDiagnosticsUtil {
|
||||
return candidateType == targetType && candidateType.isExtensionFunctionType == targetType.isExtensionFunctionType
|
||||
}
|
||||
|
||||
private fun isUpcast(candidateType: KotlinType, targetType: KotlinType, typeChecker: KotlinTypeChecker): Boolean {
|
||||
if (!typeChecker.isSubtypeOf(candidateType, targetType)) return false
|
||||
private fun isUpcast(candidateType: KotlinType, targetType: KotlinType): Boolean {
|
||||
if (!KotlinTypeChecker.DEFAULT.isSubtypeOf(candidateType, targetType)) return false
|
||||
|
||||
if (candidateType.isFunctionType && targetType.isFunctionType) {
|
||||
return candidateType.isExtensionFunctionType == targetType.isExtensionFunctionType
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.descriptors.ClassifierDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope;
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
|
||||
import org.jetbrains.kotlin.types.typeUtil.TypeUtilsKt;
|
||||
import org.jetbrains.kotlin.utils.DFS;
|
||||
|
||||
@@ -305,7 +304,7 @@ public class CommonSupertypes {
|
||||
}
|
||||
if (ins != null) {
|
||||
assert !ins.isEmpty() : "In projections is empty for parameter " + parameterDescriptor + ", type projections " + typeProjections;
|
||||
KotlinType intersection = TypeIntersector.intersectTypes(KotlinTypeChecker.DEFAULT, ins);
|
||||
KotlinType intersection = TypeIntersector.intersectTypes(ins);
|
||||
if (intersection == null) {
|
||||
return TypeUtils.makeStarProjection(parameterDescriptor);
|
||||
}
|
||||
|
||||
@@ -37,11 +37,11 @@ import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt.getB
|
||||
public class TypeIntersector {
|
||||
|
||||
public static boolean isIntersectionEmpty(@NotNull KotlinType typeA, @NotNull KotlinType typeB) {
|
||||
return intersectTypes(KotlinTypeChecker.DEFAULT, new LinkedHashSet<>(Arrays.asList(typeA, typeB))) == null;
|
||||
return intersectTypes(new LinkedHashSet<>(Arrays.asList(typeA, typeB))) == null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static KotlinType intersectTypes(@NotNull KotlinTypeChecker typeChecker, @NotNull Collection<KotlinType> types) {
|
||||
public static KotlinType intersectTypes(@NotNull Collection<KotlinType> types) {
|
||||
assert !types.isEmpty() : "Attempting to intersect empty collection of types, this case should be dealt with on the call site.";
|
||||
|
||||
if (types.size() == 1) {
|
||||
@@ -72,6 +72,7 @@ public class TypeIntersector {
|
||||
return ErrorUtils.createErrorType("Intersection of error types: " + types);
|
||||
}
|
||||
|
||||
KotlinTypeChecker typeChecker = KotlinTypeChecker.DEFAULT;
|
||||
// Now we remove types that have subtypes in the list
|
||||
List<KotlinType> resultingTypes = new ArrayList<>();
|
||||
outer:
|
||||
@@ -151,7 +152,7 @@ public class TypeIntersector {
|
||||
public static KotlinType getUpperBoundsAsType(@NotNull TypeParameterDescriptor descriptor) {
|
||||
List<KotlinType> upperBounds = descriptor.getUpperBounds();
|
||||
assert !upperBounds.isEmpty() : "Upper bound list is empty: " + descriptor;
|
||||
KotlinType upperBoundsAsType = intersectTypes(KotlinTypeChecker.DEFAULT, upperBounds);
|
||||
KotlinType upperBoundsAsType = intersectTypes(upperBounds);
|
||||
return upperBoundsAsType != null ? upperBoundsAsType : getBuiltIns(descriptor).getNothingType();
|
||||
}
|
||||
|
||||
|
||||
+2
-3
@@ -378,13 +378,12 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
return;
|
||||
}
|
||||
|
||||
KotlinTypeChecker typeChecker = KotlinTypeChecker.DEFAULT;
|
||||
if (CastDiagnosticsUtil.INSTANCE.castIsUseless(expression, context, targetType, actualType, typeChecker)) {
|
||||
if (CastDiagnosticsUtil.INSTANCE.castIsUseless(expression, context, targetType, actualType)) {
|
||||
context.trace.report(USELESS_CAST.on(expression));
|
||||
return;
|
||||
}
|
||||
|
||||
if (CastDiagnosticsUtil.isCastErased(actualType, targetType, typeChecker)) {
|
||||
if (CastDiagnosticsUtil.isCastErased(actualType, targetType, KotlinTypeChecker.DEFAULT)) {
|
||||
context.trace.report(UNCHECKED_CAST.on(expression, actualType, targetType));
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -462,7 +462,7 @@ class PatternMatchingTypingVisitor internal constructor(facade: ExpressionTyping
|
||||
if (subjectType.containsError() || targetType.containsError()) return
|
||||
|
||||
val possibleTypes = DataFlowAnalyzer.getAllPossibleTypes(subjectType, context, subjectDataFlowValue)
|
||||
if (CastDiagnosticsUtil.isRefinementUseless(possibleTypes, targetType, KotlinTypeChecker.DEFAULT, false)) {
|
||||
if (CastDiagnosticsUtil.isRefinementUseless(possibleTypes, targetType, false)) {
|
||||
context.trace.report(Errors.USELESS_IS_CHECK.on(isCheck, !negated))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -509,7 +509,7 @@ public class KotlinTypeCheckerTest extends KotlinTestWithEnvironment {
|
||||
for (String type : types) {
|
||||
typesToIntersect.add(makeType(type));
|
||||
}
|
||||
KotlinType result = TypeIntersector.intersectTypes(KotlinTypeChecker.DEFAULT, typesToIntersect);
|
||||
KotlinType result = TypeIntersector.intersectTypes(typesToIntersect);
|
||||
// assertNotNull("Intersection is null for " + typesToIntersect, result);
|
||||
assertEquals(makeType(expected), result);
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -255,7 +255,7 @@ private fun KtNamedDeclaration.guessType(context: BindingContext): Array<KotlinT
|
||||
if (expectedTypes.isEmpty() || expectedTypes.any { expectedType -> ErrorUtils.containsErrorType(expectedType) }) {
|
||||
return arrayOf()
|
||||
}
|
||||
val theType = TypeIntersector.intersectTypes(KotlinTypeChecker.DEFAULT, expectedTypes)
|
||||
val theType = TypeIntersector.intersectTypes(expectedTypes)
|
||||
return if (theType != null) {
|
||||
arrayOf(theType)
|
||||
}
|
||||
|
||||
+1
-2
@@ -66,7 +66,6 @@ import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsStatement
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||
import org.jetbrains.kotlin.utils.DFS
|
||||
import org.jetbrains.kotlin.utils.DFS.*
|
||||
@@ -514,7 +513,7 @@ internal class MutableParameter(
|
||||
private val defaultType: KotlinType by lazy {
|
||||
writable = false
|
||||
if (defaultTypes.isNotEmpty()) {
|
||||
TypeIntersector.intersectTypes(KotlinTypeChecker.DEFAULT, defaultTypes)!!
|
||||
TypeIntersector.intersectTypes(defaultTypes)!!
|
||||
}
|
||||
else originalType
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user