[NI] Perform full type checking in NI if there is no contradiction
In NI type checking actually performs in constraint system. To be conservative, now we still perform full type cheking but only if there is no contradiction in constraint system
This commit is contained in:
+4
-3
@@ -199,14 +199,15 @@ class KotlinToResolvedCallTransformer(
|
|||||||
// todo external argument
|
// todo external argument
|
||||||
|
|
||||||
val argumentExpression = valueArgument.getArgumentExpression() ?: continue
|
val argumentExpression = valueArgument.getArgumentExpression() ?: continue
|
||||||
updateRecordedType(argumentExpression, newContext)
|
updateRecordedType(argumentExpression, newContext, resolvedCall.isReallySuccess())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateRecordedType(
|
fun updateRecordedType(
|
||||||
expression: KtExpression,
|
expression: KtExpression,
|
||||||
context: BasicCallResolutionContext
|
context: BasicCallResolutionContext,
|
||||||
|
reportErrorForTypeMismatch: Boolean
|
||||||
): KotlinType? {
|
): KotlinType? {
|
||||||
val deparenthesized = expression.let {
|
val deparenthesized = expression.let {
|
||||||
KtPsiUtil.getLastElementDeparenthesized(it, context.statementFilter)
|
KtPsiUtil.getLastElementDeparenthesized(it, context.statementFilter)
|
||||||
@@ -225,7 +226,7 @@ class KotlinToResolvedCallTransformer(
|
|||||||
|
|
||||||
updatedType = updateRecordedTypeForArgument(updatedType, recordedType, expression, context)
|
updatedType = updateRecordedTypeForArgument(updatedType, recordedType, expression, context)
|
||||||
|
|
||||||
dataFlowAnalyzer.checkType(updatedType, deparenthesized, context)
|
dataFlowAnalyzer.checkType(updatedType, deparenthesized, context, reportErrorForTypeMismatch)
|
||||||
|
|
||||||
return updatedType
|
return updatedType
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -102,7 +102,7 @@ class ResolvedAtomCompleter(
|
|||||||
.replaceBindingTrace(trace)
|
.replaceBindingTrace(trace)
|
||||||
|
|
||||||
val argumentExpression = resultValueArgument.valueArgument.getArgumentExpression() ?: continue
|
val argumentExpression = resultValueArgument.valueArgument.getArgumentExpression() ?: continue
|
||||||
kotlinToResolvedCallTransformer.updateRecordedType(argumentExpression, newContext)
|
kotlinToResolvedCallTransformer.updateRecordedType(argumentExpression, newContext, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -361,7 +361,8 @@ public class ControlStructureTypingUtils {
|
|||||||
.replaceExpectedType(c.expectedType)
|
.replaceExpectedType(c.expectedType)
|
||||||
.replaceDataFlowInfo(typeInfo.getDataFlowInfo())
|
.replaceDataFlowInfo(typeInfo.getDataFlowInfo())
|
||||||
.replaceBindingTrace(c.trace),
|
.replaceBindingTrace(c.trace),
|
||||||
hasError
|
hasError,
|
||||||
|
true
|
||||||
);
|
);
|
||||||
return hasError.get();
|
return hasError.get();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,9 +24,9 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature;
|
import org.jetbrains.kotlin.config.LanguageFeature;
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings;
|
import org.jetbrains.kotlin.config.LanguageVersionSettings;
|
||||||
|
import org.jetbrains.kotlin.contracts.EffectSystem;
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtilsKt;
|
import org.jetbrains.kotlin.diagnostics.DiagnosticUtilsKt;
|
||||||
import org.jetbrains.kotlin.contracts.EffectSystem;
|
|
||||||
import org.jetbrains.kotlin.incremental.KotlinLookupLocation;
|
import org.jetbrains.kotlin.incremental.KotlinLookupLocation;
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
@@ -252,7 +252,17 @@ public class DataFlowAnalyzer {
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public KotlinType checkType(@Nullable KotlinType expressionType, @NotNull KtExpression expression, @NotNull ResolutionContext context) {
|
public KotlinType checkType(@Nullable KotlinType expressionType, @NotNull KtExpression expression, @NotNull ResolutionContext context) {
|
||||||
return checkType(expressionType, expression, context, null);
|
return checkType(expressionType, expression, context, null, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public KotlinType checkType(
|
||||||
|
@Nullable KotlinType expressionType,
|
||||||
|
@NotNull KtExpression expression,
|
||||||
|
@NotNull ResolutionContext context,
|
||||||
|
boolean reportErrorForTypeMismatch
|
||||||
|
) {
|
||||||
|
return checkType(expressionType, expression, context, null, reportErrorForTypeMismatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -265,14 +275,15 @@ public class DataFlowAnalyzer {
|
|||||||
@NotNull KotlinType expressionType,
|
@NotNull KotlinType expressionType,
|
||||||
@NotNull KtExpression expression,
|
@NotNull KtExpression expression,
|
||||||
@NotNull ResolutionContext c,
|
@NotNull ResolutionContext c,
|
||||||
@NotNull Ref<Boolean> hasError
|
@NotNull Ref<Boolean> hasError,
|
||||||
|
boolean reportErrorForTypeMismatch
|
||||||
) {
|
) {
|
||||||
if (noExpectedType(c.expectedType) || !c.expectedType.getConstructor().isDenotable() ||
|
if (noExpectedType(c.expectedType) || !c.expectedType.getConstructor().isDenotable() ||
|
||||||
KotlinTypeChecker.DEFAULT.isSubtypeOf(expressionType, c.expectedType)) {
|
KotlinTypeChecker.DEFAULT.isSubtypeOf(expressionType, c.expectedType)) {
|
||||||
return expressionType;
|
return expressionType;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expression instanceof KtConstantExpression) {
|
if (expression instanceof KtConstantExpression && reportErrorForTypeMismatch) {
|
||||||
ConstantValue<?> constantValue = constantExpressionEvaluator.evaluateToConstantValue(expression, c.trace, c.expectedType);
|
ConstantValue<?> constantValue = constantExpressionEvaluator.evaluateToConstantValue(expression, c.trace, c.expectedType);
|
||||||
boolean error = new CompileTimeConstantChecker(c, builtIns, true)
|
boolean error = new CompileTimeConstantChecker(c, builtIns, true)
|
||||||
.checkConstantExpressionType(constantValue, (KtConstantExpression) expression, c.expectedType);
|
.checkConstantExpressionType(constantValue, (KtConstantExpression) expression, c.expectedType);
|
||||||
@@ -288,7 +299,8 @@ public class DataFlowAnalyzer {
|
|||||||
SmartCastResult castResult = checkPossibleCast(expressionType, expression, c);
|
SmartCastResult castResult = checkPossibleCast(expressionType, expression, c);
|
||||||
if (castResult != null) return castResult.getResultType();
|
if (castResult != null) return castResult.getResultType();
|
||||||
|
|
||||||
if (!DiagnosticUtilsKt.reportTypeMismatchDueToTypeProjection(c, expression, c.expectedType, expressionType) &&
|
if (reportErrorForTypeMismatch &&
|
||||||
|
!DiagnosticUtilsKt.reportTypeMismatchDueToTypeProjection(c, expression, c.expectedType, expressionType) &&
|
||||||
!DiagnosticUtilsKt.reportTypeMismatchDueToScalaLikeNamedFunctionSyntax(c, expression, c.expectedType, expressionType)) {
|
!DiagnosticUtilsKt.reportTypeMismatchDueToScalaLikeNamedFunctionSyntax(c, expression, c.expectedType, expressionType)) {
|
||||||
c.trace.report(TYPE_MISMATCH.on(expression, c.expectedType, expressionType));
|
c.trace.report(TYPE_MISMATCH.on(expression, c.expectedType, expressionType));
|
||||||
}
|
}
|
||||||
@@ -301,7 +313,8 @@ public class DataFlowAnalyzer {
|
|||||||
@Nullable KotlinType expressionType,
|
@Nullable KotlinType expressionType,
|
||||||
@NotNull KtExpression expressionToCheck,
|
@NotNull KtExpression expressionToCheck,
|
||||||
@NotNull ResolutionContext c,
|
@NotNull ResolutionContext c,
|
||||||
@Nullable Ref<Boolean> hasError
|
@Nullable Ref<Boolean> hasError,
|
||||||
|
boolean reportErrorForTypeMismatch
|
||||||
) {
|
) {
|
||||||
if (hasError == null) {
|
if (hasError == null) {
|
||||||
hasError = Ref.create(false);
|
hasError = Ref.create(false);
|
||||||
@@ -315,7 +328,7 @@ public class DataFlowAnalyzer {
|
|||||||
|
|
||||||
if (expressionType == null) return null;
|
if (expressionType == null) return null;
|
||||||
|
|
||||||
KotlinType result = checkTypeInternal(expressionType, expression, c, hasError);
|
KotlinType result = checkTypeInternal(expressionType, expression, c, hasError, reportErrorForTypeMismatch);
|
||||||
if (Boolean.FALSE.equals(hasError.get())) {
|
if (Boolean.FALSE.equals(hasError.get())) {
|
||||||
for (AdditionalTypeChecker checker : additionalTypeCheckers) {
|
for (AdditionalTypeChecker checker : additionalTypeCheckers) {
|
||||||
checker.checkType(expression, expressionType, result, c);
|
checker.checkType(expression, expressionType, result, c);
|
||||||
|
|||||||
Reference in New Issue
Block a user