mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
CFGBuilder#assignAndPop, assign
This commit is contained in:
@@ -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) {
|
||||
|
||||
+4
-7
@@ -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;
|
||||
}
|
||||
|
||||
+8
-10
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user