diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/ResolveElementCache.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/ResolveElementCache.kt index aa57e787243..6f134a15053 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/ResolveElementCache.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/ResolveElementCache.kt @@ -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) + } } } diff --git a/idea/testData/quickfix/autoImports/inPrimaryConstructor.kt b/idea/testData/quickfix/autoImports/inPrimaryConstructor.kt new file mode 100644 index 00000000000..65c78f10175 --- /dev/null +++ b/idea/testData/quickfix/autoImports/inPrimaryConstructor.kt @@ -0,0 +1,4 @@ +// "Import" "true" +// RUNTIME_WITH_FULL_JDK + +class LL(val list: LinkedList) \ No newline at end of file diff --git a/idea/testData/quickfix/autoImports/inPrimaryConstructor.kt.after b/idea/testData/quickfix/autoImports/inPrimaryConstructor.kt.after new file mode 100644 index 00000000000..ec777017df4 --- /dev/null +++ b/idea/testData/quickfix/autoImports/inPrimaryConstructor.kt.after @@ -0,0 +1,6 @@ +import java.util.LinkedList + +// "Import" "true" +// RUNTIME_WITH_FULL_JDK + +class LL(val list: LinkedList) \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/createClass/referenceExpression/classInPrimaryConstructor.kt b/idea/testData/quickfix/createFromUsage/createClass/referenceExpression/classInPrimaryConstructor.kt new file mode 100644 index 00000000000..1b613834de4 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createClass/referenceExpression/classInPrimaryConstructor.kt @@ -0,0 +1,3 @@ +// "Create class 'X'" "true" + +class Foo(x: X) \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/createClass/referenceExpression/classInPrimaryConstructor.kt.after b/idea/testData/quickfix/createFromUsage/createClass/referenceExpression/classInPrimaryConstructor.kt.after new file mode 100644 index 00000000000..12ec77d94c2 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/createClass/referenceExpression/classInPrimaryConstructor.kt.after @@ -0,0 +1,7 @@ +// "Create class 'X'" "true" + +class Foo(x: X) + +class X { + +} diff --git a/idea/tests/org/jetbrains/kotlin/idea/ResolveElementCacheTest.kt b/idea/tests/org/jetbrains/kotlin/idea/ResolveElementCacheTest.kt index 198d073a132..60670569d08 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/ResolveElementCacheTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/ResolveElementCacheTest.kt @@ -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) } diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index 0900149947d..6afd848efa0 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -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");