diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml
index eb9bfce345c..76fa8c90428 100644
--- a/idea/src/META-INF/plugin.xml
+++ b/idea/src/META-INF/plugin.xml
@@ -858,6 +858,8 @@
+
+
org.jetbrains.kotlin.idea.intentions.FoldInitializerAndIfToElvisIntention
Kotlin
diff --git a/idea/src/org/jetbrains/kotlin/idea/goto/KotlinExpectOrActualGotoRelatedProvider.kt b/idea/src/org/jetbrains/kotlin/idea/goto/KotlinExpectOrActualGotoRelatedProvider.kt
new file mode 100644
index 00000000000..a1f100e10f4
--- /dev/null
+++ b/idea/src/org/jetbrains/kotlin/idea/goto/KotlinExpectOrActualGotoRelatedProvider.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2010-2017 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.kotlin.idea.goto
+
+import com.intellij.navigation.GotoRelatedItem
+import com.intellij.navigation.GotoRelatedProvider
+import com.intellij.psi.PsiElement
+import org.jetbrains.kotlin.idea.highlighter.markers.actualsForExpected
+import org.jetbrains.kotlin.idea.highlighter.markers.expectedDeclarationIfAny
+import org.jetbrains.kotlin.idea.highlighter.markers.isActualDeclaration
+import org.jetbrains.kotlin.idea.highlighter.markers.isExpectDeclaration
+import org.jetbrains.kotlin.idea.util.module
+import org.jetbrains.kotlin.psi.KtNamedDeclaration
+import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypeAndBranch
+
+class KotlinExpectOrActualGotoRelatedProvider : GotoRelatedProvider() {
+ private class ActualOrExpectGotoRelatedItem(element: PsiElement): GotoRelatedItem(element) {
+ override fun getCustomContainerName(): String? {
+ val module = element?.module ?: return null
+ return "(in module ${module.name})"
+ }
+ }
+
+ override fun getItems(psiElement: PsiElement): List {
+ val declaration = psiElement.getParentOfTypeAndBranch { nameIdentifier } ?: return emptyList()
+ val targets = when {
+ declaration.isExpectDeclaration() -> declaration.actualsForExpected()
+ declaration.isActualDeclaration() -> listOfNotNull(declaration.expectedDeclarationIfAny())
+ else -> emptyList()
+ }
+ return targets.map(::ActualOrExpectGotoRelatedItem)
+ }
+}
\ No newline at end of file
diff --git a/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/KotlinLineMarkerProvider.kt b/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/KotlinLineMarkerProvider.kt
index 4645b21afa6..afe7841b7a9 100644
--- a/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/KotlinLineMarkerProvider.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/highlighter/markers/KotlinLineMarkerProvider.kt
@@ -65,12 +65,6 @@ class KotlinLineMarkerProvider : LineMarkerProvider {
return null
}
- private fun KtNamedDeclaration.isExpectDeclaration(): Boolean =
- (toDescriptor() as? MemberDescriptor)?.isExpect == true
-
- private fun KtNamedDeclaration.isActualDeclaration(): Boolean =
- (toDescriptor() as? MemberDescriptor)?.isActual == true
-
override fun collectSlowLineMarkers(elements: List, result: MutableCollection>) {
if (elements.isEmpty()) return
@@ -120,6 +114,12 @@ class KotlinLineMarkerProvider : LineMarkerProvider {
}
}
+internal fun KtNamedDeclaration.isExpectDeclaration(): Boolean =
+ (toDescriptor() as? MemberDescriptor)?.isExpect == true
+
+internal fun KtNamedDeclaration.isActualDeclaration(): Boolean =
+ (toDescriptor() as? MemberDescriptor)?.isActual == true
+
private val OVERRIDING_MARK: Icon = AllIcons.Gutter.OverridingMethod
private val IMPLEMENTING_MARK: Icon = AllIcons.Gutter.ImplementingMethod
private val OVERRIDDEN_MARK: Icon = AllIcons.Gutter.OverridenMethod
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromActualMemberFunToExpect/common/common.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromActualMemberFunToExpect/common/common.kt
new file mode 100644
index 00000000000..4ccd35903f7
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromActualMemberFunToExpect/common/common.kt
@@ -0,0 +1,5 @@
+package test
+
+expect class Foo {
+ fun bar()
+}
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromActualMemberFunToExpect/js/js.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromActualMemberFunToExpect/js/js.kt
new file mode 100644
index 00000000000..6f446f1c37a
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromActualMemberFunToExpect/js/js.kt
@@ -0,0 +1,5 @@
+package test
+
+actual class Foo {
+ actual fun bar() {}
+}
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromActualMemberFunToExpect/jvm/jvm.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromActualMemberFunToExpect/jvm/jvm.kt
new file mode 100644
index 00000000000..88669806136
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromActualMemberFunToExpect/jvm/jvm.kt
@@ -0,0 +1,7 @@
+package test
+
+actual class Foo {
+ actual fun bar() {}
+}
+
+// REF: [common] (in test.Foo).bar()
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromActualMemberValToExpect/common/common.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromActualMemberValToExpect/common/common.kt
new file mode 100644
index 00000000000..4e9c9e62cd9
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromActualMemberValToExpect/common/common.kt
@@ -0,0 +1,5 @@
+package test
+
+expect class Foo {
+ val bar: Int
+}
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromActualMemberValToExpect/js/js.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromActualMemberValToExpect/js/js.kt
new file mode 100644
index 00000000000..32b00c6dc2b
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromActualMemberValToExpect/js/js.kt
@@ -0,0 +1,5 @@
+package test
+
+actual class Foo {
+ actual val bar: Int get() = 1
+}
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromActualMemberValToExpect/jvm/jvm.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromActualMemberValToExpect/jvm/jvm.kt
new file mode 100644
index 00000000000..6f18cb3a76c
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromActualMemberValToExpect/jvm/jvm.kt
@@ -0,0 +1,7 @@
+package test
+
+actual class Foo {
+ actual val bar: Int get() = 1
+}
+
+// REF: [common] (in test.Foo).bar
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromExpectMemberFunToActuals/common/common.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromExpectMemberFunToActuals/common/common.kt
new file mode 100644
index 00000000000..639addb9ed0
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromExpectMemberFunToActuals/common/common.kt
@@ -0,0 +1,8 @@
+package test
+
+expect class Foo {
+ fun bar()
+}
+
+// REF: [jvm] (in test.Foo).bar()
+// REF: [js] (in test.Foo).bar()
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromExpectMemberFunToActuals/js/js.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromExpectMemberFunToActuals/js/js.kt
new file mode 100644
index 00000000000..6f446f1c37a
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromExpectMemberFunToActuals/js/js.kt
@@ -0,0 +1,5 @@
+package test
+
+actual class Foo {
+ actual fun bar() {}
+}
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromExpectMemberFunToActuals/jvm/jvm.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromExpectMemberFunToActuals/jvm/jvm.kt
new file mode 100644
index 00000000000..6f446f1c37a
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromExpectMemberFunToActuals/jvm/jvm.kt
@@ -0,0 +1,5 @@
+package test
+
+actual class Foo {
+ actual fun bar() {}
+}
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromExpectMemberValToActuals/common/common.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromExpectMemberValToActuals/common/common.kt
new file mode 100644
index 00000000000..923d78d3080
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromExpectMemberValToActuals/common/common.kt
@@ -0,0 +1,8 @@
+package test
+
+expect class Foo {
+ val bar: Int
+}
+
+// REF: [jvm] (in test.Foo).bar
+// REF: [js] (in test.Foo).bar
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromExpectMemberValToActuals/js/js.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromExpectMemberValToActuals/js/js.kt
new file mode 100644
index 00000000000..32b00c6dc2b
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromExpectMemberValToActuals/js/js.kt
@@ -0,0 +1,5 @@
+package test
+
+actual class Foo {
+ actual val bar: Int get() = 1
+}
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromExpectMemberValToActuals/jvm/jvm.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromExpectMemberValToActuals/jvm/jvm.kt
new file mode 100644
index 00000000000..32b00c6dc2b
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromExpectMemberValToActuals/jvm/jvm.kt
@@ -0,0 +1,5 @@
+package test
+
+actual class Foo {
+ actual val bar: Int get() = 1
+}
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromNestedActualClassToExpect/common/common.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromNestedActualClassToExpect/common/common.kt
new file mode 100644
index 00000000000..2ea1eddb723
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromNestedActualClassToExpect/common/common.kt
@@ -0,0 +1,5 @@
+package test
+
+expect class Foo {
+ class Bar
+}
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromNestedActualClassToExpect/js/js.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromNestedActualClassToExpect/js/js.kt
new file mode 100644
index 00000000000..79d0f22c304
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromNestedActualClassToExpect/js/js.kt
@@ -0,0 +1,5 @@
+package test
+
+actual class Foo {
+ actual class Bar
+}
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromNestedActualClassToExpect/jvm/jvm.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromNestedActualClassToExpect/jvm/jvm.kt
new file mode 100644
index 00000000000..ece0eeb7153
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromNestedActualClassToExpect/jvm/jvm.kt
@@ -0,0 +1,7 @@
+package test
+
+actual class Foo {
+ actual class Bar
+}
+
+// REF: [common] (in test.Foo).Bar
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromNestedExpectClassToActuals/common/common.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromNestedExpectClassToActuals/common/common.kt
new file mode 100644
index 00000000000..b2ec1ef2ff8
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromNestedExpectClassToActuals/common/common.kt
@@ -0,0 +1,8 @@
+package test
+
+expect class Foo {
+ class Bar
+}
+
+// REF: [js] (in test.Foo).Bar
+// REF: [jvm] (in test.Foo).Bar
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromNestedExpectClassToActuals/js/js.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromNestedExpectClassToActuals/js/js.kt
new file mode 100644
index 00000000000..79d0f22c304
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromNestedExpectClassToActuals/js/js.kt
@@ -0,0 +1,5 @@
+package test
+
+actual class Foo {
+ actual class Bar
+}
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromNestedExpectClassToActuals/jvm/jvm.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromNestedExpectClassToActuals/jvm/jvm.kt
new file mode 100644
index 00000000000..79d0f22c304
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromNestedExpectClassToActuals/jvm/jvm.kt
@@ -0,0 +1,5 @@
+package test
+
+actual class Foo {
+ actual class Bar
+}
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelActualClassToExpect/common/common.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelActualClassToExpect/common/common.kt
new file mode 100644
index 00000000000..824ea6308bb
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelActualClassToExpect/common/common.kt
@@ -0,0 +1,3 @@
+package test
+
+expect class Foo
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelActualClassToExpect/js/js.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelActualClassToExpect/js/js.kt
new file mode 100644
index 00000000000..370bf00f56f
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelActualClassToExpect/js/js.kt
@@ -0,0 +1,3 @@
+package test
+
+actual class Foo
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelActualClassToExpect/jvm/jvm.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelActualClassToExpect/jvm/jvm.kt
new file mode 100644
index 00000000000..e19d004bac7
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelActualClassToExpect/jvm/jvm.kt
@@ -0,0 +1,5 @@
+package test
+
+actual class Foo
+
+// REF: [common] (test).Foo
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelActualFunToExpect/common/common.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelActualFunToExpect/common/common.kt
new file mode 100644
index 00000000000..547041af349
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelActualFunToExpect/common/common.kt
@@ -0,0 +1,3 @@
+package test
+
+expect fun foo()
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelActualFunToExpect/js/js.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelActualFunToExpect/js/js.kt
new file mode 100644
index 00000000000..374f6bda4b3
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelActualFunToExpect/js/js.kt
@@ -0,0 +1,3 @@
+package test
+
+actual fun foo() {}
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelActualFunToExpect/jvm/jvm.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelActualFunToExpect/jvm/jvm.kt
new file mode 100644
index 00000000000..f9a88dede20
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelActualFunToExpect/jvm/jvm.kt
@@ -0,0 +1,5 @@
+package test
+
+actual fun foo() {}
+
+// REF: [common] (test).foo()
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelActualValToExpect/common/common.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelActualValToExpect/common/common.kt
new file mode 100644
index 00000000000..07421dbece0
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelActualValToExpect/common/common.kt
@@ -0,0 +1,3 @@
+package test
+
+expect val foo: Int
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelActualValToExpect/js/js.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelActualValToExpect/js/js.kt
new file mode 100644
index 00000000000..b85d292d39c
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelActualValToExpect/js/js.kt
@@ -0,0 +1,3 @@
+package test
+
+actual val foo: Int get() = 1
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelActualValToExpect/jvm/jvm.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelActualValToExpect/jvm/jvm.kt
new file mode 100644
index 00000000000..bfdd681e2f9
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelActualValToExpect/jvm/jvm.kt
@@ -0,0 +1,5 @@
+package test
+
+actual val foo: Int get() = 1
+
+// REF: [common] (test).foo
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelExpectClassToActuals/common/common.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelExpectClassToActuals/common/common.kt
new file mode 100644
index 00000000000..f5af7f5b866
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelExpectClassToActuals/common/common.kt
@@ -0,0 +1,6 @@
+package test
+
+expect class Foo
+
+// REF: [jvm] (test).Foo
+// REF: [js] (test).Foo
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelExpectClassToActuals/js/js.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelExpectClassToActuals/js/js.kt
new file mode 100644
index 00000000000..370bf00f56f
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelExpectClassToActuals/js/js.kt
@@ -0,0 +1,3 @@
+package test
+
+actual class Foo
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelExpectClassToActuals/jvm/jvm.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelExpectClassToActuals/jvm/jvm.kt
new file mode 100644
index 00000000000..370bf00f56f
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelExpectClassToActuals/jvm/jvm.kt
@@ -0,0 +1,3 @@
+package test
+
+actual class Foo
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelExpectFunToActuals/common/common.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelExpectFunToActuals/common/common.kt
new file mode 100644
index 00000000000..610d0aa2166
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelExpectFunToActuals/common/common.kt
@@ -0,0 +1,6 @@
+package test
+
+expect fun foo()
+
+// REF: [jvm] (test).foo()
+// REF: [js] (test).foo()
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelExpectFunToActuals/js/js.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelExpectFunToActuals/js/js.kt
new file mode 100644
index 00000000000..374f6bda4b3
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelExpectFunToActuals/js/js.kt
@@ -0,0 +1,3 @@
+package test
+
+actual fun foo() {}
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelExpectFunToActuals/jvm/jvm.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelExpectFunToActuals/jvm/jvm.kt
new file mode 100644
index 00000000000..374f6bda4b3
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelExpectFunToActuals/jvm/jvm.kt
@@ -0,0 +1,3 @@
+package test
+
+actual fun foo() {}
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelExpectValToActuals/common/common.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelExpectValToActuals/common/common.kt
new file mode 100644
index 00000000000..6ea8c3baa02
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelExpectValToActuals/common/common.kt
@@ -0,0 +1,6 @@
+package test
+
+expect val foo: Int
+
+// REF: [jvm] (test).foo
+// REF: [js] (test).foo
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelExpectValToActuals/js/js.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelExpectValToActuals/js/js.kt
new file mode 100644
index 00000000000..b85d292d39c
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelExpectValToActuals/js/js.kt
@@ -0,0 +1,3 @@
+package test
+
+actual val foo: Int get() = 1
\ No newline at end of file
diff --git a/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelExpectValToActuals/jvm/jvm.kt b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelExpectValToActuals/jvm/jvm.kt
new file mode 100644
index 00000000000..b85d292d39c
--- /dev/null
+++ b/idea/testData/navigation/relatedSymbols/multiModule/fromTopLevelExpectValToActuals/jvm/jvm.kt
@@ -0,0 +1,3 @@
+package test
+
+actual val foo: Int get() = 1
\ No newline at end of file
diff --git a/idea/tests/org/jetbrains/kotlin/idea/navigation/AbstractKotlinNavigationMultiModuleTest.kt b/idea/tests/org/jetbrains/kotlin/idea/navigation/AbstractKotlinNavigationMultiModuleTest.kt
new file mode 100644
index 00000000000..2ef11b46ee9
--- /dev/null
+++ b/idea/tests/org/jetbrains/kotlin/idea/navigation/AbstractKotlinNavigationMultiModuleTest.kt
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2010-2017 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.kotlin.idea.navigation
+
+import com.intellij.codeInsight.navigation.GotoTargetHandler
+import com.intellij.openapi.editor.Editor
+import com.intellij.openapi.editor.EditorFactory
+import com.intellij.psi.PsiDocumentManager
+import com.intellij.psi.PsiFile
+import org.jetbrains.kotlin.config.JvmTarget
+import org.jetbrains.kotlin.config.TargetPlatformKind
+import org.jetbrains.kotlin.idea.project.PluginJetFilesProvider
+import org.jetbrains.kotlin.idea.stubs.AbstractMultiModuleTest
+import org.jetbrains.kotlin.idea.stubs.createFacet
+import org.jetbrains.kotlin.idea.test.extractMarkerOffset
+
+abstract class AbstractKotlinNavigationMultiModuleTest : AbstractMultiModuleTest() {
+ protected abstract fun doNavigate(editor: Editor, file: PsiFile): GotoTargetHandler.GotoData
+
+ protected fun doMultiPlatformTest(
+ testFileName: String,
+ commonModuleName: String = "common",
+ vararg actuals: Pair> = arrayOf("jvm" to TargetPlatformKind.Jvm[JvmTarget.JVM_1_6])
+ ) {
+ val commonModule = module(commonModuleName)
+ commonModule.createFacet(TargetPlatformKind.Common, false)
+
+ actuals.forEach { (actualName, actualKind) ->
+ val implModule = module(actualName)
+ implModule.createFacet(actualKind, implementedModuleName = commonModuleName)
+ implModule.enableMultiPlatform()
+ implModule.addDependency(commonModule)
+ }
+
+ val file = PluginJetFilesProvider.allFilesInProject(myProject).single { it.name == testFileName }
+ val doc = PsiDocumentManager.getInstance(myProject).getDocument(file)!!
+ val offset = doc.extractMarkerOffset(project, "")
+ val editor = EditorFactory.getInstance().createEditor(doc, myProject)
+ editor.caretModel.moveToOffset(offset)
+ try {
+ val gotoData = doNavigate(editor, file)
+ NavigationTestUtils.assertGotoDataMatching(editor, gotoData, true)
+ }
+ finally {
+ EditorFactory.getInstance().releaseEditor(editor)
+ }
+ }
+
+ protected fun doMultiPlatformTestJvmJs(testFileName: String, commonModuleName: String = "common") {
+ doMultiPlatformTest(
+ testFileName,
+ commonModuleName,
+ *arrayOf("jvm" to TargetPlatformKind.Jvm[JvmTarget.JVM_1_6], "js" to TargetPlatformKind.JavaScript)
+ )
+ }
+}
\ No newline at end of file
diff --git a/idea/tests/org/jetbrains/kotlin/idea/navigation/KotlinGotoImplementationMultiModuleTest.kt b/idea/tests/org/jetbrains/kotlin/idea/navigation/KotlinGotoImplementationMultiModuleTest.kt
index 08f1db5304e..ca20c52b516 100644
--- a/idea/tests/org/jetbrains/kotlin/idea/navigation/KotlinGotoImplementationMultiModuleTest.kt
+++ b/idea/tests/org/jetbrains/kotlin/idea/navigation/KotlinGotoImplementationMultiModuleTest.kt
@@ -16,50 +16,19 @@
package org.jetbrains.kotlin.idea.navigation
-import com.intellij.openapi.editor.EditorFactory
-import com.intellij.psi.PsiDocumentManager
+import com.intellij.openapi.editor.Editor
+import com.intellij.psi.PsiFile
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.config.TargetPlatformKind
-import org.jetbrains.kotlin.idea.project.PluginJetFilesProvider
-import org.jetbrains.kotlin.idea.stubs.AbstractMultiModuleTest
-import org.jetbrains.kotlin.idea.stubs.createFacet
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
-import org.jetbrains.kotlin.idea.test.extractMarkerOffset
import java.io.File
-class KotlinGotoImplementationMultiModuleTest : AbstractMultiModuleTest() {
+class KotlinGotoImplementationMultiModuleTest : AbstractKotlinNavigationMultiModuleTest() {
override fun getTestDataPath(): String {
return File(PluginTestCaseBase.getTestDataPathBase(), "/navigation/implementations/multiModule").path + File.separator
}
- private fun doMultiPlatformTest(
- testFileName: String,
- commonModuleName: String = "common",
- vararg actuals: Pair> = arrayOf("jvm" to TargetPlatformKind.Jvm[JvmTarget.JVM_1_6])
- ) {
- val commonModule = module(commonModuleName)
- commonModule.createFacet(TargetPlatformKind.Common, false)
-
- actuals.forEach { (actualName, actualKind) ->
- val implModule = module(actualName)
- implModule.createFacet(actualKind, implementedModuleName = commonModuleName)
- implModule.enableMultiPlatform()
- implModule.addDependency(commonModule)
- }
-
- val file = PluginJetFilesProvider.allFilesInProject(myProject).single { it.name == testFileName }
- val doc = PsiDocumentManager.getInstance(myProject).getDocument(file)!!
- val offset = doc.extractMarkerOffset(project, "")
- val editor = EditorFactory.getInstance().createEditor(doc, myProject)
- editor.caretModel.moveToOffset(offset)
- try {
- val gotoData = NavigationTestUtils.invokeGotoImplementations(editor, file)
- NavigationTestUtils.assertGotoDataMatching(editor, gotoData, true)
- }
- finally {
- EditorFactory.getInstance().releaseEditor(editor)
- }
- }
+ override fun doNavigate(editor: Editor, file: PsiFile) = NavigationTestUtils.invokeGotoImplementations(editor, file)
fun testSuspendFunImpl() {
doMultiPlatformTest(
diff --git a/idea/tests/org/jetbrains/kotlin/idea/navigation/KotlinGotoRelatedSymbolMultiModuleTest.kt b/idea/tests/org/jetbrains/kotlin/idea/navigation/KotlinGotoRelatedSymbolMultiModuleTest.kt
new file mode 100644
index 00000000000..01ca6a6aee1
--- /dev/null
+++ b/idea/tests/org/jetbrains/kotlin/idea/navigation/KotlinGotoRelatedSymbolMultiModuleTest.kt
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2010-2017 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.kotlin.idea.navigation
+
+import com.intellij.codeInsight.navigation.GotoTargetHandler
+import com.intellij.codeInsight.navigation.NavigationUtil
+import com.intellij.openapi.editor.Editor
+import com.intellij.psi.PsiFile
+import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
+import java.io.File
+
+class KotlinGotoRelatedSymbolMultiModuleTest : AbstractKotlinNavigationMultiModuleTest() {
+ override fun getTestDataPath() =
+ File(PluginTestCaseBase.getTestDataPathBase(), "/navigation/relatedSymbols/multiModule").path + File.separator
+
+ override fun doNavigate(editor: Editor, file: PsiFile): GotoTargetHandler.GotoData {
+ val source = file.findElementAt(editor.caretModel.offset)!!
+ val relatedItems = NavigationUtil.collectRelatedItems(source, null)
+ return GotoTargetHandler.GotoData(source, relatedItems.map { it.element }.toTypedArray(), emptyList())
+ }
+
+ fun testFromTopLevelExpectClassToActuals() {
+ doMultiPlatformTestJvmJs("common.kt")
+ }
+
+ fun testFromTopLevelActualClassToExpect() {
+ doMultiPlatformTestJvmJs("jvm.kt")
+ }
+
+ fun testFromTopLevelExpectFunToActuals() {
+ doMultiPlatformTestJvmJs("common.kt")
+ }
+
+ fun testFromTopLevelActualFunToExpect() {
+ doMultiPlatformTestJvmJs("jvm.kt")
+ }
+
+ fun testFromTopLevelExpectValToActuals() {
+ doMultiPlatformTestJvmJs("common.kt")
+ }
+
+ fun testFromTopLevelActualValToExpect() {
+ doMultiPlatformTestJvmJs("jvm.kt")
+ }
+
+ fun testFromNestedExpectClassToActuals() {
+ doMultiPlatformTestJvmJs("common.kt")
+ }
+
+ fun testFromNestedActualClassToExpect() {
+ doMultiPlatformTestJvmJs("jvm.kt")
+ }
+
+ fun testFromExpectMemberFunToActuals() {
+ doMultiPlatformTestJvmJs("common.kt")
+ }
+
+ fun testFromActualMemberFunToExpect() {
+ doMultiPlatformTestJvmJs("jvm.kt")
+ }
+
+ fun testFromExpectMemberValToActuals() {
+ doMultiPlatformTestJvmJs("common.kt")
+ }
+
+ fun testFromActualMemberValToExpect() {
+ doMultiPlatformTestJvmJs("jvm.kt")
+ }
+}
\ No newline at end of file