From aa65eb105513fceee65d21fd94c15b1398a185fd Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Wed, 1 Jul 2015 20:49:20 +0300 Subject: [PATCH] More proper fix for KT-8137/EA-69470: avoiding failed assertion when searching usages of parameter of local class constructor KT-8137 AE at JetSourceNavigationHelper.convertNamedClassOrObject() on function local class with several constructor parameters #KT-8137 fixed #EA-69470 fixed --- .../jetbrains/kotlin/psi/JetConstructor.kt | 5 +++ .../jetbrains/kotlin/psi/JetParameter.java | 2 +- .../org/jetbrains/kotlin/psi/JetPsiUtil.java | 4 +-- .../kotlinPrivatePropertyUsages2.0.kt | 5 +-- .../kotlinPrivatePropertyUsages2.1.kt | 2 +- .../kotlinPrivatePropertyUsages2.results.txt | 6 +++- .../libraryUsages/_library/library/library.kt | 5 +++ .../findUsages/AbstractJetFindUsagesTest.java | 12 +++---- .../KotlinFindUsagesWithLibraryCustomTest.kt | 32 +++++++++++++++++++ 9 files changed, 60 insertions(+), 13 deletions(-) create mode 100644 idea/tests/org/jetbrains/kotlin/findUsages/KotlinFindUsagesWithLibraryCustomTest.kt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetConstructor.kt b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetConstructor.kt index 2a10bdc2bce..32336cf1b65 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetConstructor.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetConstructor.kt @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.psi import com.intellij.lang.ASTNode import com.intellij.navigation.ItemPresentationProviders import com.intellij.psi.PsiElement +import com.intellij.psi.search.SearchScope import com.intellij.util.IncorrectOperationException import org.jetbrains.kotlin.lexer.JetTokens import org.jetbrains.kotlin.name.Name @@ -89,4 +90,8 @@ public abstract class JetConstructor> : JetDeclarationStub ?: getValueParameterList()?.getTextOffset() ?: super.getTextOffset() } + + override fun getUseScope(): SearchScope { + return getContainingClassOrObject().getUseScope() + } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetParameter.java b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetParameter.java index adf8d9a5390..c02ee94de2f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetParameter.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetParameter.java @@ -182,7 +182,7 @@ public class JetParameter extends JetNamedDeclarationStub i PsiElement parent = getParent(); if (parent != null) { PsiElement grandparent = parent.getParent(); - if (grandparent instanceof JetNamedFunction) { + if (grandparent instanceof JetFunction && !(grandparent instanceof JetFunctionLiteral)) { return grandparent.getUseScope(); } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetPsiUtil.java b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetPsiUtil.java index 54ddd225259..d84168d11b3 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetPsiUtil.java @@ -775,9 +775,9 @@ public class JetPsiUtil { else if (declaration instanceof JetParameter) { PsiElement parent = declaration.getParent(); - // val/var parameter of primary constructor should not be considered as local + // val/var parameter of primary constructor should be considered as local according to containing class if (((JetParameter) declaration).hasValOrVar() && parent != null && parent.getParent() instanceof JetPrimaryConstructor) { - return null; + return getEnclosingElementForLocalDeclaration(((JetPrimaryConstructor) parent.getParent()).getContainingClassOrObject(), skipParameters); } else if (skipParameters && parent != null && parent.getParent() instanceof JetNamedFunction) { diff --git a/idea/testData/findUsages/kotlin/findPropertyUsages/kotlinPrivatePropertyUsages2.0.kt b/idea/testData/findUsages/kotlin/findPropertyUsages/kotlinPrivatePropertyUsages2.0.kt index 0043dadf521..ad25821bdad 100644 --- a/idea/testData/findUsages/kotlin/findPropertyUsages/kotlinPrivatePropertyUsages2.0.kt +++ b/idea/testData/findUsages/kotlin/findPropertyUsages/kotlinPrivatePropertyUsages2.0.kt @@ -6,7 +6,8 @@ public open class Server(private val foo: String = "foo") { open fun processRequest() = foo } -public class ServerEx(): Server() { - override fun processRequest() = "foo" + foo +public class ServerEx(): Server(foo = "!") { + override fun processRequest() = "foo" + foo // this reference is found as a side effect of big use scope of constructor parameter: + // if it was simple property, it wouldn't be found } diff --git a/idea/testData/findUsages/kotlin/findPropertyUsages/kotlinPrivatePropertyUsages2.1.kt b/idea/testData/findUsages/kotlin/findPropertyUsages/kotlinPrivatePropertyUsages2.1.kt index fc85e72876a..86c7d186022 100644 --- a/idea/testData/findUsages/kotlin/findPropertyUsages/kotlinPrivatePropertyUsages2.1.kt +++ b/idea/testData/findUsages/kotlin/findPropertyUsages/kotlinPrivatePropertyUsages2.1.kt @@ -2,7 +2,7 @@ import server.*; class Client { public fun foo() { - println(Server().foo) + println(Server(foo = "!").foo) ServerEx().processRequest() } } diff --git a/idea/testData/findUsages/kotlin/findPropertyUsages/kotlinPrivatePropertyUsages2.results.txt b/idea/testData/findUsages/kotlin/findPropertyUsages/kotlinPrivatePropertyUsages2.results.txt index 9fddae8966e..2c7f2972fa0 100644 --- a/idea/testData/findUsages/kotlin/findPropertyUsages/kotlinPrivatePropertyUsages2.results.txt +++ b/idea/testData/findUsages/kotlin/findPropertyUsages/kotlinPrivatePropertyUsages2.results.txt @@ -1 +1,5 @@ -Value read (6: 33) open fun processRequest() = foo +[kotlinPrivatePropertyUsages2.0.kt] Named argument (9: 33) public class ServerEx(): Server(foo = "!") { +[kotlinPrivatePropertyUsages2.0.kt] Value read (10: 45) override fun processRequest() = "foo" + foo +[kotlinPrivatePropertyUsages2.0.kt] Value read (6: 33) open fun processRequest() = foo +[kotlinPrivatePropertyUsages2.1.kt] Named argument (5: 24) println(Server(foo = "!").foo) +[kotlinPrivatePropertyUsages2.1.kt] Value read (5: 35) println(Server(foo = "!").foo) \ No newline at end of file diff --git a/idea/testData/findUsages/libraryUsages/_library/library/library.kt b/idea/testData/findUsages/libraryUsages/_library/library/library.kt index 21ad72ec8bc..be51210073e 100644 --- a/idea/testData/findUsages/libraryUsages/_library/library/library.kt +++ b/idea/testData/findUsages/libraryUsages/_library/library/library.kt @@ -64,4 +64,9 @@ fun test() { val tt = A.T() t.bar(2) val fff = A.T::bar + + class LocalClass(val localClassProperty: Int) { + } + + LocalClass(localClassProperty = 1).localClassProperty } \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/findUsages/AbstractJetFindUsagesTest.java b/idea/tests/org/jetbrains/kotlin/findUsages/AbstractJetFindUsagesTest.java index fb48fb6a26b..622e0d95f9d 100644 --- a/idea/tests/org/jetbrains/kotlin/findUsages/AbstractJetFindUsagesTest.java +++ b/idea/tests/org/jetbrains/kotlin/findUsages/AbstractJetFindUsagesTest.java @@ -358,11 +358,11 @@ public abstract class AbstractJetFindUsagesTest extends JetLightCodeInsightFixtu } private void findUsagesAndCheckResults( - String mainFileText, - String prefix, - String rootPath, - T caretElement, - FindUsagesOptions options + @NotNull String mainFileText, + @NotNull String prefix, + @NotNull String rootPath, + @NotNull T caretElement, + @Nullable FindUsagesOptions options ) throws ClassNotFoundException, InstantiationException, IllegalAccessException { Collection usageInfos = findUsages(caretElement, options); @@ -419,7 +419,7 @@ public abstract class AbstractJetFindUsagesTest extends JetLightCodeInsightFixtu JetTestUtils.assertEqualsToFile(new File(rootPath, prefix + "results.txt"), StringUtil.join(finalUsages, "\n")); } - private Collection findUsages(@NotNull PsiElement targetElement, @Nullable FindUsagesOptions options) { + protected Collection findUsages(@NotNull PsiElement targetElement, @Nullable FindUsagesOptions options) { Project project = getProject(); FindUsagesHandler handler = ((FindManagerImpl) FindManager.getInstance(project)).getFindUsagesManager().getFindUsagesHandler(targetElement, false); diff --git a/idea/tests/org/jetbrains/kotlin/findUsages/KotlinFindUsagesWithLibraryCustomTest.kt b/idea/tests/org/jetbrains/kotlin/findUsages/KotlinFindUsagesWithLibraryCustomTest.kt new file mode 100644 index 00000000000..ad4646e403c --- /dev/null +++ b/idea/tests/org/jetbrains/kotlin/findUsages/KotlinFindUsagesWithLibraryCustomTest.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2010-2015 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.findUsages + +import com.intellij.psi.search.FilenameIndex +import org.jetbrains.kotlin.psi.JetParameter +import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType +import kotlin.test.assertEquals + +public class KotlinFindUsagesWithLibraryCustomTest : AbstractKotlinFindUsagesWithLibraryTest() { + public fun testFindUsagesForLocalClassProperty() { + val libraryFile = FilenameIndex.getFilesByName(getProject(), "library.kt", myFixture.getModule().getModuleWithLibrariesScope()).first() + val indexOf = libraryFile.getText().indexOf("localClassProperty") + val jetParameter = libraryFile.findElementAt(indexOf)!!.getStrictParentOfType()!! + val usages = findUsages(jetParameter.getOriginalElement(), null) + assertEquals(2, usages.size()) + } +} \ No newline at end of file