Fix erroneous full resolve cache filling

Before this commit, we could store partial resolve results in full
resolve cache (for some declarations, e.g. primary constructors).
This may be done iff current partial resolve mode provides all results
from full resolve mode (CFA results & diagnostics).
Otherwise we should not do it.

This fixes four quick-fix tests on CreateTypeParameter
So #KT-23860 Fixed
So #KT-22758 Fixed
This commit is contained in:
Mikhail Glukhikh
2018-06-19 16:37:47 +03:00
parent 40668e3f96
commit 152327d69d
7 changed files with 44 additions and 8 deletions
@@ -177,17 +177,23 @@ class ResolveElementCache(
val (bindingContext, statementFilter) = performElementAdditionalResolve(resolveElement, contextElements, bodyResolveMode)
if (statementFilter == StatementFilter.NONE) {
// partial resolve is not supported for the given declaration - full resolve performed instead
if (statementFilter == StatementFilter.NONE &&
bodyResolveMode.doControlFlowAnalysis && !bodyResolveMode.bindingTraceFilter.ignoreDiagnostics
) {
// Without statement filter, we analyze everything, so we can count partial resolve result as full resolve
// But we can do this only if our resolve mode also provides *both* CFA and diagnostics
// This is true only for PARTIAL_WITH_DIAGNOSTICS resolve mode
fullResolveMap[resolveElement] = CachedFullResolve(bindingContext, resolveElement)
return bindingContext
}
val resolveToCache = CachedPartialResolve(bindingContext, file, bodyResolveMode)
for (statement in (statementFilter as PartialBodyResolveFilter).allStatementsToResolve) {
if (bindingContext[BindingContext.PROCESSED, statement] == true) {
partialResolveMap.putIfAbsent(statement, resolveToCache)
if (statementFilter is PartialBodyResolveFilter) {
for (statement in statementFilter.allStatementsToResolve) {
if (bindingContext[BindingContext.PROCESSED, statement] == true) {
partialResolveMap.putIfAbsent(statement, resolveToCache)
}
}
}
@@ -0,0 +1,4 @@
// "Import" "true"
// RUNTIME_WITH_FULL_JDK
class LL(val list: <caret>LinkedList<String>)
@@ -0,0 +1,6 @@
import java.util.LinkedList
// "Import" "true"
// RUNTIME_WITH_FULL_JDK
class LL(val list: LinkedList<String>)
@@ -0,0 +1,3 @@
// "Create class 'X'" "true"
class Foo(x: <caret>X)
@@ -0,0 +1,7 @@
// "Create class 'X'" "true"
class Foo(x: X)
class X {
}
@@ -302,9 +302,9 @@ class C(param1: String = "", param2: Int = 0) {
fun testFullResolvedCachedWhenPartialForConstructorInvoked() {
doTest {
val defaultValue1 = klass.getPrimaryConstructorParameters()[0].defaultValue!!
val defaultValue2 = klass.getPrimaryConstructorParameters()[1].defaultValue!!
val bindingContext1 = defaultValue1.analyze(BodyResolveMode.PARTIAL)
val defaultValue1 = klass.primaryConstructorParameters[0].defaultValue!!
val defaultValue2 = klass.primaryConstructorParameters[1].defaultValue!!
val bindingContext1 = defaultValue1.analyze(BodyResolveMode.PARTIAL_WITH_DIAGNOSTICS)
val bindingContext2 = defaultValue2.analyze(BodyResolveMode.FULL)
assert(bindingContext1 === bindingContext2)
}
@@ -1301,6 +1301,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
runTest("idea/testData/quickfix/autoImports/excludedFromImport.kt");
}
@TestMetadata("inPrimaryConstructor.kt")
public void testInPrimaryConstructor() throws Exception {
runTest("idea/testData/quickfix/autoImports/inPrimaryConstructor.kt");
}
@TestMetadata("infixCallAndObject.kt")
public void testInfixCallAndObject() throws Exception {
runTest("idea/testData/quickfix/autoImports/infixCallAndObject.kt");
@@ -2503,6 +2508,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
runTest("idea/testData/quickfix/createFromUsage/createClass/referenceExpression/classInPackage.kt");
}
@TestMetadata("classInPrimaryConstructor.kt")
public void testClassInPrimaryConstructor() throws Exception {
runTest("idea/testData/quickfix/createFromUsage/createClass/referenceExpression/classInPrimaryConstructor.kt");
}
@TestMetadata("classNoReceiver.kt")
public void testClassNoReceiver() throws Exception {
runTest("idea/testData/quickfix/createFromUsage/createClass/referenceExpression/classNoReceiver.kt");