[java-dfa] Keep JvmPushInstruction for write only (JvmPushForWriteInstruction)

GitOrigin-RevId: e4ced75e32a14eff1c42b216dad947a4f4a4c032
This commit is contained in:
Tagir Valeev
2024-11-08 13:00:01 +00:00
committed by intellij-monorepo-bot
parent d7af3fc254
commit 24bbf0e151
7 changed files with 91 additions and 81 deletions
@@ -17,7 +17,6 @@ import com.intellij.codeInspection.dataFlow.java.anchor.JavaExpressionAnchor;
import com.intellij.codeInspection.dataFlow.java.inst.AssignInstruction;
import com.intellij.codeInspection.dataFlow.java.inst.CheckNotNullInstruction;
import com.intellij.codeInspection.dataFlow.java.inst.InstanceofInstruction;
import com.intellij.codeInspection.dataFlow.java.inst.JvmPushInstruction;
import com.intellij.codeInspection.dataFlow.jvm.FieldChecker;
import com.intellij.codeInspection.dataFlow.jvm.JvmPsiRangeSetUtil;
import com.intellij.codeInspection.dataFlow.jvm.SpecialField;
@@ -548,7 +547,7 @@ public final class TrackingRunner extends StandardDataFlowRunner {
public CauseItem[] findCauses(TrackingRunner runner, PsiExpression expression, MemoryStateChange history) {
DfaValue topOfStack = history.myTopOfStack;
DfaValue value = myField.createValue(runner.getFactory(), topOfStack);
MemoryStateChange change = MemoryStateChange.create(history, new JvmPushInstruction(value, null), Map.of(), value);
MemoryStateChange change = MemoryStateChange.create(history, new PushInstruction(value, null), Map.of(), value);
return runner.findConstantValueCause(expression, change, 0);
}
@@ -1447,12 +1446,12 @@ public final class TrackingRunner extends StandardDataFlowRunner {
right = rightVal.makeDfaValue(getFactory(), arguments);
}
if (leftPush == null && left != top) {
leftPush = MemoryStateChange.create(history.getPrevious(), new JvmPushInstruction(left, null), Collections.emptyMap(), left);
leftPush = MemoryStateChange.create(history.getPrevious(), new PushInstruction(left, null), Collections.emptyMap(), left);
}
PsiExpression rightPlace = rightVal.findPlace(call);
MemoryStateChange rightPush = history.findSubExpressionPush(rightPlace);
if (rightPush == null && right != top) {
rightPush = MemoryStateChange.create(history.getPrevious(), new JvmPushInstruction(right, null), Collections.emptyMap(), right);
rightPush = MemoryStateChange.create(history.getPrevious(), new PushInstruction(right, null), Collections.emptyMap(), right);
}
if (leftPush != null && rightPush != null) {
causeItem.addChildren(findRelationCause(type,
@@ -161,7 +161,7 @@ public class CFGBuilder {
* @return this builder
*/
public CFGBuilder pushForWrite(DfaVariableValue variable) {
return add(new JvmPushInstruction(variable, null, true));
return add(new JvmPushForWriteInstruction(variable));
}
/**
@@ -175,7 +175,7 @@ public class CFGBuilder {
* @return this builder
*/
public CFGBuilder push(DfaValue value) {
return add(new JvmPushInstruction(value, null));
return add(new PushInstruction(value, null));
}
/**
@@ -190,7 +190,7 @@ public class CFGBuilder {
* @return this builder
*/
public CFGBuilder push(DfaValue value, PsiExpression expression) {
return add(new JvmPushInstruction(value, expression == null ? null : new JavaExpressionAnchor(expression)));
return add(new PushInstruction(value, expression == null ? null : new JavaExpressionAnchor(expression)));
}
/**
@@ -310,7 +310,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
private void initializeVariable(PsiVariable variable, PsiExpression initializer) {
if (JavaDfaValueFactory.ignoreInitializer(variable)) return;
DfaVariableValue dfaVariable = PlainDescriptor.createVariableValue(myFactory, variable);
addInstruction(new JvmPushInstruction(dfaVariable, null, true));
addInstruction(new JvmPushForWriteInstruction(dfaVariable));
initializer.accept(this);
generateBoxingUnboxingInstructionFor(initializer, variable.getType());
addInstruction(new AssignInstruction(initializer, dfaVariable));
@@ -955,7 +955,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
}
private void push(@NotNull DfaValue value, @NotNull PsiExpression expression) {
addInstruction(new JvmPushInstruction(value, new JavaExpressionAnchor(expression)));
addInstruction(new PushInstruction(value, new JavaExpressionAnchor(expression)));
}
private void push(@NotNull DfType dfType, @NotNull PsiExpression expression) {
@@ -1011,17 +1011,17 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
ref.resolve() instanceof PsiEnumConstant;
if (expressionValue != null && (enumConstant || PsiUtil.isConstantExpression(expr))) {
if (PsiPrimitiveType.getUnboxedType(targetType) == null) {
addInstruction(new JvmPushInstruction(expressionValue, null));
addInstruction(new PushInstruction(expressionValue, null));
expr.accept(this);
addInstruction(new BooleanBinaryInstruction(RelationType.EQ, true, new JavaSwitchLabelTakenAnchor(expr)));
addInstruction(new ConditionalGotoInstruction(targetOffset, DfTypes.TRUE));
}
else {
addInstruction(new JvmPushInstruction(expressionValue, null));
addInstruction(new PushInstruction(expressionValue, null));
DeferredOffset condGotoOffset = new DeferredOffset();
addInstruction(new ConditionalGotoInstruction(condGotoOffset, DfTypes.NULL));
addInstruction(new JvmPushInstruction(expressionValue, null));
addInstruction(new PushInstruction(expressionValue, null));
generateBoxingUnboxingInstructionFor(selector, PsiPrimitiveType.getUnboxedType(targetType));
expr.accept(this);
addInstruction(new BooleanBinaryInstruction(RelationType.EQ, true, new JavaSwitchLabelTakenAnchor(expr)));
@@ -1038,7 +1038,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
}
}
else if (expressionValue != null && ExpressionUtils.isNullLiteral(expr)) {
addInstruction(new JvmPushInstruction(expressionValue, null));
addInstruction(new PushInstruction(expressionValue, null));
expr.accept(this);
addInstruction(new BooleanBinaryInstruction(RelationType.EQ, true, new JavaSwitchLabelTakenAnchor(expr)));
addInstruction(new ConditionalGotoInstruction(targetOffset, DfTypes.TRUE));
@@ -1092,7 +1092,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
private void processPatternInSwitch(@NotNull PsiPattern pattern, @NotNull DfaVariableValue expressionValue, @NotNull PsiType checkType) {
DeferredOffset endPatternOffset = new DeferredOffset();
addInstruction(new JvmPushInstruction(expressionValue, null));
addInstruction(new PushInstruction(expressionValue, null));
processPattern(pattern, pattern, checkType, null, endPatternOffset);
endPatternOffset.setOffset(getInstructionCount());
}
@@ -1141,7 +1141,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
PsiField field = PropertyUtil.getFieldOfGetter(accessor);
VariableDescriptor descriptor = field == null ? new GetterDescriptor(accessor) : new PlainDescriptor(field);
DfaVariableValue accessorDfaVar = getFactory().getVarFactory().createVariableValue(descriptor, patternDfaVar);
addInstruction(new JvmPushInstruction(accessorDfaVar, null));
addInstruction(new PushInstruction(accessorDfaVar, null));
processPattern(sourcePattern, patternComponent, substitutor.substitute(recordComponent.getType()), null, endPatternOffset);
}
}
@@ -1719,7 +1719,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
.meet(type == null ? DfTypes.OBJECT_OR_NULL : TypeConstraints.exact(type).asDfType())
.meet(DfTypes.LOCAL_OBJECT);
if (arrayWriteTarget != null) {
addInstruction(new JvmPushInstruction(arrayWriteTarget, null, true));
addInstruction(new JvmPushForWriteInstruction(arrayWriteTarget));
push(arrayType, expression);
addInstruction(new AssignInstruction(originalExpression, arrayWriteTarget));
int index = 0;
@@ -1729,7 +1729,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
target = Objects.requireNonNull(ArrayElementDescriptor.getArrayElementValue(getFactory(), arrayWriteTarget, index));
}
index++;
addInstruction(new JvmPushInstruction(target == null ? myFactory.getUnknown() : target, null, true));
addInstruction(new JvmPushForWriteInstruction(target == null ? myFactory.getUnknown() : target));
initializer.accept(this);
if (componentType != null) {
generateBoxingUnboxingInstructionFor(initializer, componentType);
@@ -1740,7 +1740,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
}
else {
for (PsiExpression initializer : initializers) {
addInstruction(new JvmPushInstruction(myFactory.getUnknown(), null, true));
addInstruction(new JvmPushForWriteInstruction(myFactory.getUnknown()));
initializer.accept(this);
if (componentType != null) {
generateBoxingUnboxingInstructionFor(initializer, componentType);
@@ -1750,7 +1750,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
addInstruction(new PopInstruction());
}
if (ControlFlow.isTempVariable(var)) {
addInstruction(new JvmPushInstruction(var, null, true));
addInstruction(new JvmPushForWriteInstruction(var));
push(arrayType, expression);
addInstruction(new AssignInstruction(null, var));
} else {
@@ -2101,7 +2101,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
if (qualifierExpression == null) {
DfaValue thisVariable = JavaDfaValueFactory.getQualifierOrThisValue(myFactory, call.getMethodExpression());
if (thisVariable != null) {
addInstruction(new JvmPushInstruction(thisVariable, null));
addInstruction(new PushInstruction(thisVariable, null));
}
else {
pushUnknown();
@@ -2257,7 +2257,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
qualifierValue = ThisDescriptor.createThisValue(myFactory, outerClass);
}
}
addInstruction(new JvmPushInstruction(qualifierValue, null));
addInstruction(new PushInstruction(qualifierValue, null));
}
PsiMember constructorOrClass = pushConstructorArguments(expression);
@@ -2505,7 +2505,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
if (!writing && var != null && !PlainDescriptor.hasInitializationHacks(var)) {
DfaValue constValue = JavaDfaValueFactory.getConstantFromVariable(myFactory, var);
if (constValue != null && !JavaDfaValueFactory.maybeUninitializedConstant(constValue, expression, var)) {
addInstruction(new JvmPushInstruction(constValue, anchor));
addInstruction(new PushInstruction(constValue, anchor));
return;
}
}
@@ -2513,7 +2513,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
if (var instanceof PsiField field && !field.hasModifierProperty(PsiModifier.STATIC) && !writing) {
DfaValue effectiveQualifier = JavaDfaValueFactory.getQualifierOrThisValue(myFactory, expression);
if (qualifierExpression == null) {
addInstruction(new JvmPushInstruction(effectiveQualifier == null ? myFactory.getUnknown() : effectiveQualifier, null));
addInstruction(new PushInstruction(effectiveQualifier == null ? myFactory.getUnknown() : effectiveQualifier, null));
} else {
qualifierExpression.accept(this);
}
@@ -2532,9 +2532,12 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
}
DfaValue value = JavaDfaValueFactory.getExpressionDfaValue(myFactory, expression);
addInstruction(new JvmPushInstruction(value == null ? myFactory.getUnknown() : value,
writing ? null : anchor,
writing));
if (writing) {
addInstruction(new JvmPushForWriteInstruction(value == null ? myFactory.getUnknown() : value));
}
else {
addInstruction(new PushInstruction(value == null ? myFactory.getUnknown() : value, anchor));
}
}
@Override public void visitLiteralExpression(@NotNull PsiLiteralExpression expression) {
@@ -2617,7 +2620,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
@Nullable PsiType type) {
// Transfer value is pushed to avoid emptying stack beyond this point
pushTrap(new InsideInlinedBlockTrap(block));
addInstruction(new JvmPushInstruction(myFactory.controlTransfer(DfaControlTransferValue.RETURN_TRANSFER, FList.emptyList()), null));
addInstruction(new PushInstruction(myFactory.controlTransfer(DfaControlTransferValue.RETURN_TRANSFER, FList.emptyList()), null));
myExpressionBlockContext =
new ExpressionBlockContext(myExpressionBlockContext, block, resultNullability == Nullability.NOT_NULL, target, type);
startElement(block);
@@ -2734,7 +2737,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
void generateReturn(PsiExpression returnValue, ControlFlowAnalyzer analyzer) {
if (returnValue != null) {
analyzer.addInstruction(new JvmPushInstruction(myTarget, null, true));
analyzer.addInstruction(new JvmPushForWriteInstruction(myTarget));
if (!isSwitch()) {
analyzer.addCustomNullabilityProblem(returnValue, myForceNonNullBlockResult ?
NullabilityProblemKind.nullableFunctionReturn : NullabilityProblemKind.noProblem);
@@ -0,0 +1,29 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection.dataFlow.java.inst;
import com.intellij.codeInspection.dataFlow.lang.ir.Instruction;
import com.intellij.codeInspection.dataFlow.lang.ir.PushInstruction;
import com.intellij.codeInspection.dataFlow.value.DfaValue;
import com.intellij.codeInspection.dataFlow.value.DfaValueFactory;
import org.jetbrains.annotations.NotNull;
/**
* An instruction that pushes given value to the stack for subsequent write via {@link AssignInstruction}
* (it additionally processes escaping)
*/
public class JvmPushForWriteInstruction extends PushInstruction {
public JvmPushForWriteInstruction(@NotNull DfaValue value) {
super(value, null);
}
@Override
public @NotNull Instruction bindToFactory(@NotNull DfaValueFactory factory) {
return new JvmPushForWriteInstruction(getValue().bindToFactory(factory));
}
@Override
public String toString() {
return "PUSH_FOR_WRITE " + getValue();
}
}
@@ -2,23 +2,19 @@
package com.intellij.codeInspection.dataFlow.java.inst;
import com.intellij.codeInspection.dataFlow.java.JavaDfaHelpers;
import com.intellij.codeInspection.dataFlow.lang.DfaAnchor;
import com.intellij.codeInspection.dataFlow.lang.ir.Instruction;
import com.intellij.codeInspection.dataFlow.lang.ir.PushInstruction;
import com.intellij.codeInspection.dataFlow.memory.DfaMemoryState;
import com.intellij.codeInspection.dataFlow.value.DfaValue;
import com.intellij.codeInspection.dataFlow.value.DfaValueFactory;
import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
import org.jetbrains.annotations.NotNull;
/**
* An instruction that pushes given value to the stack for JVM analysis
* (it additionally processes escaping)
* @deprecated use simply {@link PushInstruction}. If escaping processing is necessary (which is unlikely),
* emit explicit {@link EscapeInstruction}.
*/
@Deprecated(forRemoval = true)
public class JvmPushInstruction extends PushInstruction {
private final boolean myReferenceWrite;
public JvmPushInstruction(@NotNull DfaValue value, DfaAnchor place) {
this(value, place, false);
}
@@ -26,27 +22,10 @@ public class JvmPushInstruction extends PushInstruction {
public JvmPushInstruction(@NotNull DfaValue value, DfaAnchor place, final boolean isReferenceWrite) {
super(value, place);
assert place == null || !isReferenceWrite;
myReferenceWrite = isReferenceWrite;
}
@Override
public @NotNull Instruction bindToFactory(@NotNull DfaValueFactory factory) {
return new JvmPushInstruction(getValue().bindToFactory(factory), getDfaAnchor(), myReferenceWrite);
}
public boolean isReferenceWrite() {
return myReferenceWrite;
}
@Override
public @NotNull DfaValue eval(@NotNull DfaValueFactory factory, @NotNull DfaMemoryState state, @NotNull DfaValue @NotNull ... arguments) {
DfaValue value = getValue();
if (value instanceof DfaVariableValue && JavaDfaHelpers.mayLeakFromType(value.getDfType())) {
DfaVariableValue qualifier = ((DfaVariableValue)value).getQualifier();
if (qualifier != null) {
JavaDfaHelpers.dropLocality(qualifier, state);
}
}
return value;
return new JvmPushInstruction(getValue().bindToFactory(factory), getDfaAnchor());
}
}
@@ -337,7 +337,7 @@ class KtControlFlowBuilder(val factory: DfaValueFactory, val context: KtExpressi
val offset = DeferredOffset()
addInstruction(ConditionalGotoInstruction(offset, DfTypes.FALSE))
val anchor = KotlinExpressionAnchor(expr)
addInstruction(JvmPushInstruction(tempVariable, anchor))
addInstruction(PushInstruction(tempVariable, anchor))
val endOffset = DeferredOffset()
addInstruction(GotoInstruction(endOffset))
setOffset(offset)
@@ -921,7 +921,7 @@ class KtControlFlowBuilder(val factory: DfaValueFactory, val context: KtExpressi
if (dfVar != null) {
val balancedType = balanceType(exprType, dfVarType, true)
addImplicitConversion(exprType, balancedType)
addInstruction(JvmPushInstruction(dfVar, null))
addInstruction(PushInstruction(dfVar, null))
addImplicitConversion(dfVarType, balancedType)
addInstruction(BooleanBinaryInstruction(RelationType.EQ, true, KotlinWhenConditionAnchor(condition)))
} else {
@@ -934,7 +934,7 @@ class KtControlFlowBuilder(val factory: DfaValueFactory, val context: KtExpressi
if (dfVar == null || type == DfType.TOP) {
pushUnknown()
} else {
addInstruction(JvmPushInstruction(dfVar, null))
addInstruction(PushInstruction(dfVar, null))
addInstruction(PushValueInstruction(type))
if (condition.isNegated) {
addInstruction(InstanceofInstruction(null, false))
@@ -947,7 +947,7 @@ class KtControlFlowBuilder(val factory: DfaValueFactory, val context: KtExpressi
is KtWhenConditionInRange -> {
if (dfVar != null) {
addInstruction(JvmPushInstruction(dfVar, null))
addInstruction(PushInstruction(dfVar, null))
} else {
pushUnknown()
}
@@ -1196,7 +1196,7 @@ class KtControlFlowBuilder(val factory: DfaValueFactory, val context: KtExpressi
addInstruction(JvmAssignmentInstruction(null, collectionVar))
addInstruction(PopInstruction())
return {
addInstruction(JvmPushInstruction(lengthField.createValue(factory, collectionVar), null))
addInstruction(PushInstruction(lengthField.createValue(factory, collectionVar), null))
addInstruction(PushValueInstruction(DfTypes.intValue(0)))
addInstruction(BooleanBinaryInstruction(RelationType.GT, false, null))
pushUnknown()
@@ -1223,13 +1223,13 @@ class KtControlFlowBuilder(val factory: DfaValueFactory, val context: KtExpressi
rightRelation: RelationType
): () -> Unit = {
val forAnchor = KotlinForVisitedAnchor(expr)
addInstruction(JvmPushInstruction(parameterVar, null))
addInstruction(JvmPushInstruction(leftVar, null))
addInstruction(PushInstruction(parameterVar, null))
addInstruction(PushInstruction(leftVar, null))
addInstruction(BooleanBinaryInstruction(leftRelation, false, null))
val offset = DeferredOffset()
addInstruction(ConditionalGotoInstruction(offset, DfTypes.FALSE))
addInstruction(JvmPushInstruction(parameterVar, null))
addInstruction(JvmPushInstruction(rightVar, null))
addInstruction(PushInstruction(parameterVar, null))
addInstruction(PushInstruction(rightVar, null))
addInstruction(BooleanBinaryInstruction(rightRelation, false, forAnchor))
val finalOffset = DeferredOffset()
addInstruction(GotoInstruction(finalOffset))
@@ -1242,7 +1242,7 @@ class KtControlFlowBuilder(val factory: DfaValueFactory, val context: KtExpressi
private inline fun inlinedBlock(element: KtElement, fn: () -> Unit) {
// Transfer value is pushed to avoid emptying stack beyond this point
trapTracker.pushTrap(InsideInlinedBlockTrap(element))
addInstruction(JvmPushInstruction(factory.controlTransfer(DfaControlTransferValue.RETURN_TRANSFER, FList.emptyList()), null))
addInstruction(PushInstruction(factory.controlTransfer(DfaControlTransferValue.RETURN_TRANSFER, FList.emptyList()), null))
fn()
@@ -1308,7 +1308,7 @@ class KtControlFlowBuilder(val factory: DfaValueFactory, val context: KtExpressi
if (qualifierOnStack) {
addInstruction(PopInstruction())
}
addInstruction(JvmPushInstruction(dfVar, KotlinExpressionAnchor(expr)))
addInstruction(PushInstruction(dfVar, KotlinExpressionAnchor(expr)))
var realExpr: KtExpression = expr
while (true) {
val parent = realExpr.parent
@@ -1525,7 +1525,7 @@ class KtControlFlowBuilder(val factory: DfaValueFactory, val context: KtExpressi
addInstruction(JvmAssignmentInstruction(null, result))
addInstruction(PopInstruction())
}
addInstruction(JvmPushInstruction(result, null))
addInstruction(PushInstruction(result, null))
addImplicitConversion(lambdaResultType, expr.getKotlinType())
}
@@ -1547,7 +1547,7 @@ class KtControlFlowBuilder(val factory: DfaValueFactory, val context: KtExpressi
addInstruction(JvmAssignmentInstruction(null, result))
addInstruction(PopInstruction())
}
addInstruction(JvmPushInstruction(result, null))
addInstruction(PushInstruction(result, null))
val offset = DeferredOffset()
addInstruction(ConditionalGotoInstruction(offset, DfTypes.booleanValue(name == TAKE_IF)))
addInstruction(PopInstruction())
@@ -1777,7 +1777,7 @@ class KtControlFlowBuilder(val factory: DfaValueFactory, val context: KtExpressi
val exprType = expr.getKotlinType()
val (varDesc, declType) = KtThisDescriptor.descriptorFromThis(expr)
if (varDesc != null) {
addInstruction(JvmPushInstruction(factory.varFactory.createVariableValue(varDesc), KotlinExpressionAnchor(expr)))
addInstruction(PushInstruction(factory.varFactory.createVariableValue(varDesc), KotlinExpressionAnchor(expr)))
addImplicitConversion(declType, exprType)
}
else {
@@ -274,7 +274,7 @@ class KtControlFlowBuilder(val factory: DfaValueFactory, val context: KtExpressi
} else {
KtThisDescriptor(descriptor, dfType)
}
addInstruction(JvmPushInstruction(factory.varFactory.createVariableValue(varDesc), KotlinExpressionAnchor(expr)))
addInstruction(PushInstruction(factory.varFactory.createVariableValue(varDesc), KotlinExpressionAnchor(expr)))
addImplicitConversion(thisType, exprType)
} else {
addInstruction(PushValueInstruction(dfType, KotlinExpressionAnchor(expr)))
@@ -337,7 +337,7 @@ class KtControlFlowBuilder(val factory: DfaValueFactory, val context: KtExpressi
val offset = DeferredOffset()
addInstruction(ConditionalGotoInstruction(offset, DfTypes.FALSE))
val anchor = KotlinExpressionAnchor(expr)
addInstruction(JvmPushInstruction(tempVariable, anchor))
addInstruction(PushInstruction(tempVariable, anchor))
val endOffset = DeferredOffset()
addInstruction(GotoInstruction(endOffset))
setOffset(offset)
@@ -693,7 +693,7 @@ class KtControlFlowBuilder(val factory: DfaValueFactory, val context: KtExpressi
addInstruction(JvmAssignmentInstruction(null, result))
addInstruction(PopInstruction())
}
addInstruction(JvmPushInstruction(result, null))
addInstruction(PushInstruction(result, null))
addImplicitConversion(lambdaResultType, expr.getKotlinType())
}
"also", "apply" -> {
@@ -713,7 +713,7 @@ class KtControlFlowBuilder(val factory: DfaValueFactory, val context: KtExpressi
addInstruction(JvmAssignmentInstruction(null, result))
addInstruction(PopInstruction())
}
addInstruction(JvmPushInstruction(result, null))
addInstruction(PushInstruction(result, null))
val offset = DeferredOffset()
addInstruction(ConditionalGotoInstruction(offset, DfTypes.booleanValue(name == "takeIf")))
addInstruction(PopInstruction())
@@ -798,7 +798,7 @@ class KtControlFlowBuilder(val factory: DfaValueFactory, val context: KtExpressi
private inline fun inlinedBlock(element: KtElement, fn : () -> Unit) {
// Transfer value is pushed to avoid emptying stack beyond this point
trapTracker.pushTrap(InsideInlinedBlockTrap(element))
addInstruction(JvmPushInstruction(factory.controlTransfer(DfaControlTransferValue.RETURN_TRANSFER, FList.emptyList()), null))
addInstruction(PushInstruction(factory.controlTransfer(DfaControlTransferValue.RETURN_TRANSFER, FList.emptyList()), null))
fn()
@@ -1095,7 +1095,7 @@ class KtControlFlowBuilder(val factory: DfaValueFactory, val context: KtExpressi
addInstruction(JvmAssignmentInstruction(null, collectionVar))
addInstruction(PopInstruction())
return {
addInstruction(JvmPushInstruction(lengthField.createValue(factory, collectionVar), null))
addInstruction(PushInstruction(lengthField.createValue(factory, collectionVar), null))
addInstruction(PushValueInstruction(DfTypes.intValue(0)))
addInstruction(BooleanBinaryInstruction(RelationType.GT, false, null))
pushUnknown()
@@ -1119,13 +1119,13 @@ class KtControlFlowBuilder(val factory: DfaValueFactory, val context: KtExpressi
rightRelation: RelationType
): () -> Unit = {
val forAnchor = KotlinForVisitedAnchor(expr)
addInstruction(JvmPushInstruction(parameterVar, null))
addInstruction(JvmPushInstruction(leftVar, null))
addInstruction(PushInstruction(parameterVar, null))
addInstruction(PushInstruction(leftVar, null))
addInstruction(BooleanBinaryInstruction(leftRelation, false, null))
val offset = DeferredOffset()
addInstruction(ConditionalGotoInstruction(offset, DfTypes.FALSE))
addInstruction(JvmPushInstruction(parameterVar, null))
addInstruction(JvmPushInstruction(rightVar, null))
addInstruction(PushInstruction(parameterVar, null))
addInstruction(PushInstruction(rightVar, null))
addInstruction(BooleanBinaryInstruction(rightRelation, false, forAnchor))
val finalOffset = DeferredOffset()
addInstruction(GotoInstruction(finalOffset))
@@ -1263,7 +1263,7 @@ class KtControlFlowBuilder(val factory: DfaValueFactory, val context: KtExpressi
if (qualifierOnStack) {
addInstruction(PopInstruction())
}
addInstruction(JvmPushInstruction(dfVar, KotlinExpressionAnchor(expr)))
addInstruction(PushInstruction(dfVar, KotlinExpressionAnchor(expr)))
var realExpr: KtExpression = expr
while (true) {
val parent = realExpr.parent
@@ -1696,7 +1696,7 @@ class KtControlFlowBuilder(val factory: DfaValueFactory, val context: KtExpressi
if (dfVar != null) {
val balancedType = balanceType(exprType, dfVarType, true)
addImplicitConversion(exprType, balancedType)
addInstruction(JvmPushInstruction(dfVar, null))
addInstruction(PushInstruction(dfVar, null))
addImplicitConversion(dfVarType, balancedType)
addInstruction(BooleanBinaryInstruction(RelationType.EQ, true, KotlinWhenConditionAnchor(condition)))
} else if (exprType?.canBeNull() == true) {
@@ -1710,7 +1710,7 @@ class KtControlFlowBuilder(val factory: DfaValueFactory, val context: KtExpressi
if (dfVar == null || type == DfType.TOP) {
pushUnknown()
} else {
addInstruction(JvmPushInstruction(dfVar, null))
addInstruction(PushInstruction(dfVar, null))
addInstruction(PushValueInstruction(type))
if (condition.isNegated) {
addInstruction(InstanceofInstruction(null, false))
@@ -1722,7 +1722,7 @@ class KtControlFlowBuilder(val factory: DfaValueFactory, val context: KtExpressi
}
is KtWhenConditionInRange -> {
if (dfVar != null) {
addInstruction(JvmPushInstruction(dfVar, null))
addInstruction(PushInstruction(dfVar, null))
} else {
pushUnknown()
}