Commit dd16819f authored by Tagir Valeev's avatar Tagir Valeev
Browse files

CFGBuilder#assignAndPop, assign

parent 07ade078
Branches unavailable Tags unavailable
No related merge requests found
Showing with 57 additions and 20 deletions
+57 -20
......@@ -235,7 +235,7 @@ public class CFGBuilder {
* @param relation relation to use for comparison
* @return this builder
*/
private CFGBuilder compare(IElementType relation) {
CFGBuilder compare(IElementType relation) {
return add(new BinopInstruction(relation, null, PsiType.BOOLEAN));
}
......@@ -415,6 +415,49 @@ public class CFGBuilder {
return add(new AssignInstruction(null, null));
}
/**
* Generate instructions to assign given source value to the given target value. Stack remains unchanged.
* May skip generating instructions if target is not writable (e.g. not a variable)
*
* @param target target to write
* @param source source value
* @return this builder
*/
public CFGBuilder assignAndPop(DfaValue target, DfaValue source) {
if (target instanceof DfaVariableValue) {
if (source == DfaUnknownValue.getInstance()) {
add(new FlushVariableInstruction((DfaVariableValue)target));
} else {
pushForWrite((DfaVariableValue)target).push(source).assign().pop();
}
}
return this;
}
/**
* Generate instructions to assign given source value to the given target value and leave the result on stack.
* <p>
* Stack before: ...
* <p>
* Stack after: ... target
*
* @param target target to write
* @param source source value
* @return this builder
*/
public CFGBuilder assign(DfaValue target, DfaValue source) {
if (target instanceof DfaVariableValue) {
if (source == DfaUnknownValue.getInstance()) {
add(new FlushVariableInstruction((DfaVariableValue)target)).push(target);
} else {
pushForWrite((DfaVariableValue)target).push(source).assign();
}
} else {
push(source);
}
return this;
}
/**
* Generate instructions to assign top stack value to the specified variable
* <p>
......@@ -638,8 +681,7 @@ public class CFGBuilder {
ConditionalGotoInstruction condGoto = new ConditionalGotoInstruction(null, false, null);
condGoto.setOffset(myAnalyzer.getInstructionCount());
myBranches.add(() -> pushUnknown().add(condGoto));
DfaValue loopElement = factory.createCommonValue(expressions);
pushForWrite(targetVariable).push(loopElement).assign();
assign(targetVariable, factory.createCommonValue(expressions));
} else {
push(factory.getConstFactory().getSentinel());
for (PsiExpression expression : expressions) {
......
......@@ -104,13 +104,10 @@ public class CollectionFactoryInliner implements CallInliner {
builder.push(result);
} else {
DfaVariableValue variableValue = builder.createTempVariable(call.getType());
builder.pushForWrite(variableValue) // tmpVar = <Value of collection type>
.push(result)
.assign() // leave tmpVar on stack: it's result of method call
.push(factoryInfo.mySizeField.createValue(factory, variableValue)) // tmpVar.size = <size>
.push(factory.getInt(factoryInfo.mySize))
.assign()
.pop();
// tmpVar = <Value of collection type>; leave tmpVar on stack: it's result of method call
builder.assign(variableValue, result);
// tmpVar.size = <size>
builder.assignAndPop(factoryInfo.mySizeField.createValue(factory, variableValue), factory.getInt(factoryInfo.mySize));
}
return true;
}
......
......@@ -16,6 +16,8 @@
package com.intellij.codeInspection.dataFlow.inliner;
import com.intellij.codeInspection.dataFlow.*;
import com.intellij.codeInspection.dataFlow.value.DfaConstValue;
import com.intellij.codeInspection.dataFlow.value.DfaUnknownValue;
import com.intellij.codeInspection.dataFlow.value.DfaValue;
import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
import com.intellij.psi.*;
......@@ -243,7 +245,7 @@ public class StreamChainInliner implements CallInliner {
@Override
void iteration(CFGBuilder builder) {
builder.pushForWrite(myResult).pushUnknown().assign().splice(2);
builder.pop().assignAndPop(myResult, DfaUnknownValue.getInstance());
}
}
......@@ -262,7 +264,7 @@ public class StreamChainInliner implements CallInliner {
if (myFunction != null) {
builder.pushUnknown().invokeFunction(2, myFunction);
}
builder.pushForWrite(myResult).push(builder.getFactory().getFactValue(DfaFactType.OPTIONAL_PRESENCE, true)).assign().splice(2);
builder.assign(myResult, builder.getFactory().getFactValue(DfaFactType.OPTIONAL_PRESENCE, true)).splice(2);
}
}
......@@ -288,7 +290,7 @@ public class StreamChainInliner implements CallInliner {
@Override
void iteration(CFGBuilder builder) {
myComparatorModel.invoke(builder);
builder.pushForWrite(myResult).push(builder.getFactory().getFactValue(DfaFactType.OPTIONAL_PRESENCE, true)).assign().pop();
builder.assignAndPop(myResult, builder.getFactory().getFactValue(DfaFactType.OPTIONAL_PRESENCE, true));
}
@Override
......@@ -309,12 +311,10 @@ public class StreamChainInliner implements CallInliner {
@Override
void iteration(CFGBuilder builder) {
DfaConstValue result = builder.getFactory().getBoolean("anyMatch".equals(myCall.getMethodExpression().getReferenceName()));
builder.invokeFunction(1, myFunction)
.ifConditionIs(!"allMatch".equals(myCall.getMethodExpression().getReferenceName()))
.pushForWrite(myResult)
.push(builder.getFactory().getBoolean("anyMatch".equals(myCall.getMethodExpression().getReferenceName())))
.assign()
.pop()
.assignAndPop(myResult, result)
.end();
}
}
......@@ -731,9 +731,7 @@ public class StreamChainInliner implements CallInliner {
private static void makeMainLoop(CFGBuilder builder, Step firstStep, PsiType inType) {
builder.doWhileUnknown()
.pushForWrite(builder.createTempVariable(inType))
.push(builder.getFactory().createTypeValue(inType, DfaPsiUtil.getTypeNullability(inType)))
.assign()
.assign(builder.createTempVariable(inType), builder.getFactory().createTypeValue(inType, DfaPsiUtil.getTypeNullability(inType)))
.chain(firstStep::iteration).end();
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment