diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassUtil.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassUtil.java index 04104a33439..7ef41f7d4c3 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassUtil.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassUtil.java @@ -133,27 +133,11 @@ public class LightClassUtil { PsiMethod getterWrapper = getter != null ? getLightClassAccessorMethod(getter) : null; PsiMethod setterWrapper = setter != null ? getLightClassAccessorMethod(setter) : null; - if (getterWrapper == null || setterWrapper == null) { - List wrappers = getPsiMethodWrappers(property, true); - assert wrappers.size() <= 2 : "Maximum two wrappers are expected to be generated for property"; + return extractPropertyAccessors(property, getterWrapper, setterWrapper); + } - for (PsiMethod wrapper : wrappers) { - if (wrapper.getName().startsWith(JvmAbi.SETTER_PREFIX)) { - assert setterWrapper == null : String.format( - "Setter accessor isn't expected to be reassigned (old: %s, new: %s)", setterWrapper, wrapper); - - setterWrapper = wrapper; - } - else { - assert getterWrapper == null : String.format( - "Getter accessor isn't expected to be reassigned (old: %s, new: %s)", getterWrapper, wrapper); - - getterWrapper = wrapper; - } - } - } - - return new PropertyAccessorsPsiMethods(getterWrapper, setterWrapper); + public static PropertyAccessorsPsiMethods getLightClassPropertyMethods(@NotNull JetParameter parameter) { + return extractPropertyAccessors(parameter, null, null); } @Nullable @@ -212,6 +196,10 @@ public class LightClassUtil { @Nullable private static PsiClass getWrappingClass(@NotNull JetDeclaration declaration) { + if (declaration instanceof JetParameter && declaration.getParent().getParent() instanceof JetClass) { + return getPsiClass((JetClassOrObject) declaration.getParent().getParent()); + } + if (declaration instanceof JetPropertyAccessor) { PsiElement propertyParent = declaration.getParent(); assert propertyParent instanceof JetProperty : "JetProperty is expected to be parent of accessor"; @@ -246,6 +234,38 @@ public class LightClassUtil { return null; } + private static PropertyAccessorsPsiMethods extractPropertyAccessors( + @NotNull JetDeclaration jetDeclaration, + @Nullable PsiMethod specialGetter, @Nullable PsiMethod specialSetter) + { + PsiMethod getterWrapper = specialGetter; + PsiMethod setterWrapper = specialSetter; + + if (getterWrapper == null || setterWrapper == null) { + // If some getter or setter isn't found yet try to get it from wrappers for general declaration + + List wrappers = getPsiMethodWrappers(jetDeclaration, true); + assert wrappers.size() <= 2 : "Maximum two wrappers are expected to be generated for declaration: " + jetDeclaration.getText(); + + for (PsiMethod wrapper : wrappers) { + if (wrapper.getName().startsWith(JvmAbi.SETTER_PREFIX)) { + assert setterWrapper == null : String.format( + "Setter accessor isn't expected to be reassigned (old: %s, new: %s)", setterWrapper, wrapper); + + setterWrapper = wrapper; + } + else { + assert getterWrapper == null : String.format( + "Getter accessor isn't expected to be reassigned (old: %s, new: %s)", getterWrapper, wrapper); + + getterWrapper = wrapper; + } + } + } + + return new PropertyAccessorsPsiMethods(getterWrapper, setterWrapper); + } + public static class PropertyAccessorsPsiMethods implements Iterable { private final PsiMethod getter; private final PsiMethod setter; diff --git a/idea/src/org/jetbrains/jet/plugin/search/KotlinDefinitionsSearcher.java b/idea/src/org/jetbrains/jet/plugin/search/KotlinDefinitionsSearcher.java index 950032e1fbe..89980b7611d 100644 --- a/idea/src/org/jetbrains/jet/plugin/search/KotlinDefinitionsSearcher.java +++ b/idea/src/org/jetbrains/jet/plugin/search/KotlinDefinitionsSearcher.java @@ -29,10 +29,7 @@ import com.intellij.util.Processor; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.asJava.LightClassUtil; -import org.jetbrains.jet.lang.psi.JetClass; -import org.jetbrains.jet.lang.psi.JetNamedFunction; -import org.jetbrains.jet.lang.psi.JetProperty; -import org.jetbrains.jet.lang.psi.JetPropertyAccessor; +import org.jetbrains.jet.lang.psi.*; public class KotlinDefinitionsSearcher extends QueryExecutorBase { @Override @@ -48,6 +45,13 @@ public class KotlinDefinitionsSearcher extends QueryExecutorBase consumer) { @@ -75,6 +79,18 @@ public class KotlinDefinitionsSearcher extends QueryExecutorBase consumer) { + LightClassUtil.PropertyAccessorsPsiMethods accessorsPsiMethods = ApplicationManager.getApplication().runReadAction( + new Computable() { + @Override + public LightClassUtil.PropertyAccessorsPsiMethods compute() { + return LightClassUtil.getLightClassPropertyMethods(parameter); + } + }); + + processPropertyImplementationsMethods(accessorsPsiMethods, consumer); + } + private static void processPropertyImplementations(@NotNull final JetProperty property, @NotNull Processor consumer) { LightClassUtil.PropertyAccessorsPsiMethods accessorsPsiMethods = ApplicationManager.getApplication().runReadAction( new Computable() { @@ -84,11 +100,15 @@ public class KotlinDefinitionsSearcher extends QueryExecutorBase consumer) { + for (PsiMethod method : accessors) { PsiMethod[] implementations = MethodImplementationsSearch.getMethodImplementations(method); for (PsiMethod implementation : implementations) { PsiElement mirrorElement = implementation instanceof PsiCompiledElement ? ((PsiCompiledElement) implementation).getMirror() : null; - if (mirrorElement instanceof JetProperty) { + if (mirrorElement instanceof JetProperty || mirrorElement instanceof JetParameter) { consumer.process(mirrorElement); } else if (mirrorElement instanceof JetPropertyAccessor && mirrorElement.getParent() instanceof JetProperty) { diff --git a/idea/testData/javaFacade/wrapConstructorField.kt b/idea/testData/javaFacade/wrapConstructorField.kt new file mode 100644 index 00000000000..37419fc3881 --- /dev/null +++ b/idea/testData/javaFacade/wrapConstructorField.kt @@ -0,0 +1 @@ +class Test(var field: Int) \ No newline at end of file diff --git a/idea/testData/javaFacade/wrapConstructorParameter.kt b/idea/testData/javaFacade/wrapConstructorParameter.kt new file mode 100644 index 00000000000..87fcd86a1f0 --- /dev/null +++ b/idea/testData/javaFacade/wrapConstructorParameter.kt @@ -0,0 +1 @@ +class Test(var field: Int, parameter: Int) \ No newline at end of file diff --git a/idea/testData/javaFacade/wrapFunctionParameter.kt b/idea/testData/javaFacade/wrapFunctionParameter.kt new file mode 100644 index 00000000000..68f96dab810 --- /dev/null +++ b/idea/testData/javaFacade/wrapFunctionParameter.kt @@ -0,0 +1 @@ +fun testFun(parameter: Int) = 0 \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java b/idea/tests/org/jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java index 8f444c4fa6e..a43fd97d429 100644 --- a/idea/tests/org/jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java @@ -122,6 +122,18 @@ public class JetJavaFacadeTest extends LightCodeInsightFixtureTestCase { doTestWrapPropertyAccessor(true); } + public void testWrapConstructorField() { + doTestWrapParameter(true, true); + } + + public void testWrapConstructorParameter() { + doTestWrapParameter(false, false); + } + + public void testWrapFunctionParameter() { + doTestWrapParameter(false, false); + } + public void testEa38770() { myFixture.configureByFile(getTestName(true) + ".kt"); @@ -197,6 +209,16 @@ public class JetJavaFacadeTest extends LightCodeInsightFixtureTestCase { checkDeclarationMethodWrapped(shouldBeWrapped, jetFunction, psiMethod); } + private void doTestWrapParameter(boolean shouldWrapGetter, boolean shouldWrapSetter) { + JetParameter jetParameter = getPreparedElement(JetParameter.class); + + // Should not fail! + LightClassUtil.PropertyAccessorsPsiMethods propertyAccessors = LightClassUtil.getLightClassPropertyMethods(jetParameter); + + checkDeclarationMethodWrapped(shouldWrapGetter, jetParameter, propertyAccessors.getGetter()); + checkDeclarationMethodWrapped(shouldWrapSetter, jetParameter, propertyAccessors.getSetter()); + } + private void doTestWrapProperty(boolean shouldWrapGetter, boolean shouldWrapSetter) { JetProperty jetProperty = getPreparedElement(JetProperty.class);