From c3d2334eed5a9e2d30c3bc664cde7c54886b77c2 Mon Sep 17 00:00:00 2001 From: "Pavel V. Talanov" Date: Wed, 28 Mar 2018 18:06:19 +0200 Subject: [PATCH] Fix expect declarations available in completion in platform modules --- .../kotlin/generators/tests/GenerateTests.kt | 4 ++ .../idea/completion/CompletionSession.kt | 9 +++- .../completion/LookupElementsCollector.kt | 8 ++- .../classInCommon/common/common.kt | 11 ++++ .../multiPlatform/classInCommon/js/js.kt | 3 ++ .../multiPlatform/classInCommon/jvm/jvm.kt | 3 ++ .../classInPlatform/common/common.kt | 4 ++ .../multiPlatform/classInPlatform/js/js.kt | 13 +++++ .../functionInCommon/common/common.kt | 11 ++++ .../multiPlatform/functionInCommon/js/js.kt | 3 ++ .../multiPlatform/functionInCommon/jvm/jvm.kt | 3 ++ .../functionInPlatform/common/common.kt | 3 ++ .../functionInPlatform/jvm/jvm.kt | 12 +++++ .../MultiPlatformCompletionTestGenerated.java | 51 +++++++++++++++++++ 14 files changed, 136 insertions(+), 2 deletions(-) create mode 100644 idea/idea-completion/testData/multiPlatform/classInCommon/common/common.kt create mode 100644 idea/idea-completion/testData/multiPlatform/classInCommon/js/js.kt create mode 100644 idea/idea-completion/testData/multiPlatform/classInCommon/jvm/jvm.kt create mode 100644 idea/idea-completion/testData/multiPlatform/classInPlatform/common/common.kt create mode 100644 idea/idea-completion/testData/multiPlatform/classInPlatform/js/js.kt create mode 100644 idea/idea-completion/testData/multiPlatform/functionInCommon/common/common.kt create mode 100644 idea/idea-completion/testData/multiPlatform/functionInCommon/js/js.kt create mode 100644 idea/idea-completion/testData/multiPlatform/functionInCommon/jvm/jvm.kt create mode 100644 idea/idea-completion/testData/multiPlatform/functionInPlatform/common/common.kt create mode 100644 idea/idea-completion/testData/multiPlatform/functionInPlatform/jvm/jvm.kt create mode 100644 idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/MultiPlatformCompletionTestGenerated.java diff --git a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt index 57631693526..df64ba49e0e 100755 --- a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt +++ b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt @@ -877,6 +877,10 @@ fun main(args: Array) { testClass { model("incrementalResolve") } + + testClass { + model("multiPlatform", recursive = false, extension = null) + } } //TODO: move these tests into idea-completion module diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionSession.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionSession.kt index 747f87cd47a..e1b90d47c3f 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionSession.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionSession.kt @@ -43,7 +43,9 @@ import org.jetbrains.kotlin.idea.references.mainReference import org.jetbrains.kotlin.idea.util.* import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.MultiTargetPlatform import org.jetbrains.kotlin.resolve.descriptorUtil.module +import org.jetbrains.kotlin.resolve.getMultiTargetPlatform import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver @@ -143,7 +145,12 @@ abstract class CompletionSession( // LookupElementsCollector instantiation is deferred because virtual call to createSorter uses data from derived classes protected val collector: LookupElementsCollector by lazy(LazyThreadSafetyMode.NONE) { - LookupElementsCollector({ CompletionBenchmarkSink.instance.onFlush(this) }, prefixMatcher, parameters, resultSet, createSorter(), (file as? KtCodeFragment)?.extraCompletionFilter) + LookupElementsCollector( + { CompletionBenchmarkSink.instance.onFlush(this) }, + prefixMatcher, parameters, resultSet, + createSorter(), (file as? KtCodeFragment)?.extraCompletionFilter, + moduleDescriptor.getMultiTargetPlatform() === MultiTargetPlatform.Common + ) } protected val searchScope: GlobalSearchScope = diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/LookupElementsCollector.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/LookupElementsCollector.kt index 9794ee01fa1..f1e6fdf4cd8 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/LookupElementsCollector.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/LookupElementsCollector.kt @@ -24,6 +24,7 @@ import com.intellij.openapi.util.TextRange import com.intellij.patterns.ElementPattern import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.MemberDescriptor import org.jetbrains.kotlin.idea.completion.handlers.WithExpressionPrefixInsertHandler import org.jetbrains.kotlin.idea.completion.handlers.WithTailInsertHandler import org.jetbrains.kotlin.idea.core.completion.DeclarationLookupObject @@ -35,7 +36,8 @@ class LookupElementsCollector( private val completionParameters: CompletionParameters, resultSet: CompletionResultSet, sorter: CompletionSorter, - private val filter: ((LookupElement) -> Boolean)? + private val filter: ((LookupElement) -> Boolean)?, + private val allowExpectDeclarations: Boolean ) { var bestMatchingDegree = Int.MIN_VALUE @@ -102,6 +104,10 @@ class LookupElementsCollector( fun addElement(element: LookupElement, notImported: Boolean = false) { if (!prefixMatcher.prefixMatches(element)) return + if (!allowExpectDeclarations) { + val descriptor = (element.`object` as? DeclarationLookupObject)?.descriptor + if ((descriptor as? MemberDescriptor)?.isExpect == true) return + } if (notImported) { element.putUserData(NOT_IMPORTED_KEY, Unit) diff --git a/idea/idea-completion/testData/multiPlatform/classInCommon/common/common.kt b/idea/idea-completion/testData/multiPlatform/classInCommon/common/common.kt new file mode 100644 index 00000000000..92ac345ffa9 --- /dev/null +++ b/idea/idea-completion/testData/multiPlatform/classInCommon/common/common.kt @@ -0,0 +1,11 @@ +package test + +expect class Foo + +fun use() { + Foo +} + +// ABSENT: { lookupString: Foo, module: testModule_JVM } +// ABSENT: { lookupString: Foo, module: testModule_JS } +// EXIST: { lookupString: Foo, module: testModule_Common } \ No newline at end of file diff --git a/idea/idea-completion/testData/multiPlatform/classInCommon/js/js.kt b/idea/idea-completion/testData/multiPlatform/classInCommon/js/js.kt new file mode 100644 index 00000000000..370bf00f56f --- /dev/null +++ b/idea/idea-completion/testData/multiPlatform/classInCommon/js/js.kt @@ -0,0 +1,3 @@ +package test + +actual class Foo \ No newline at end of file diff --git a/idea/idea-completion/testData/multiPlatform/classInCommon/jvm/jvm.kt b/idea/idea-completion/testData/multiPlatform/classInCommon/jvm/jvm.kt new file mode 100644 index 00000000000..370bf00f56f --- /dev/null +++ b/idea/idea-completion/testData/multiPlatform/classInCommon/jvm/jvm.kt @@ -0,0 +1,3 @@ +package test + +actual class Foo \ No newline at end of file diff --git a/idea/idea-completion/testData/multiPlatform/classInPlatform/common/common.kt b/idea/idea-completion/testData/multiPlatform/classInPlatform/common/common.kt new file mode 100644 index 00000000000..2e017158648 --- /dev/null +++ b/idea/idea-completion/testData/multiPlatform/classInPlatform/common/common.kt @@ -0,0 +1,4 @@ +package test + +expect class FooCl +expect object FooObj \ No newline at end of file diff --git a/idea/idea-completion/testData/multiPlatform/classInPlatform/js/js.kt b/idea/idea-completion/testData/multiPlatform/classInPlatform/js/js.kt new file mode 100644 index 00000000000..bd7efcf35d7 --- /dev/null +++ b/idea/idea-completion/testData/multiPlatform/classInPlatform/js/js.kt @@ -0,0 +1,13 @@ +package test + +actual class FooCl +actual object FooObj + +fun use() { + Fo +} + +// EXIST: { lookupString: FooCl, module: testModule_JS } +// EXIST: { lookupString: FooObj, module: testModule_JS } +// ABSENT: { lookupString: FooCl, module: testModule_Common } +// ABSENT: { lookupString: FooObj, module: testModule_Common } \ No newline at end of file diff --git a/idea/idea-completion/testData/multiPlatform/functionInCommon/common/common.kt b/idea/idea-completion/testData/multiPlatform/functionInCommon/common/common.kt new file mode 100644 index 00000000000..7c2c462e564 --- /dev/null +++ b/idea/idea-completion/testData/multiPlatform/functionInCommon/common/common.kt @@ -0,0 +1,11 @@ +package test + +expect fun foo() + +fun use() { + foo +} + +// ABSENT: { lookupString: foo, module: testModule_JVM } +// ABSENT: { lookupString: foo, module: testModule_JS } +// EXIST: { lookupString: foo, module: testModule_Common } \ No newline at end of file diff --git a/idea/idea-completion/testData/multiPlatform/functionInCommon/js/js.kt b/idea/idea-completion/testData/multiPlatform/functionInCommon/js/js.kt new file mode 100644 index 00000000000..374f6bda4b3 --- /dev/null +++ b/idea/idea-completion/testData/multiPlatform/functionInCommon/js/js.kt @@ -0,0 +1,3 @@ +package test + +actual fun foo() {} \ No newline at end of file diff --git a/idea/idea-completion/testData/multiPlatform/functionInCommon/jvm/jvm.kt b/idea/idea-completion/testData/multiPlatform/functionInCommon/jvm/jvm.kt new file mode 100644 index 00000000000..374f6bda4b3 --- /dev/null +++ b/idea/idea-completion/testData/multiPlatform/functionInCommon/jvm/jvm.kt @@ -0,0 +1,3 @@ +package test + +actual fun foo() {} \ No newline at end of file diff --git a/idea/idea-completion/testData/multiPlatform/functionInPlatform/common/common.kt b/idea/idea-completion/testData/multiPlatform/functionInPlatform/common/common.kt new file mode 100644 index 00000000000..547041af349 --- /dev/null +++ b/idea/idea-completion/testData/multiPlatform/functionInPlatform/common/common.kt @@ -0,0 +1,3 @@ +package test + +expect fun foo() \ No newline at end of file diff --git a/idea/idea-completion/testData/multiPlatform/functionInPlatform/jvm/jvm.kt b/idea/idea-completion/testData/multiPlatform/functionInPlatform/jvm/jvm.kt new file mode 100644 index 00000000000..471a21d2657 --- /dev/null +++ b/idea/idea-completion/testData/multiPlatform/functionInPlatform/jvm/jvm.kt @@ -0,0 +1,12 @@ +package test + +actual fun foo() { + +} + +fun use() { + foo +} + +// EXIST: { lookupString: foo, module: testModule_JVM } +// ABSENT: { lookupString: foo, module: testModule_Common } \ No newline at end of file diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/MultiPlatformCompletionTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/MultiPlatformCompletionTestGenerated.java new file mode 100644 index 00000000000..079e5e473e1 --- /dev/null +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/MultiPlatformCompletionTestGenerated.java @@ -0,0 +1,51 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.completion.test; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.test.JUnit3RunnerWithInners; +import org.jetbrains.kotlin.test.KotlinTestUtils; +import org.jetbrains.kotlin.test.TargetBackend; +import org.jetbrains.kotlin.test.TestMetadata; +import org.junit.runner.RunWith; + +import java.io.File; +import java.util.regex.Pattern; + +/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("idea/idea-completion/testData/multiPlatform") +@TestDataPath("$PROJECT_ROOT") +@RunWith(JUnit3RunnerWithInners.class) +public class MultiPlatformCompletionTestGenerated extends AbstractMultiPlatformCompletionTest { + public void testAllFilesPresentInMultiPlatform() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/multiPlatform"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, false); + } + + @TestMetadata("classInCommon") + public void testClassInCommon() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/multiPlatform/classInCommon/"); + doTest(fileName); + } + + @TestMetadata("classInPlatform") + public void testClassInPlatform() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/multiPlatform/classInPlatform/"); + doTest(fileName); + } + + @TestMetadata("functionInCommon") + public void testFunctionInCommon() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/multiPlatform/functionInCommon/"); + doTest(fileName); + } + + @TestMetadata("functionInPlatform") + public void testFunctionInPlatform() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/multiPlatform/functionInPlatform/"); + doTest(fileName); + } +}