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:
@@ -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>)
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
// "Create class 'X'" "true"
|
||||
|
||||
class Foo(x: <caret>X)
|
||||
+7
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user