Navigate to lambda declaration from generated 'it' (KT-16992)
#KT-16992 Fixed #KT-13013 In Progress
This commit is contained in:
@@ -24,9 +24,9 @@ import org.jetbrains.kotlin.allopen.AbstractBytecodeListingTestForAllOpen
|
||||
import org.jetbrains.kotlin.android.*
|
||||
import org.jetbrains.kotlin.android.configure.AbstractConfigureProjectTest
|
||||
import org.jetbrains.kotlin.android.folding.AbstractAndroidResourceFoldingTest
|
||||
import org.jetbrains.kotlin.android.quickfix.AbstractAndroidLintQuickfixTest
|
||||
import org.jetbrains.kotlin.android.intention.AbstractAndroidResourceIntentionTest
|
||||
import org.jetbrains.kotlin.android.lint.AbstractKotlinLintTest
|
||||
import org.jetbrains.kotlin.android.quickfix.AbstractAndroidLintQuickfixTest
|
||||
import org.jetbrains.kotlin.android.quickfix.AbstractAndroidQuickFixMultiFileTest
|
||||
import org.jetbrains.kotlin.annotation.AbstractAnnotationProcessorBoxTest
|
||||
import org.jetbrains.kotlin.annotation.processing.test.sourceRetention.AbstractBytecodeListingTestForSourceRetention
|
||||
@@ -104,10 +104,7 @@ import org.jetbrains.kotlin.idea.kdoc.AbstractKDocHighlightingTest
|
||||
import org.jetbrains.kotlin.idea.kdoc.AbstractKDocTypingTest
|
||||
import org.jetbrains.kotlin.idea.maven.AbstractKotlinMavenInspectionTest
|
||||
import org.jetbrains.kotlin.idea.maven.configuration.AbstractMavenConfigureProjectByChangingFileTest
|
||||
import org.jetbrains.kotlin.idea.navigation.AbstractGotoSuperTest
|
||||
import org.jetbrains.kotlin.idea.navigation.AbstractGotoTypeDeclarationTest
|
||||
import org.jetbrains.kotlin.idea.navigation.AbstractKotlinGotoImplementationTest
|
||||
import org.jetbrains.kotlin.idea.navigation.AbstractKotlinGotoTest
|
||||
import org.jetbrains.kotlin.idea.navigation.*
|
||||
import org.jetbrains.kotlin.idea.parameterInfo.AbstractParameterInfoTest
|
||||
import org.jetbrains.kotlin.idea.quickfix.AbstractQuickFixMultiFileTest
|
||||
import org.jetbrains.kotlin.idea.quickfix.AbstractQuickFixTest
|
||||
@@ -506,6 +503,10 @@ fun main(args: Array<String>) {
|
||||
model("navigation/gotoTypeDeclaration", extension = "test")
|
||||
}
|
||||
|
||||
testClass<AbstractGotoDeclarationTest> {
|
||||
model("navigation/gotoDeclaration", extension = "test")
|
||||
}
|
||||
|
||||
testClass<AbstractParameterInfoTest> {
|
||||
model("parameterInfo", recursive = true, excludeDirs = listOf("withLib1/sharedLib", "withLib2/sharedLib", "withLib3/sharedLib"))
|
||||
}
|
||||
|
||||
+29
-2
@@ -22,16 +22,39 @@ import com.intellij.codeInsight.TargetElementUtil
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiReference
|
||||
import com.intellij.util.BitUtil
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource
|
||||
import org.jetbrains.kotlin.idea.intentions.isAutoCreatedItUsage
|
||||
import org.jetbrains.kotlin.idea.references.KtDestructuringDeclarationReference
|
||||
import org.jetbrains.kotlin.idea.references.resolveMainReferenceToDescriptors
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypeAndBranch
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isAbstract
|
||||
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||
|
||||
class KotlinTargetElementEvaluator : TargetElementEvaluatorEx {
|
||||
companion object {
|
||||
// Place caret after the open curly brace in lambda for generated 'it'
|
||||
fun findLambdaOpenLBraceForGeneratedIt(ref: PsiReference): PsiElement? {
|
||||
val element: PsiElement = ref.element
|
||||
if (element.text != "it") return null
|
||||
|
||||
if (element !is KtNameReferenceExpression || !isAutoCreatedItUsage(element)) return null
|
||||
|
||||
val itDescriptor = element.resolveMainReferenceToDescriptors().singleOrNull() ?: return null
|
||||
val descriptorWithSource = itDescriptor.containingDeclaration as? DeclarationDescriptorWithSource ?: return null
|
||||
val lambdaExpression = descriptorWithSource.source.getPsi()?.parent as? KtLambdaExpression ?: return null
|
||||
return lambdaExpression.leftCurlyBrace.treeNext?.psi
|
||||
}
|
||||
}
|
||||
|
||||
override fun includeSelfInGotoImplementation(element: PsiElement): Boolean = !(element is KtClass && element.isAbstract())
|
||||
|
||||
override fun getElementByReference(ref: PsiReference, flags: Int): PsiElement? {
|
||||
// prefer destructing declaration entry to its target if element name is accepted
|
||||
if (ref is KtDestructuringDeclarationReference && flags.and(TargetElementUtil.ELEMENT_NAME_ACCEPTED) != 0) {
|
||||
if (ref is KtDestructuringDeclarationReference && BitUtil.isSet(flags, TargetElementUtil.ELEMENT_NAME_ACCEPTED)) {
|
||||
return ref.element
|
||||
}
|
||||
|
||||
@@ -43,6 +66,10 @@ class KotlinTargetElementEvaluator : TargetElementEvaluatorEx {
|
||||
}
|
||||
}
|
||||
|
||||
if (BitUtil.isSet(flags, TargetElementUtil.REFERENCED_ELEMENT_ACCEPTED)) {
|
||||
return findLambdaOpenLBraceForGeneratedIt(ref)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
// FILE: before.kt
|
||||
interface Foo
|
||||
interface Bar
|
||||
|
||||
fun foo(a: Foo.(Bar) -> Unit) {}
|
||||
|
||||
fun bar() {
|
||||
foo {
|
||||
<caret>it
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: after.kt
|
||||
interface Foo
|
||||
interface Bar
|
||||
|
||||
fun foo(a: Foo.(Bar) -> Unit) {}
|
||||
|
||||
fun bar() {
|
||||
foo {<caret>
|
||||
it
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// FILE: before.kt
|
||||
interface Foo
|
||||
interface Bar
|
||||
|
||||
fun foo(b: Int, a: Foo.(Bar) -> Unit) {}
|
||||
|
||||
fun bar() {
|
||||
foo(12, {
|
||||
<caret>it
|
||||
})
|
||||
}
|
||||
|
||||
// FILE: after.kt
|
||||
interface Foo
|
||||
interface Bar
|
||||
|
||||
fun foo(b: Int, a: Foo.(Bar) -> Unit) {}
|
||||
|
||||
fun bar() {
|
||||
foo(12, {<caret>
|
||||
it
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// FILE: before.kt
|
||||
fun test(a: (Int) -> Unit = { <caret>it }) {}
|
||||
|
||||
// FILE: after.kt
|
||||
fun test(a: (Int) -> Unit = {<caret> it }) {}
|
||||
@@ -0,0 +1,5 @@
|
||||
// FILE: before.kt
|
||||
val a: (Int) -> Unit = { <caret>it }
|
||||
|
||||
// FILE: after.kt
|
||||
val a: (Int) -> Unit = {<caret> it }
|
||||
@@ -0,0 +1,23 @@
|
||||
// FILE: before.kt
|
||||
class Foo
|
||||
|
||||
fun <T> some(a: T, f: (T) -> Unit) {}
|
||||
fun foo(a: Any) {}
|
||||
|
||||
fun baz() {
|
||||
some(Foo()) {
|
||||
foo(it<caret>)
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: after.kt
|
||||
class Foo
|
||||
|
||||
fun <T> some(a: T, f: (T) -> Unit) {}
|
||||
fun foo(a: Any) {}
|
||||
|
||||
fun baz() {
|
||||
some(Foo()) {<caret>
|
||||
foo(it)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
abstract class AbstractGotoDeclarationTest : AbstractGotoActionTest() {
|
||||
override val actionName: String get() = "GotoDeclaration"
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.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/testData/navigation/gotoDeclaration")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class GotoDeclarationTestGenerated extends AbstractGotoDeclarationTest {
|
||||
public void testAllFilesPresentInGotoDeclaration() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/navigation/gotoDeclaration"), Pattern.compile("^(.+)\\.test$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("itExtensionLambda.test")
|
||||
public void testItExtensionLambda() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/navigation/gotoDeclaration/itExtensionLambda.test");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("itExtensionLambdaInBrackets.test")
|
||||
public void testItExtensionLambdaInBrackets() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/navigation/gotoDeclaration/itExtensionLambdaInBrackets.test");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("itInLambdaAsDefaultArgument.test")
|
||||
public void testItInLambdaAsDefaultArgument() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/navigation/gotoDeclaration/itInLambdaAsDefaultArgument.test");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("itInLambdaWithoutCall.test")
|
||||
public void testItInLambdaWithoutCall() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/navigation/gotoDeclaration/itInLambdaWithoutCall.test");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("itParameterInLambda.test")
|
||||
public void testItParameterInLambda() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/navigation/gotoDeclaration/itParameterInLambda.test");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user