From 8a9e4bfa89485d6af3a7dc29c7c2fd82095cbf22 Mon Sep 17 00:00:00 2001 From: greg Date: Wed, 8 Jul 2009 17:59:13 +0400 Subject: [PATCH] IDEA-23649 Concatenation Injector and += --- .../dataFlow/ValuableDataFlowRunner.java | 33 ++++++++++++++++------ .../injected/JavaConcatenationInjectorManager.java | 5 ++-- source/com/intellij/slicer/SliceUtil.java | 6 +++- 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/inspections/impl/com/intellij/codeInspection/dataFlow/ValuableDataFlowRunner.java b/inspections/impl/com/intellij/codeInspection/dataFlow/ValuableDataFlowRunner.java index f73f77b726..496220e3a2 100644 --- a/inspections/impl/com/intellij/codeInspection/dataFlow/ValuableDataFlowRunner.java +++ b/inspections/impl/com/intellij/codeInspection/dataFlow/ValuableDataFlowRunner.java @@ -5,13 +5,14 @@ package com.intellij.codeInspection.dataFlow; import com.intellij.codeInspection.dataFlow.instructions.AssignInstruction; +import com.intellij.codeInspection.dataFlow.instructions.Instruction; import com.intellij.codeInspection.dataFlow.instructions.PushInstruction; import com.intellij.codeInspection.dataFlow.value.DfaValue; import com.intellij.codeInspection.dataFlow.value.DfaValueFactory; import com.intellij.codeInspection.dataFlow.value.DfaVariableValue; import com.intellij.openapi.util.MultiValuesMap; -import com.intellij.psi.PsiExpression; -import com.intellij.psi.PsiVariable; +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NotNull; import java.util.Collection; @@ -78,15 +79,29 @@ public class ValuableDataFlowRunner extends DataFlowRunner { public AssignInstruction createAssignInstruction(final PsiExpression rExpression) { return new AssignInstruction(rExpression) { public DfaInstructionState[] apply(final DataFlowRunner runner, final DfaMemoryState memState) { - final DfaInstructionState[] states = super.apply(runner, memState); - final DfaValue value = memState.peek(); - if (value instanceof DfaVariableValue) { - final MyDfaVariableState state = (MyDfaVariableState)((MyDfaMemoryState)memState).getVariableState((DfaVariableValue)value); - if (state.myExpression == null) { - state.myExpression = getRExpression(); + final Instruction nextInstruction = runner.getInstruction(getIndex() + 1); + + final DfaValue dfaSource = memState.pop(); + final DfaValue dfaDest = memState.pop(); + + if (dfaDest instanceof DfaVariableValue) { + DfaVariableValue var = (DfaVariableValue)dfaDest; + final PsiExpression curValue = getRExpression(); + final PsiElement parent = curValue.getParent(); + final IElementType type = parent instanceof PsiAssignmentExpression ? ((PsiAssignmentExpression)parent).getOperationTokenType() : JavaTokenType.EQ; + final PsiExpression prevValue = ((MyDfaVariableState)((MyDfaMemoryState)memState).getVariableState(var)).myExpression; + memState.setVarValue(var, dfaSource); + final PsiExpression nextValue; + if (prevValue != null && type == JavaTokenType.PLUSEQ) { + nextValue = JavaPsiFacade.getElementFactory(myContext.getProject()).createExpressionFromText(prevValue.getText()+"+"+curValue.getText(), curValue); } + else { + nextValue = curValue; + } + ((MyDfaVariableState)((MyDfaMemoryState)memState).getVariableState(var)).myExpression = nextValue; } - return states; + memState.push(dfaDest); + return new DfaInstructionState[]{new DfaInstructionState(nextInstruction, memState)}; } }; } diff --git a/source/com/intellij/psi/impl/source/tree/injected/JavaConcatenationInjectorManager.java b/source/com/intellij/psi/impl/source/tree/injected/JavaConcatenationInjectorManager.java index f293c5d755..575762ab08 100644 --- a/source/com/intellij/psi/impl/source/tree/injected/JavaConcatenationInjectorManager.java +++ b/source/com/intellij/psi/impl/source/tree/injected/JavaConcatenationInjectorManager.java @@ -90,6 +90,7 @@ public class JavaConcatenationInjectorManager implements ProjectComponent, Modif PsiElement element = context; PsiElement parent = context.getParent(); while (parent instanceof PsiBinaryExpression && ((PsiBinaryExpression)parent).getOperationSign().getTokenType() == JavaTokenType.PLUS + || parent instanceof PsiAssignmentExpression && ((PsiAssignmentExpression)parent).getOperationSign().getTokenType() == JavaTokenType.PLUSEQ || parent instanceof PsiConditionalExpression && ((PsiConditionalExpression)parent).getCondition() != element || parent instanceof PsiTypeCastExpression || parent instanceof PsiParenthesizedExpression) { @@ -99,7 +100,7 @@ public class JavaConcatenationInjectorManager implements ProjectComponent, Modif PsiElement[] operands; PsiElement anchor; - if (element instanceof PsiBinaryExpression) { + if (element instanceof PsiBinaryExpression || element instanceof PsiAssignmentExpression) { List operandList = new ArrayList(); collectOperands(element, operandList); operands = operandList.toArray(new PsiElement[operandList.size()]); @@ -162,7 +163,7 @@ public class JavaConcatenationInjectorManager implements ProjectComponent, Modif private static void collectOperands(PsiElement expression, List operands) { if (expression instanceof PsiBinaryExpression) { - PsiBinaryExpression binaryExpression = (PsiBinaryExpression)expression; + final PsiBinaryExpression binaryExpression = (PsiBinaryExpression)expression; collectOperands(binaryExpression.getLOperand(), operands); collectOperands(binaryExpression.getROperand(), operands); } diff --git a/source/com/intellij/slicer/SliceUtil.java b/source/com/intellij/slicer/SliceUtil.java index 18dc2dc653..0db3aa6a7c 100644 --- a/source/com/intellij/slicer/SliceUtil.java +++ b/source/com/intellij/slicer/SliceUtil.java @@ -2,6 +2,7 @@ package com.intellij.slicer; import com.intellij.codeInspection.dataFlow.DfaUtil; import com.intellij.psi.*; +import com.intellij.psi.impl.source.DummyHolder; import com.intellij.psi.search.searches.MethodReferencesSearch; import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.util.PsiUtil; @@ -79,7 +80,10 @@ public class SliceUtil { private static boolean processFlownFromExpressions(final Collection expressions, final Processor processor, final SliceUsage parent) { for (PsiExpression exp : expressions) { - SliceUsage usage = new SliceUsage(new UsageInfo(exp), parent); + final PsiExpression realExpression; + realExpression = exp.getParent() instanceof DummyHolder? (PsiExpression) ((DummyHolder)exp.getParent()).getContext() : exp; + assert realExpression != null; + SliceUsage usage = new SliceUsage(new UsageInfo(realExpression), parent); if (!processor.process(usage)) return false; } -- 2.11.4.GIT