diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/types/InferenceCache.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/types/InferenceCache.java index c1561c0bba2a..92aaa435045d 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/types/InferenceCache.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/types/InferenceCache.java @@ -79,7 +79,9 @@ class InferenceCache { myTooComplexInstructions.addAll(interesting.first); } else { - cacheDfaResult(dfaResult); + Set stored = interesting.first; + stored.add(instruction); + cacheDfaResult(dfaResult, stored); } } DFAType dfaType = getCachedInferredType(descriptor, instruction); @@ -147,15 +149,21 @@ class InferenceCache { return pairs; } - private void cacheDfaResult(@NotNull List dfaResult) { - myVarTypes.accumulateAndGet(dfaResult, InferenceCache::addDfaResult); + private void cacheDfaResult(@NotNull List dfaResult, + Set storingInstructions) { + myVarTypes.accumulateAndGet(dfaResult, (oldState, newState) -> addDfaResult(oldState, newState, storingInstructions)); } @NotNull - private static List addDfaResult(@NotNull List oldTypes, @NotNull List dfaResult) { + private static List addDfaResult(@NotNull List oldTypes, + @NotNull List dfaResult, + @NotNull Set storingInstructions) { List newTypes = new ArrayList<>(oldTypes); + Set interestingInstructionNums = storingInstructions.stream().map(Instruction::num).collect(Collectors.toSet()); for (int i = 0; i < dfaResult.size(); i++) { - newTypes.set(i, newTypes.get(i).mergeWith(dfaResult.get(i))); + if (interestingInstructionNums.contains(i)) { + newTypes.set(i, newTypes.get(i).mergeWith(dfaResult.get(i))); + } } return newTypes; } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.groovy index 7fb7c245a884..c7b756fba9fe 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.groovy @@ -1164,4 +1164,21 @@ def test() { void 'test spread list of classes'() { doExprTest "[String, Integer]*.'class'", 'java.util.ArrayList>' } + + void 'test reassigned local CS'() { + doTest ''' +def aa = "1" +aa.toUpperCase() +if (false) { + aa = new Object() + aa +} +aa +''', JAVA_LANG_STRING + + myFixture.getDocument(file).getTextLength() + def ref = file.findReferenceAt(myFixture.getDocument(file).getTextLength() - 2) as GrReferenceExpression + def actual = ref.type + assertType(JAVA_LANG_OBJECT, actual) + } }