From 09cf7ac2aa8f465542587e9f1e23131f9cc9909e Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 22 May 2012 18:14:52 +0200 Subject: [PATCH] find usages and rename work for Kotlin classes called from Java code (KT-1641) #KT-1641 fixed --- .../jetbrains/jet/asJava/JetLightClass.java | 5 ++ idea/src/META-INF/plugin.xml | 1 + .../KotlinFindClassUsagesHandler.java | 38 +++++++++++++ .../KotlinFindUsagesHandlerFactory.java | 38 +++++++++++++ .../rename/RenameJetClassProcessor.java | 21 ++++++- .../run/JetJUnitConfigurationProducer.java | 8 +-- .../findUsages/findClassUsages/Client.java | 5 ++ .../findUsages/findClassUsages/Server.kt | 4 ++ .../after/testing/JavaClient.java | 7 +++ .../before/testing/JavaClient.java | 7 +++ .../jet/findUsages/JetFindUsagesTest.java | 56 +++++++++++++++++++ 11 files changed, 182 insertions(+), 8 deletions(-) create mode 100644 idea/src/org/jetbrains/jet/plugin/findUsages/KotlinFindClassUsagesHandler.java create mode 100644 idea/src/org/jetbrains/jet/plugin/findUsages/KotlinFindUsagesHandlerFactory.java create mode 100644 idea/testData/findUsages/findClassUsages/Client.java create mode 100644 idea/testData/findUsages/findClassUsages/Server.kt create mode 100644 idea/testData/refactoring/rename/renameKotlinClass/after/testing/JavaClient.java create mode 100644 idea/testData/refactoring/rename/renameKotlinClass/before/testing/JavaClient.java create mode 100644 idea/tests/org/jetbrains/jet/findUsages/JetFindUsagesTest.java diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightClass.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightClass.java index ba04aeacfba..fe17ef8dde5 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightClass.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightClass.java @@ -47,6 +47,7 @@ import org.jetbrains.jet.codegen.ClassBuilderFactory; import org.jetbrains.jet.codegen.ClassBuilderMode; import org.jetbrains.jet.codegen.CompilationErrorHandler; import org.jetbrains.jet.codegen.GenerationState; +import org.jetbrains.jet.lang.psi.JetClass; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetPsiUtil; import org.jetbrains.jet.lang.resolve.FqName; @@ -238,4 +239,8 @@ public class JetLightClass extends AbstractLightClass implements JetJavaMirrorMa return JetLightClass.class.getSimpleName() + ":" + e.toString(); } } + + public static JetLightClass wrapDelegate(JetClass jetClass) { + return new JetLightClass(jetClass.getManager(), (JetFile) jetClass.getContainingFile(), JetPsiUtil.getFQName(jetClass)); + } } diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 25197fa32c1..01f7da8ee16 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -157,6 +157,7 @@ + diff --git a/idea/src/org/jetbrains/jet/plugin/findUsages/KotlinFindClassUsagesHandler.java b/idea/src/org/jetbrains/jet/plugin/findUsages/KotlinFindClassUsagesHandler.java new file mode 100644 index 00000000000..beaa26bd28d --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/findUsages/KotlinFindClassUsagesHandler.java @@ -0,0 +1,38 @@ +/* + * Copyright 2010-2012 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.jet.plugin.findUsages; + +import com.intellij.find.findUsages.FindUsagesHandler; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.asJava.JetLightClass; +import org.jetbrains.jet.lang.psi.JetClass; + +/** + * @author yole + */ +public class KotlinFindClassUsagesHandler extends FindUsagesHandler { + public KotlinFindClassUsagesHandler(@NotNull PsiElement psiElement) { + super(psiElement); + } + + @NotNull + @Override + public PsiElement[] getSecondaryElements() { + return new PsiElement[] {JetLightClass.wrapDelegate((JetClass) getPsiElement()) }; + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/findUsages/KotlinFindUsagesHandlerFactory.java b/idea/src/org/jetbrains/jet/plugin/findUsages/KotlinFindUsagesHandlerFactory.java new file mode 100644 index 00000000000..c8ab9bf11cc --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/findUsages/KotlinFindUsagesHandlerFactory.java @@ -0,0 +1,38 @@ +/* + * Copyright 2010-2012 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.jet.plugin.findUsages; + +import com.intellij.find.findUsages.FindUsagesHandler; +import com.intellij.find.findUsages.FindUsagesHandlerFactory; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.psi.JetClass; + +/** + * @author yole + */ +public class KotlinFindUsagesHandlerFactory extends FindUsagesHandlerFactory { + @Override + public boolean canFindUsages(@NotNull PsiElement element) { + return element instanceof JetClass; + } + + @Override + public FindUsagesHandler createFindUsagesHandler(@NotNull PsiElement element, boolean forHighlightUsages) { + return new KotlinFindClassUsagesHandler(element); + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/rename/RenameJetClassProcessor.java b/idea/src/org/jetbrains/jet/plugin/refactoring/rename/RenameJetClassProcessor.java index 75fbbf2dc49..8f4355e77c3 100644 --- a/idea/src/org/jetbrains/jet/plugin/refactoring/rename/RenameJetClassProcessor.java +++ b/idea/src/org/jetbrains/jet/plugin/refactoring/rename/RenameJetClassProcessor.java @@ -16,15 +16,20 @@ package org.jetbrains.jet.plugin.refactoring.rename; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiReference; +import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.refactoring.rename.RenamePsiElementProcessor; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.asJava.JetLightClass; +import org.jetbrains.jet.lang.psi.JetClass; import org.jetbrains.jet.lang.psi.JetClassOrObject; import org.jetbrains.jet.lang.psi.JetFile; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; import java.util.Map; /** @@ -37,6 +42,18 @@ public class RenameJetClassProcessor extends RenamePsiElementProcessor { return element instanceof JetClassOrObject; } + @NotNull + @Override + public Collection findReferences(PsiElement element) { + if (element instanceof JetClass) { + List references = new ArrayList(); + references.addAll(ReferencesSearch.search(element).findAll()); + references.addAll(ReferencesSearch.search(JetLightClass.wrapDelegate((JetClass) element)).findAll()); + return references; + } + return super.findReferences(element); + } + @Override public void prepareRenaming(PsiElement element, String newName, Map allRenames) { JetClassOrObject clazz = (JetClassOrObject) element; diff --git a/idea/src/org/jetbrains/jet/plugin/run/JetJUnitConfigurationProducer.java b/idea/src/org/jetbrains/jet/plugin/run/JetJUnitConfigurationProducer.java index 0328ba617b9..c220a9b3e7f 100644 --- a/idea/src/org/jetbrains/jet/plugin/run/JetJUnitConfigurationProducer.java +++ b/idea/src/org/jetbrains/jet/plugin/run/JetJUnitConfigurationProducer.java @@ -67,7 +67,7 @@ public class JetJUnitConfigurationProducer extends RuntimeConfigurationProducer JetElement owner = PsiTreeUtil.getParentOfType(function, JetFunction.class, JetClass.class); if (owner instanceof JetClass) { - JetLightClass delegate = wrapDelegate((JetClass) owner); + JetLightClass delegate = JetLightClass.wrapDelegate((JetClass) owner); for (PsiMethod method : delegate.getMethods()) { if (method.getNavigationElement() == function) { Location methodLocation = PsiLocation.fromPsiElement(method); @@ -97,7 +97,7 @@ public class JetJUnitConfigurationProducer extends RuntimeConfigurationProducer if (jetClass != null) { myElement = jetClass; - PsiClass delegate = wrapDelegate(jetClass); + PsiClass delegate = JetLightClass.wrapDelegate(jetClass); if (JUnitUtil.isTestClass(delegate)) { RunnerAndConfigurationSettings settings = cloneTemplateConfiguration(context.getProject(), context); @@ -136,10 +136,6 @@ public class JetJUnitConfigurationProducer extends RuntimeConfigurationProducer return tempSingleDeclaration; } - private static JetLightClass wrapDelegate(JetClass jetClass) { - return new JetLightClass(jetClass.getManager(), (JetFile) jetClass.getContainingFile(), JetPsiUtil.getFQName(jetClass)); - } - @Override public int compareTo(Object o) { return 0; diff --git a/idea/testData/findUsages/findClassUsages/Client.java b/idea/testData/findUsages/findClassUsages/Client.java new file mode 100644 index 00000000000..30a18142b2a --- /dev/null +++ b/idea/testData/findUsages/findClassUsages/Client.java @@ -0,0 +1,5 @@ +import testing.*; + +class Client { + private Server myServer; +} diff --git a/idea/testData/findUsages/findClassUsages/Server.kt b/idea/testData/findUsages/findClassUsages/Server.kt new file mode 100644 index 00000000000..ce3c4c58477 --- /dev/null +++ b/idea/testData/findUsages/findClassUsages/Server.kt @@ -0,0 +1,4 @@ +package testing; + +class Server() { +} diff --git a/idea/testData/refactoring/rename/renameKotlinClass/after/testing/JavaClient.java b/idea/testData/refactoring/rename/renameKotlinClass/after/testing/JavaClient.java new file mode 100644 index 00000000000..7acaa8a80fc --- /dev/null +++ b/idea/testData/refactoring/rename/renameKotlinClass/after/testing/JavaClient.java @@ -0,0 +1,7 @@ +package testing; + +import testing.rename.Third; + +class JavaClient { + private Third myField; +} diff --git a/idea/testData/refactoring/rename/renameKotlinClass/before/testing/JavaClient.java b/idea/testData/refactoring/rename/renameKotlinClass/before/testing/JavaClient.java new file mode 100644 index 00000000000..6a74101d71c --- /dev/null +++ b/idea/testData/refactoring/rename/renameKotlinClass/before/testing/JavaClient.java @@ -0,0 +1,7 @@ +package testing; + +import testing.rename.First; + +class JavaClient { + private First myField; +} diff --git a/idea/tests/org/jetbrains/jet/findUsages/JetFindUsagesTest.java b/idea/tests/org/jetbrains/jet/findUsages/JetFindUsagesTest.java new file mode 100644 index 00000000000..bc1c00b9c08 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/findUsages/JetFindUsagesTest.java @@ -0,0 +1,56 @@ +/* + * Copyright 2010-2012 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.jet.findUsages; + +import com.intellij.psi.PsiField; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.testFramework.LightProjectDescriptor; +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; +import com.intellij.usageView.UsageInfo; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.psi.JetClass; +import org.jetbrains.jet.plugin.JetLightProjectDescriptor; +import org.jetbrains.jet.plugin.PluginTestCaseBase; + +import java.util.Collection; + +/** + * @author yole + */ +public class JetFindUsagesTest extends LightCodeInsightFixtureTestCase { + @NotNull + @Override + protected LightProjectDescriptor getProjectDescriptor() { + return JetLightProjectDescriptor.INSTANCE; + } + + @Override + public void setUp() throws Exception { + super.setUp(); + myFixture.setTestDataPath(PluginTestCaseBase.getTestDataPathBase() + "/findUsages"); + } + + public void testFindClassUsages() { + myFixture.configureByFiles("findClassUsages/Server.kt", "findClassUsages/Client.java"); + JetClass cls = PsiTreeUtil.getParentOfType(myFixture.getElementAtCaret(), JetClass.class, false); + final Collection usages = myFixture.findUsages(cls); + assertEquals(1, usages.size()); + UsageInfo first = usages.iterator().next(); + final PsiField field = PsiTreeUtil.getParentOfType(first.getElement(), PsiField.class); + assertEquals("private Server myServer;", field.getText()); + } +}