NI: resolve try catch as synthetic function call (#KT-25435 fixed)
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.resolve;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import kotlin.annotations.jvm.ReadOnly;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -15,7 +16,6 @@ import org.jetbrains.kotlin.cfg.LeakingThisDescriptor;
|
||||
import org.jetbrains.kotlin.cfg.TailRecursionKind;
|
||||
import org.jetbrains.kotlin.contracts.description.InvocationKind;
|
||||
import org.jetbrains.kotlin.contracts.model.Computation;
|
||||
import org.jetbrains.kotlin.contracts.model.Functor;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
@@ -264,6 +264,8 @@ public interface BindingContext {
|
||||
|
||||
WritableSlice<KtExpression, PrimitiveNumericComparisonInfo> PRIMITIVE_NUMERIC_COMPARISON_INFO = Slices.createSimpleSlice();
|
||||
|
||||
WritableSlice<KtExpression, Ref<VariableDescriptor>> NEW_INFERENCE_CATCH_EXCEPTION_PARAMETER = Slices.createSimpleSlice();
|
||||
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
@Deprecated // This field is needed only for the side effects of its initializer
|
||||
Void _static_initializer = BasicWritableSlice.initSliceDebugNames(BindingContext.class);
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.referenceExpression
|
||||
import org.jetbrains.kotlin.resolve.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.NEW_INFERENCE_CATCH_EXCEPTION_PARAMETER
|
||||
import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver
|
||||
import org.jetbrains.kotlin.resolve.calls.CallTransformer
|
||||
import org.jetbrains.kotlin.resolve.calls.KotlinCallResolver
|
||||
@@ -40,9 +41,7 @@ import org.jetbrains.kotlin.resolve.calls.util.CallMaker
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
|
||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
|
||||
import org.jetbrains.kotlin.resolve.scopes.*
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.*
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.expressions.*
|
||||
@@ -632,6 +631,7 @@ class PSICallResolver(
|
||||
|
||||
val context = outerCallContext.replaceContextDependency(ContextDependency.DEPENDENT)
|
||||
.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).replaceDataFlowInfo(startDataFlowInfo)
|
||||
.expandContextForCatchClause(ktExpression)
|
||||
|
||||
if (ktExpression is KtCallableReferenceExpression) {
|
||||
checkNoSpread(outerCallContext, valueArgument)
|
||||
@@ -683,4 +683,20 @@ class PSICallResolver(
|
||||
val typeInfo = expressionTypingServices.getTypeInfo(argumentExpression, context)
|
||||
return createSimplePSICallArgument(context, valueArgument, typeInfo) ?: parseErrorArgument
|
||||
}
|
||||
|
||||
private fun BasicCallResolutionContext.expandContextForCatchClause(ktExpression: Any): BasicCallResolutionContext {
|
||||
if (ktExpression !is KtExpression) return this
|
||||
|
||||
val variableDescriptorHolder = trace.bindingContext[NEW_INFERENCE_CATCH_EXCEPTION_PARAMETER, ktExpression] ?: return this
|
||||
val variableDescriptor = variableDescriptorHolder.get() ?: return this
|
||||
variableDescriptorHolder.set(null)
|
||||
|
||||
val redeclarationChecker = expressionTypingServices.createLocalRedeclarationChecker(trace)
|
||||
|
||||
val catchScope = with(scope) {
|
||||
LexicalWritableScope(this, ownerDescriptor, false, redeclarationChecker, LexicalScopeKind.CATCH)
|
||||
}
|
||||
catchScope.addVariableDescriptor(variableDescriptor)
|
||||
return replaceScope(catchScope)
|
||||
}
|
||||
}
|
||||
|
||||
+50
-1
@@ -22,6 +22,7 @@ import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import kotlin.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
@@ -35,6 +36,7 @@ import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl;
|
||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.BindingContextUtils;
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace;
|
||||
import org.jetbrains.kotlin.resolve.calls.CallResolver;
|
||||
@@ -67,7 +69,7 @@ public class ControlStructureTypingUtils {
|
||||
private static final Logger LOG = Logger.getInstance(ControlStructureTypingUtils.class);
|
||||
|
||||
public enum ResolveConstruct {
|
||||
IF("if"), ELVIS("elvis"), EXCL_EXCL("ExclExcl"), WHEN("when");
|
||||
IF("if"), ELVIS("elvis"), EXCL_EXCL("ExclExcl"), WHEN("when"), TRY("try");
|
||||
|
||||
private final String name;
|
||||
private final Name specialFunctionName;
|
||||
@@ -116,6 +118,39 @@ public class ControlStructureTypingUtils {
|
||||
) {
|
||||
SimpleFunctionDescriptorImpl function = createFunctionDescriptorForSpecialConstruction(
|
||||
construct, argumentNames, isArgumentNullable);
|
||||
return resolveSpecialConstructionAsCall(call, function, construct, context, dataFlowInfoForArguments);
|
||||
}
|
||||
|
||||
/*package*/ ResolvedCall<FunctionDescriptor> resolveTryAsCall(
|
||||
@NotNull Call call,
|
||||
@NotNull KtTryExpression tryExpression,
|
||||
@NotNull List<Pair<KtExpression, VariableDescriptor>> catchedExceptions,
|
||||
@NotNull ExpressionTypingContext context,
|
||||
@Nullable MutableDataFlowInfoForArguments dataFlowInfoForArguments
|
||||
) {
|
||||
List<String> argumentNames = Lists.newArrayList("tryBlock");
|
||||
List<Boolean> argumentsNullability = Lists.newArrayList(false);
|
||||
for (int i = 0; i < tryExpression.getCatchClauses().size(); i++) {
|
||||
argumentNames.add("catchBlock" + i);
|
||||
argumentsNullability.add(false);
|
||||
}
|
||||
SimpleFunctionDescriptorImpl function =
|
||||
createFunctionDescriptorForSpecialConstruction(ResolveConstruct.TRY, argumentNames, argumentsNullability);
|
||||
for (Pair<KtExpression, VariableDescriptor> descriptorPair : catchedExceptions) {
|
||||
KtExpression catchBlock = descriptorPair.getFirst();
|
||||
VariableDescriptor catchedExceptionDescriptor = descriptorPair.getSecond();
|
||||
context.trace.record(BindingContext.NEW_INFERENCE_CATCH_EXCEPTION_PARAMETER, catchBlock, Ref.create(catchedExceptionDescriptor));
|
||||
}
|
||||
return resolveSpecialConstructionAsCall(call, function, ResolveConstruct.TRY, context, dataFlowInfoForArguments);
|
||||
}
|
||||
|
||||
private ResolvedCall<FunctionDescriptor> resolveSpecialConstructionAsCall(
|
||||
@NotNull Call call,
|
||||
@NotNull SimpleFunctionDescriptorImpl function,
|
||||
@NotNull ResolveConstruct construct,
|
||||
@NotNull ExpressionTypingContext context,
|
||||
@Nullable MutableDataFlowInfoForArguments dataFlowInfoForArguments
|
||||
) {
|
||||
TracingStrategy tracing = createTracingForSpecialConstruction(call, construct.getName(), context);
|
||||
TypeSubstitutor knownTypeParameterSubstitutor = createKnownTypeParameterSubstitutorForSpecialCall(construct, function, context.expectedType, context.languageVersionSettings);
|
||||
ResolutionCandidate<FunctionDescriptor> resolutionCandidate =
|
||||
@@ -252,6 +287,20 @@ public class ControlStructureTypingUtils {
|
||||
return createIndependentDataFlowInfoForArgumentsForCall(subjectDataFlowInfo, dataFlowInfoForArgumentsMap);
|
||||
}
|
||||
|
||||
public static MutableDataFlowInfoForArguments createDataFlowInfoForArgumentsOfTryCall(
|
||||
@NotNull Call callForTry,
|
||||
@NotNull DataFlowInfo dataFlowInfoBeforeTry,
|
||||
@NotNull DataFlowInfo dataFlowInfoAfterTry
|
||||
) {
|
||||
Map<ValueArgument, DataFlowInfo> dataFlowInfoForArgumentsMap = new HashMap<>();
|
||||
List<? extends ValueArgument> valueArguments = callForTry.getValueArguments();
|
||||
dataFlowInfoForArgumentsMap.put(valueArguments.get(0), dataFlowInfoBeforeTry);
|
||||
for (int i = 1; i < valueArguments.size(); i++) {
|
||||
dataFlowInfoForArgumentsMap.put(valueArguments.get(i), dataFlowInfoAfterTry);
|
||||
}
|
||||
return createIndependentDataFlowInfoForArgumentsForCall(dataFlowInfoBeforeTry, dataFlowInfoForArgumentsMap);
|
||||
}
|
||||
|
||||
/*package*/ static Call createCallForSpecialConstruction(
|
||||
@NotNull KtExpression expression,
|
||||
@NotNull KtExpression calleeExpression,
|
||||
|
||||
+132
-20
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.types.expressions;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import kotlin.collections.CollectionsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
@@ -47,13 +48,13 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.jetbrains.kotlin.diagnostics.Errors.*;
|
||||
import static org.jetbrains.kotlin.resolve.BindingContext.*;
|
||||
import static org.jetbrains.kotlin.resolve.calls.context.ContextDependency.INDEPENDENT;
|
||||
import static org.jetbrains.kotlin.types.TypeUtils.*;
|
||||
import static org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils.createCallForSpecialConstruction;
|
||||
import static org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils.createDataFlowInfoForArgumentsForIfCall;
|
||||
import static org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils.*;
|
||||
import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.*;
|
||||
|
||||
public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
|
||||
@@ -489,6 +490,9 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
|
||||
|
||||
@Override
|
||||
public KotlinTypeInfo visitTryExpression(@NotNull KtTryExpression expression, ExpressionTypingContext typingContext) {
|
||||
if (typingContext.languageVersionSettings.supportsFeature(LanguageFeature.NewInference)) {
|
||||
return resolveTryExpressionWithNewInference(expression, typingContext);
|
||||
}
|
||||
ExpressionTypingContext context = typingContext.replaceContextDependency(INDEPENDENT);
|
||||
KtExpression tryBlock = expression.getTryBlock();
|
||||
List<KtCatchClause> catchClauses = expression.getCatchClauses();
|
||||
@@ -500,15 +504,8 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
|
||||
KtExpression catchBody = catchClause.getCatchBody();
|
||||
boolean nothingInCatchBranch = false;
|
||||
if (catchParameter != null) {
|
||||
checkCatchParameterDeclaration(catchParameter, context);
|
||||
VariableDescriptor variableDescriptor = resolveAndCheckCatchParameter(catchParameter, context);
|
||||
|
||||
VariableDescriptor variableDescriptor = components.descriptorResolver.resolveLocalVariableDescriptor(
|
||||
context.scope, catchParameter, context.trace);
|
||||
KotlinType catchParameterType = variableDescriptor.getType();
|
||||
checkCatchParameterType(catchParameter, catchParameterType, context);
|
||||
|
||||
KotlinType throwableType = components.builtIns.getThrowable().getDefaultType();
|
||||
components.dataFlowAnalyzer.checkType(catchParameterType, catchParameter, context.replaceExpectedType(throwableType));
|
||||
if (catchBody != null) {
|
||||
LexicalWritableScope catchScope = newWritableScopeImpl(context, LexicalScopeKind.CATCH, components.overloadChecker);
|
||||
catchScope.addVariableDescriptor(variableDescriptor);
|
||||
@@ -527,15 +524,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
|
||||
}
|
||||
|
||||
KotlinTypeInfo tryResult = facade.getTypeInfo(tryBlock, context);
|
||||
ExpressionTypingContext tryOutputContext = context.replaceExpectedType(NO_EXPECTED_TYPE);
|
||||
if (!nothingInAllCatchBranches &&
|
||||
facade.getComponents().languageVersionSettings.supportsFeature(LanguageFeature.SoundSmartCastsAfterTry)) {
|
||||
PreliminaryLoopVisitor tryVisitor = PreliminaryLoopVisitor.visitTryBlock(expression);
|
||||
tryOutputContext = tryOutputContext.replaceDataFlowInfo(
|
||||
tryVisitor.clearDataFlowInfoForAssignedLocalVariables(tryOutputContext.dataFlowInfo,
|
||||
components.languageVersionSettings)
|
||||
);
|
||||
}
|
||||
ExpressionTypingContext tryOutputContext = getCleanedContextFromTryWithAssignmentsToVar(expression, nothingInAllCatchBranches, context);
|
||||
|
||||
KotlinTypeInfo result = TypeInfoFactoryKt.noTypeInfo(tryOutputContext);
|
||||
if (finallyBlock != null) {
|
||||
@@ -557,6 +546,129 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
private KotlinTypeInfo resolveTryExpressionWithNewInference(@NotNull KtTryExpression tryExpression, ExpressionTypingContext tryInputContext) {
|
||||
// tryInputContext is an ExpressionTypingContext before try/catch expression
|
||||
|
||||
KtBlockExpression tryBlock = tryExpression.getTryBlock();
|
||||
List<KtCatchClause> catchClauses = tryExpression.getCatchClauses();
|
||||
KtFinallySection finallySection = tryExpression.getFinallyBlock();
|
||||
|
||||
DataFlowInfo dataFlowInfoBeforeTry = tryInputContext.dataFlowInfo;
|
||||
|
||||
List<KtExpression> catchBlocks = Lists.newArrayList();
|
||||
List<kotlin.Pair<KtExpression, VariableDescriptor>> catchClausesBlocksAndParameters = Lists.newArrayList();
|
||||
|
||||
for (KtCatchClause catchClause : catchClauses) {
|
||||
KtParameter catchParameter = catchClause.getCatchParameter();
|
||||
KtExpression catchBody = catchClause.getCatchBody();
|
||||
if (catchParameter != null) {
|
||||
VariableDescriptor variableDescriptor = resolveAndCheckCatchParameter(catchParameter, tryInputContext);
|
||||
if (catchBody != null) {
|
||||
catchBlocks.add(catchBody);
|
||||
catchClausesBlocksAndParameters.add(new kotlin.Pair<>(catchBody, variableDescriptor));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
KtBlockExpression finallyBlock = null;
|
||||
if (finallySection != null) {
|
||||
finallyBlock = finallySection.getFinalExpression();
|
||||
}
|
||||
|
||||
List<KtExpression> arguments = Lists.newArrayList(tryBlock);
|
||||
arguments.addAll(catchBlocks);
|
||||
|
||||
Call callForTry = createCallForSpecialConstruction(tryExpression, tryExpression, arguments);
|
||||
|
||||
MutableDataFlowInfoForArguments dataFlowInfoForArguments = createDataFlowInfoForArgumentsOfTryCall(callForTry, dataFlowInfoBeforeTry, dataFlowInfoBeforeTry);
|
||||
ResolvedCall<FunctionDescriptor> resolvedCall = components.controlStructureTypingUtils
|
||||
.resolveTryAsCall(callForTry, tryExpression, catchClausesBlocksAndParameters, tryInputContext, dataFlowInfoForArguments);
|
||||
KotlinType resultType = resolvedCall.getResultingDescriptor().getReturnType();
|
||||
|
||||
BindingContext bindingContext = tryInputContext.trace.getBindingContext();
|
||||
|
||||
return processTryBranches(tryExpression, tryBlock, tryInputContext, catchBlocks, finallyBlock, bindingContext, resultType);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private KotlinTypeInfo processTryBranches(
|
||||
@NotNull KtTryExpression tryExpression,
|
||||
KtBlockExpression tryBlock,
|
||||
ExpressionTypingContext context,
|
||||
List<KtExpression> catchBlocks,
|
||||
KtBlockExpression finallyBlock,
|
||||
BindingContext bindingContext,
|
||||
KotlinType resultType
|
||||
) {
|
||||
KotlinTypeInfo tryInfo = BindingContextUtils.getRecordedTypeInfo(tryBlock, bindingContext);
|
||||
DataFlowInfo dataFlowInfoAfterTry;
|
||||
if (tryInfo != null) {
|
||||
dataFlowInfoAfterTry = tryInfo.getDataFlowInfo();
|
||||
}
|
||||
else {
|
||||
dataFlowInfoAfterTry = DataFlowInfo.Companion.getEMPTY();
|
||||
}
|
||||
boolean nothingInAllCatchBranches = isCatchBranchesReturnsNothing(catchBlocks, bindingContext);
|
||||
|
||||
// it is not actually correct way (#KT-28370) of computing context, but it's how was in OI
|
||||
ExpressionTypingContext tryOutputContext = getCleanedContextFromTryWithAssignmentsToVar(tryExpression, nothingInAllCatchBranches, context);
|
||||
|
||||
KotlinTypeInfo result = TypeInfoFactoryKt.createTypeInfo(resultType, tryOutputContext);
|
||||
|
||||
if (finallyBlock != null) {
|
||||
return facade.getTypeInfo(finallyBlock, tryOutputContext).replaceType(resultType);
|
||||
} else if (!nothingInAllCatchBranches || tryInfo == null) {
|
||||
return result;
|
||||
} else {
|
||||
return TypeInfoFactoryKt.createTypeInfo(
|
||||
components.dataFlowAnalyzer.checkType(resultType, tryExpression, tryOutputContext),
|
||||
dataFlowInfoAfterTry
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isCatchBranchesReturnsNothing(List<KtExpression> catchBlocks, BindingContext bindingContext) {
|
||||
return CollectionsKt.all(whichCatchBranchesReturnNothing(catchBlocks, bindingContext), it -> it);
|
||||
}
|
||||
|
||||
private static List<Boolean> whichCatchBranchesReturnNothing(List<KtExpression> catchBlocks, BindingContext bindingContext) {
|
||||
return catchBlocks.stream()
|
||||
.map(catchBlock -> BindingContextUtils.getRecordedTypeInfo(catchBlock, bindingContext))
|
||||
.map(catchTypeInfo -> {
|
||||
if (catchTypeInfo == null) return true;
|
||||
KotlinType catchType = catchTypeInfo.getType();
|
||||
return catchType == null || KotlinBuiltIns.isNothing(catchType);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private VariableDescriptor resolveAndCheckCatchParameter(@NotNull KtParameter catchParameter, ExpressionTypingContext context) {
|
||||
checkCatchParameterDeclaration(catchParameter, context);
|
||||
|
||||
VariableDescriptor variableDescriptor = components.descriptorResolver
|
||||
.resolveLocalVariableDescriptor(context.scope, catchParameter, context.trace);
|
||||
KotlinType catchParameterType = variableDescriptor.getType();
|
||||
checkCatchParameterType(catchParameter, catchParameterType, context);
|
||||
KotlinType throwableType = components.builtIns.getThrowable().getDefaultType();
|
||||
components.dataFlowAnalyzer.checkType(catchParameterType, catchParameter, context.replaceExpectedType(throwableType));
|
||||
return variableDescriptor;
|
||||
}
|
||||
|
||||
private ExpressionTypingContext getCleanedContextFromTryWithAssignmentsToVar(
|
||||
KtTryExpression tryExpression,
|
||||
boolean nothingInAllCatchBranches,
|
||||
ExpressionTypingContext context
|
||||
) {
|
||||
context = context.replaceExpectedType(NO_EXPECTED_TYPE);
|
||||
if (!nothingInAllCatchBranches && facade.getComponents().languageVersionSettings.supportsFeature(LanguageFeature.SoundSmartCastsAfterTry)) {
|
||||
PreliminaryLoopVisitor tryVisitor = PreliminaryLoopVisitor.visitTryBlock(tryExpression);
|
||||
context = context.replaceDataFlowInfo(
|
||||
tryVisitor.clearDataFlowInfoForAssignedLocalVariables(context.dataFlowInfo, components.languageVersionSettings)
|
||||
);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
private static void checkCatchParameterType(KtParameter catchParameter, KotlinType catchParameterType, ExpressionTypingContext context) {
|
||||
TypeParameterDescriptor typeParameterDescriptor = TypeUtils.getTypeParameterDescriptorOrNull(catchParameterType);
|
||||
if (typeParameterDescriptor != null) {
|
||||
@@ -679,7 +791,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
|
||||
} else {
|
||||
KotlinTypeInfo result = facade
|
||||
.getTypeInfo(returnedExpression, context.replaceExpectedType(newInferenceLambdaInfo.getExpectedType())
|
||||
.replaceContextDependency(newInferenceLambdaInfo.getContextDependency()));
|
||||
.replaceContextDependency(newInferenceLambdaInfo.getContextDependency()));
|
||||
contextInfo = new LambdaContextInfo(result, null, context.scope, context.trace);
|
||||
}
|
||||
newInferenceLambdaInfo.getReturnStatements().add(new kotlin.Pair<>(expression, contextInfo));
|
||||
|
||||
+5
-4
@@ -24,10 +24,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.tower.KotlinResolutionCallbacksImpl;
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind;
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope;
|
||||
import org.jetbrains.kotlin.resolve.scopes.TraceBasedLocalRedeclarationChecker;
|
||||
import org.jetbrains.kotlin.resolve.scopes.*;
|
||||
import org.jetbrains.kotlin.types.ErrorUtils;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.TypeInfoFactoryKt;
|
||||
@@ -380,4 +377,8 @@ public class ExpressionTypingServices {
|
||||
return slice == BindingContext.EXPRESSION_EFFECTS;
|
||||
}
|
||||
}
|
||||
|
||||
public LocalRedeclarationChecker createLocalRedeclarationChecker(BindingTrace trace) {
|
||||
return new TraceBasedLocalRedeclarationChecker(trace, expressionTypingComponents.overloadChecker);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,15 +14,15 @@ fun foo() : Int {
|
||||
}
|
||||
|
||||
fun bar() : Int =
|
||||
try {
|
||||
<!NI;TYPE_MISMATCH, TYPE_MISMATCH!>doSmth()<!>
|
||||
<!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>try {
|
||||
<!OI;TYPE_MISMATCH!>doSmth()<!>
|
||||
}
|
||||
catch (e: Exception) {
|
||||
<!TYPE_MISMATCH!>""<!>
|
||||
<!OI;TYPE_MISMATCH!>""<!>
|
||||
}
|
||||
finally {
|
||||
<!UNUSED_EXPRESSION!>""<!>
|
||||
}
|
||||
}<!>
|
||||
|
||||
|
||||
fun doSmth() {}
|
||||
|
||||
@@ -5,15 +5,15 @@ class ExcA : Exception()
|
||||
class ExcB : Exception()
|
||||
|
||||
fun test2() {
|
||||
val s: String? = try {
|
||||
val s: String? = <!NI;TYPE_MISMATCH!>try {
|
||||
""
|
||||
}
|
||||
catch (e: ExcA) {
|
||||
null
|
||||
}
|
||||
catch (e: ExcB) {
|
||||
<!CONSTANT_EXPECTED_TYPE_MISMATCH!>10<!>
|
||||
}
|
||||
<!OI;CONSTANT_EXPECTED_TYPE_MISMATCH!>10<!>
|
||||
}<!>
|
||||
s<!UNSAFE_CALL!>.<!>length
|
||||
}
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@ fun test0(): List<Int> = run {
|
||||
}
|
||||
}
|
||||
|
||||
fun test1(): Map<Int, Int> = <!NI;TYPE_MISMATCH!>run {
|
||||
<!NI;TYPE_MISMATCH!>try {
|
||||
fun test1(): Map<Int, Int> = run {
|
||||
try {
|
||||
emptyMap()
|
||||
} catch (e: ExcA) {
|
||||
emptyMap()
|
||||
@@ -22,13 +22,13 @@ fun test1(): Map<Int, Int> = <!NI;TYPE_MISMATCH!>run {
|
||||
e.map
|
||||
} finally {
|
||||
<!UNUSED_EXPRESSION!>""<!>
|
||||
}<!>
|
||||
}<!>
|
||||
}
|
||||
}
|
||||
|
||||
fun test2(): Map<Int, Int> = <!NI;TYPE_MISMATCH!>run {
|
||||
<!NI;TYPE_MISMATCH!>try {
|
||||
fun test2(): Map<Int, Int> = run {
|
||||
<!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>try {
|
||||
emptyMap()
|
||||
} catch (e: ExcA) {
|
||||
<!OI;TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH!>mapOf("" to "")<!>
|
||||
<!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, OI;TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH!>mapOf(<!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>"" to ""<!>)<!>
|
||||
}<!>
|
||||
}<!>
|
||||
}
|
||||
Reference in New Issue
Block a user