Get rid of MutableDataFlorInfoForArguments.setInitialDataFlowInfo

This commit is contained in:
Mikhail Glukhikh
2016-01-14 13:02:20 +03:00
parent 5ceb973ee9
commit 16d97ab72c
8 changed files with 33 additions and 52 deletions
@@ -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.callUtil.getCall
import org.jetbrains.kotlin.resolve.calls.model.* import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.getExplicitReceiverValue 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.ExplicitReceiverKind
import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionCandidate import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionCandidate
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy
@@ -112,7 +113,7 @@ fun getExpectedTypePredicate(
resolutionCandidate, resolutionCandidate,
DelegatingBindingTrace(bindingContext, "Compute type predicates for unresolved call arguments"), DelegatingBindingTrace(bindingContext, "Compute type predicates for unresolved call arguments"),
TracingStrategy.EMPTY, TracingStrategy.EMPTY,
DataFlowInfoForArgumentsImpl(call) DataFlowInfoForArgumentsImpl(DataFlowInfo.EMPTY, call)
) )
val status = ValueArgumentsToParametersMapper.mapValueArgumentsToParameters(call, val status = ValueArgumentsToParametersMapper.mapValueArgumentsToParameters(call,
TracingStrategy.EMPTY, TracingStrategy.EMPTY,
@@ -313,7 +313,6 @@ public class ArgumentTypeResolver {
) { ) {
MutableDataFlowInfoForArguments infoForArguments = context.dataFlowInfoForArguments; MutableDataFlowInfoForArguments infoForArguments = context.dataFlowInfoForArguments;
Call call = context.call; Call call = context.call;
infoForArguments.setInitialDataFlowInfo(context.dataFlowInfo);
for (ValueArgument argument : call.getValueArguments()) { for (ValueArgument argument : call.getValueArguments()) {
KtExpression expression = argument.getArgumentExpression(); KtExpression expression = argument.getArgumentExpression();
@@ -60,10 +60,10 @@ public abstract class CallResolutionContext<Context extends CallResolutionContex
this.dataFlowInfoForArguments = dataFlowInfoForArguments; this.dataFlowInfoForArguments = dataFlowInfoForArguments;
} }
else if (checkArguments == CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS) { else if (checkArguments == CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS) {
this.dataFlowInfoForArguments = new DataFlowInfoForArgumentsImpl(call); this.dataFlowInfoForArguments = new DataFlowInfoForArgumentsImpl(dataFlowInfo, call);
} }
else { else {
this.dataFlowInfoForArguments = new MutableDataFlowInfoForArguments.WithoutArgumentsCheck(); this.dataFlowInfoForArguments = new MutableDataFlowInfoForArguments.WithoutArgumentsCheck(dataFlowInfo);
} }
} }
@@ -27,15 +27,13 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
public class DataFlowInfoForArgumentsImpl implements MutableDataFlowInfoForArguments { public class DataFlowInfoForArgumentsImpl extends MutableDataFlowInfoForArguments {
@NotNull private final Call call; //for better debug messages only
@Nullable private Map<ValueArgument, DataFlowInfo> infoMap = null; @Nullable private Map<ValueArgument, DataFlowInfo> infoMap = null;
@Nullable private Map<ValueArgument, ValueArgument> nextArgument = null; @Nullable private Map<ValueArgument, ValueArgument> nextArgument = null;
@Nullable private DataFlowInfo initialInfo;
@Nullable private DataFlowInfo resultInfo; @Nullable private DataFlowInfo resultInfo;
public DataFlowInfoForArgumentsImpl(@NotNull Call call) { public DataFlowInfoForArgumentsImpl(@NotNull DataFlowInfo initialInfo, @NotNull Call call) {
this.call = call; super(initialInfo);
initNextArgMap(call.getValueArguments()); 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 @NotNull
@Override @Override
public DataFlowInfo getInfo(@NotNull ValueArgument valueArgument) { 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); DataFlowInfo infoForArgument = infoMap == null ? null : infoMap.get(valueArgument);
if (infoForArgument == null) { if (infoForArgument == null) {
return initialInfo; return initialDataFlowInfo;
} }
return initialInfo.and(infoForArgument); return initialDataFlowInfo.and(infoForArgument);
} }
@Override @Override
@@ -88,8 +79,7 @@ public class DataFlowInfoForArgumentsImpl implements MutableDataFlowInfoForArgum
@NotNull @NotNull
@Override @Override
public DataFlowInfo getResultInfo() { public DataFlowInfo getResultInfo() {
assert initialInfo != null : "Initial data flow info was not set for call: " + call; if (resultInfo == null) return initialDataFlowInfo;
if (resultInfo == null) return initialInfo; return initialDataFlowInfo.and(resultInfo);
return initialInfo.and(resultInfo);
} }
} }
@@ -20,18 +20,26 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.psi.ValueArgument; import org.jetbrains.kotlin.psi.ValueArgument;
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo; 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 { public abstract void updateInfo(@NotNull ValueArgument valueArgument, @NotNull DataFlowInfo dataFlowInfo);
private DataFlowInfo dataFlowInfo;
@Override @NotNull
public void setInitialDataFlowInfo(@NotNull DataFlowInfo dataFlowInfo) { @Override
this.dataFlowInfo = dataFlowInfo; public DataFlowInfo getResultInfo() {
return initialDataFlowInfo;
}
public static class WithoutArgumentsCheck extends MutableDataFlowInfoForArguments {
public WithoutArgumentsCheck(@NotNull DataFlowInfo dataFlowInfo) {
super(dataFlowInfo);
} }
@Override @Override
@@ -44,11 +52,5 @@ public interface MutableDataFlowInfoForArguments extends DataFlowInfoForArgument
public DataFlowInfo getInfo(@NotNull ValueArgument valueArgument) { public DataFlowInfo getInfo(@NotNull ValueArgument valueArgument) {
throw new IllegalStateException(); throw new IllegalStateException();
} }
@NotNull
@Override
public DataFlowInfo getResultInfo() {
return dataFlowInfo;
}
}; };
} }
@@ -564,7 +564,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
ResolvedCallImpl.create(resolutionCandidate, ResolvedCallImpl.create(resolutionCandidate,
TemporaryBindingTrace.create(trace, "Fake trace for fake 'this' or 'super' resolved call"), TemporaryBindingTrace.create(trace, "Fake trace for fake 'this' or 'super' resolved call"),
TracingStrategy.EMPTY, TracingStrategy.EMPTY,
new DataFlowInfoForArgumentsImpl(call)); new DataFlowInfoForArgumentsImpl(context.dataFlowInfo, call));
resolvedCall.markCallAsCompleted(); resolvedCall.markCallAsCompleted();
trace.record(RESOLVED_CALL, call, resolvedCall); trace.record(RESOLVED_CALL, call, resolvedCall);
@@ -157,15 +157,10 @@ public class ControlStructureTypingUtils {
} }
/*package*/ static MutableDataFlowInfoForArguments createIndependentDataFlowInfoForArgumentsForCall( /*package*/ static MutableDataFlowInfoForArguments createIndependentDataFlowInfoForArgumentsForCall(
@NotNull DataFlowInfo initialDataFlowInfo,
final Map<ValueArgument, DataFlowInfo> dataFlowInfoForArgumentsMap final Map<ValueArgument, DataFlowInfo> dataFlowInfoForArgumentsMap
) { ) {
return new MutableDataFlowInfoForArguments() { return new MutableDataFlowInfoForArguments(initialDataFlowInfo) {
private DataFlowInfo initialDataFlowInfo;
@Override
public void setInitialDataFlowInfo(@NotNull DataFlowInfo dataFlowInfo) {
this.initialDataFlowInfo = dataFlowInfo;
}
@Override @Override
public void updateInfo(@NotNull ValueArgument valueArgument, @NotNull DataFlowInfo dataFlowInfo) { public void updateInfo(@NotNull ValueArgument valueArgument, @NotNull DataFlowInfo dataFlowInfo) {
@@ -177,25 +172,19 @@ public class ControlStructureTypingUtils {
public DataFlowInfo getInfo(@NotNull ValueArgument valueArgument) { public DataFlowInfo getInfo(@NotNull ValueArgument valueArgument) {
return dataFlowInfoForArgumentsMap.get(valueArgument); return dataFlowInfoForArgumentsMap.get(valueArgument);
} }
@NotNull
@Override
public DataFlowInfo getResultInfo() {
//todo merge and use
return initialDataFlowInfo;
}
}; };
} }
public static MutableDataFlowInfoForArguments createDataFlowInfoForArgumentsForIfCall( public static MutableDataFlowInfoForArguments createDataFlowInfoForArgumentsForIfCall(
@NotNull Call callForIf, @NotNull Call callForIf,
@NotNull DataFlowInfo conditionInfo,
@NotNull DataFlowInfo thenInfo, @NotNull DataFlowInfo thenInfo,
@NotNull DataFlowInfo elseInfo @NotNull DataFlowInfo elseInfo
) { ) {
Map<ValueArgument, DataFlowInfo> dataFlowInfoForArgumentsMap = Maps.newHashMap(); Map<ValueArgument, DataFlowInfo> dataFlowInfoForArgumentsMap = Maps.newHashMap();
dataFlowInfoForArgumentsMap.put(callForIf.getValueArguments().get(0), thenInfo); dataFlowInfoForArgumentsMap.put(callForIf.getValueArguments().get(0), thenInfo);
dataFlowInfoForArgumentsMap.put(callForIf.getValueArguments().get(1), elseInfo); dataFlowInfoForArgumentsMap.put(callForIf.getValueArguments().get(1), elseInfo);
return createIndependentDataFlowInfoForArgumentsForCall(dataFlowInfoForArgumentsMap); return createIndependentDataFlowInfoForArgumentsForCall(conditionInfo, dataFlowInfoForArgumentsMap);
} }
/*package*/ static Call createCallForSpecialConstruction( /*package*/ static Call createCallForSpecialConstruction(
@@ -125,7 +125,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
KtBlockExpression elseBlock = psiFactory.wrapInABlockWrapper(elseBranch); KtBlockExpression elseBlock = psiFactory.wrapInABlockWrapper(elseBranch);
Call callForIf = createCallForSpecialConstruction(ifExpression, ifExpression, Lists.newArrayList(thenBlock, elseBlock)); Call callForIf = createCallForSpecialConstruction(ifExpression, ifExpression, Lists.newArrayList(thenBlock, elseBlock));
MutableDataFlowInfoForArguments dataFlowInfoForArguments = MutableDataFlowInfoForArguments dataFlowInfoForArguments =
createDataFlowInfoForArgumentsForIfCall(callForIf, thenInfo, elseInfo); createDataFlowInfoForArgumentsForIfCall(callForIf, conditionDataFlowInfo, thenInfo, elseInfo);
ResolvedCall<FunctionDescriptor> resolvedCall = components.controlStructureTypingUtils.resolveSpecialConstructionAsCall( ResolvedCall<FunctionDescriptor> resolvedCall = components.controlStructureTypingUtils.resolveSpecialConstructionAsCall(
callForIf, ResolveConstruct.IF, Lists.newArrayList("thenBranch", "elseBranch"), callForIf, ResolveConstruct.IF, Lists.newArrayList("thenBranch", "elseBranch"),
Lists.newArrayList(false, false), Lists.newArrayList(false, false),