diff --git a/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/pseudocodeUtils.kt b/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/pseudocodeUtils.kt index efd9a3f79cc..906745545c6 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/pseudocodeUtils.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/pseudocodeUtils.kt @@ -41,6 +41,7 @@ import org.jetbrains.kotlin.resolve.calls.ValueArgumentsToParametersMapper import org.jetbrains.kotlin.resolve.calls.callUtil.getCall import org.jetbrains.kotlin.resolve.calls.model.* import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.getExplicitReceiverValue +import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionCandidate import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy @@ -112,7 +113,7 @@ fun getExpectedTypePredicate( resolutionCandidate, DelegatingBindingTrace(bindingContext, "Compute type predicates for unresolved call arguments"), TracingStrategy.EMPTY, - DataFlowInfoForArgumentsImpl(call) + DataFlowInfoForArgumentsImpl(DataFlowInfo.EMPTY, call) ) val status = ValueArgumentsToParametersMapper.mapValueArgumentsToParameters(call, TracingStrategy.EMPTY, diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/ArgumentTypeResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/ArgumentTypeResolver.java index e99836065e1..a1316764820 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/ArgumentTypeResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/ArgumentTypeResolver.java @@ -313,7 +313,6 @@ public class ArgumentTypeResolver { ) { MutableDataFlowInfoForArguments infoForArguments = context.dataFlowInfoForArguments; Call call = context.call; - infoForArguments.setInitialDataFlowInfo(context.dataFlowInfo); for (ValueArgument argument : call.getValueArguments()) { KtExpression expression = argument.getArgumentExpression(); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/context/CallResolutionContext.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/context/CallResolutionContext.java index 9e0093427f2..2107d52a501 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/context/CallResolutionContext.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/context/CallResolutionContext.java @@ -60,10 +60,10 @@ public abstract class CallResolutionContext infoMap = null; @Nullable private Map nextArgument = null; - @Nullable private DataFlowInfo initialInfo; @Nullable private DataFlowInfo resultInfo; - public DataFlowInfoForArgumentsImpl(@NotNull Call call) { - this.call = call; + public DataFlowInfoForArgumentsImpl(@NotNull DataFlowInfo initialInfo, @NotNull Call call) { + super(initialInfo); initNextArgMap(call.getValueArguments()); } @@ -54,21 +52,14 @@ public class DataFlowInfoForArgumentsImpl implements MutableDataFlowInfoForArgum } } - @Override - public void setInitialDataFlowInfo(@NotNull DataFlowInfo dataFlowInfo) { - //TODO assert initialInfo == null - initialInfo = dataFlowInfo; - } - @NotNull @Override public DataFlowInfo getInfo(@NotNull ValueArgument valueArgument) { - assert initialInfo != null : "Initial data flow info was not set for call: " + call; DataFlowInfo infoForArgument = infoMap == null ? null : infoMap.get(valueArgument); if (infoForArgument == null) { - return initialInfo; + return initialDataFlowInfo; } - return initialInfo.and(infoForArgument); + return initialDataFlowInfo.and(infoForArgument); } @Override @@ -88,8 +79,7 @@ public class DataFlowInfoForArgumentsImpl implements MutableDataFlowInfoForArgum @NotNull @Override public DataFlowInfo getResultInfo() { - assert initialInfo != null : "Initial data flow info was not set for call: " + call; - if (resultInfo == null) return initialInfo; - return initialInfo.and(resultInfo); + if (resultInfo == null) return initialDataFlowInfo; + return initialDataFlowInfo.and(resultInfo); } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/model/MutableDataFlowInfoForArguments.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/model/MutableDataFlowInfoForArguments.java index ff736178bae..757c766a82e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/model/MutableDataFlowInfoForArguments.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/model/MutableDataFlowInfoForArguments.java @@ -20,18 +20,26 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.psi.ValueArgument; import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo; -public interface MutableDataFlowInfoForArguments extends DataFlowInfoForArguments { +public abstract class MutableDataFlowInfoForArguments implements DataFlowInfoForArguments { - void setInitialDataFlowInfo(@NotNull DataFlowInfo dataFlowInfo); + @NotNull protected final DataFlowInfo initialDataFlowInfo; - void updateInfo(@NotNull ValueArgument valueArgument, @NotNull DataFlowInfo dataFlowInfo); + public MutableDataFlowInfoForArguments(@NotNull DataFlowInfo initialDataFlowInfo) { + this.initialDataFlowInfo = initialDataFlowInfo; + } - class WithoutArgumentsCheck implements MutableDataFlowInfoForArguments { - private DataFlowInfo dataFlowInfo; + public abstract void updateInfo(@NotNull ValueArgument valueArgument, @NotNull DataFlowInfo dataFlowInfo); - @Override - public void setInitialDataFlowInfo(@NotNull DataFlowInfo dataFlowInfo) { - this.dataFlowInfo = dataFlowInfo; + @NotNull + @Override + public DataFlowInfo getResultInfo() { + return initialDataFlowInfo; + } + + public static class WithoutArgumentsCheck extends MutableDataFlowInfoForArguments { + + public WithoutArgumentsCheck(@NotNull DataFlowInfo dataFlowInfo) { + super(dataFlowInfo); } @Override @@ -44,11 +52,5 @@ public interface MutableDataFlowInfoForArguments extends DataFlowInfoForArgument public DataFlowInfo getInfo(@NotNull ValueArgument valueArgument) { throw new IllegalStateException(); } - - @NotNull - @Override - public DataFlowInfo getResultInfo() { - return dataFlowInfo; - } }; } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java index 4f5cd1e03f7..1d1159925f5 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java @@ -564,7 +564,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { ResolvedCallImpl.create(resolutionCandidate, TemporaryBindingTrace.create(trace, "Fake trace for fake 'this' or 'super' resolved call"), TracingStrategy.EMPTY, - new DataFlowInfoForArgumentsImpl(call)); + new DataFlowInfoForArgumentsImpl(context.dataFlowInfo, call)); resolvedCall.markCallAsCompleted(); trace.record(RESOLVED_CALL, call, resolvedCall); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingUtils.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingUtils.java index 97568184b36..af10249a880 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingUtils.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingUtils.java @@ -157,15 +157,10 @@ public class ControlStructureTypingUtils { } /*package*/ static MutableDataFlowInfoForArguments createIndependentDataFlowInfoForArgumentsForCall( + @NotNull DataFlowInfo initialDataFlowInfo, final Map dataFlowInfoForArgumentsMap ) { - return new MutableDataFlowInfoForArguments() { - private DataFlowInfo initialDataFlowInfo; - - @Override - public void setInitialDataFlowInfo(@NotNull DataFlowInfo dataFlowInfo) { - this.initialDataFlowInfo = dataFlowInfo; - } + return new MutableDataFlowInfoForArguments(initialDataFlowInfo) { @Override public void updateInfo(@NotNull ValueArgument valueArgument, @NotNull DataFlowInfo dataFlowInfo) { @@ -177,25 +172,19 @@ public class ControlStructureTypingUtils { public DataFlowInfo getInfo(@NotNull ValueArgument valueArgument) { return dataFlowInfoForArgumentsMap.get(valueArgument); } - - @NotNull - @Override - public DataFlowInfo getResultInfo() { - //todo merge and use - return initialDataFlowInfo; - } }; } public static MutableDataFlowInfoForArguments createDataFlowInfoForArgumentsForIfCall( @NotNull Call callForIf, + @NotNull DataFlowInfo conditionInfo, @NotNull DataFlowInfo thenInfo, @NotNull DataFlowInfo elseInfo ) { Map dataFlowInfoForArgumentsMap = Maps.newHashMap(); dataFlowInfoForArgumentsMap.put(callForIf.getValueArguments().get(0), thenInfo); dataFlowInfoForArgumentsMap.put(callForIf.getValueArguments().get(1), elseInfo); - return createIndependentDataFlowInfoForArgumentsForCall(dataFlowInfoForArgumentsMap); + return createIndependentDataFlowInfoForArgumentsForCall(conditionInfo, dataFlowInfoForArgumentsMap); } /*package*/ static Call createCallForSpecialConstruction( diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingVisitor.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingVisitor.java index ffaa81a03f3..4b438f7ef6d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ControlStructureTypingVisitor.java @@ -125,7 +125,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { KtBlockExpression elseBlock = psiFactory.wrapInABlockWrapper(elseBranch); Call callForIf = createCallForSpecialConstruction(ifExpression, ifExpression, Lists.newArrayList(thenBlock, elseBlock)); MutableDataFlowInfoForArguments dataFlowInfoForArguments = - createDataFlowInfoForArgumentsForIfCall(callForIf, thenInfo, elseInfo); + createDataFlowInfoForArgumentsForIfCall(callForIf, conditionDataFlowInfo, thenInfo, elseInfo); ResolvedCall resolvedCall = components.controlStructureTypingUtils.resolveSpecialConstructionAsCall( callForIf, ResolveConstruct.IF, Lists.newArrayList("thenBranch", "elseBranch"), Lists.newArrayList(false, false),