Search implementations for properties from constructor parameters
This commit is contained in:
committed by
Nikolay Krasko
parent
5cc49f55f3
commit
0a2ca39f88
@@ -133,27 +133,11 @@ public class LightClassUtil {
|
|||||||
PsiMethod getterWrapper = getter != null ? getLightClassAccessorMethod(getter) : null;
|
PsiMethod getterWrapper = getter != null ? getLightClassAccessorMethod(getter) : null;
|
||||||
PsiMethod setterWrapper = setter != null ? getLightClassAccessorMethod(setter) : null;
|
PsiMethod setterWrapper = setter != null ? getLightClassAccessorMethod(setter) : null;
|
||||||
|
|
||||||
if (getterWrapper == null || setterWrapper == null) {
|
return extractPropertyAccessors(property, getterWrapper, setterWrapper);
|
||||||
List<PsiMethod> wrappers = getPsiMethodWrappers(property, true);
|
}
|
||||||
assert wrappers.size() <= 2 : "Maximum two wrappers are expected to be generated for property";
|
|
||||||
|
|
||||||
for (PsiMethod wrapper : wrappers) {
|
public static PropertyAccessorsPsiMethods getLightClassPropertyMethods(@NotNull JetParameter parameter) {
|
||||||
if (wrapper.getName().startsWith(JvmAbi.SETTER_PREFIX)) {
|
return extractPropertyAccessors(parameter, null, null);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -212,6 +196,10 @@ public class LightClassUtil {
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private static PsiClass getWrappingClass(@NotNull JetDeclaration declaration) {
|
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) {
|
if (declaration instanceof JetPropertyAccessor) {
|
||||||
PsiElement propertyParent = declaration.getParent();
|
PsiElement propertyParent = declaration.getParent();
|
||||||
assert propertyParent instanceof JetProperty : "JetProperty is expected to be parent of accessor";
|
assert propertyParent instanceof JetProperty : "JetProperty is expected to be parent of accessor";
|
||||||
@@ -246,6 +234,38 @@ public class LightClassUtil {
|
|||||||
return null;
|
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<PsiMethod> 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<PsiMethod> {
|
public static class PropertyAccessorsPsiMethods implements Iterable<PsiMethod> {
|
||||||
private final PsiMethod getter;
|
private final PsiMethod getter;
|
||||||
private final PsiMethod setter;
|
private final PsiMethod setter;
|
||||||
|
|||||||
@@ -29,10 +29,7 @@ import com.intellij.util.Processor;
|
|||||||
import com.intellij.util.containers.ContainerUtil;
|
import com.intellij.util.containers.ContainerUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.asJava.LightClassUtil;
|
import org.jetbrains.jet.asJava.LightClassUtil;
|
||||||
import org.jetbrains.jet.lang.psi.JetClass;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.psi.JetNamedFunction;
|
|
||||||
import org.jetbrains.jet.lang.psi.JetProperty;
|
|
||||||
import org.jetbrains.jet.lang.psi.JetPropertyAccessor;
|
|
||||||
|
|
||||||
public class KotlinDefinitionsSearcher extends QueryExecutorBase<PsiElement, PsiElement> {
|
public class KotlinDefinitionsSearcher extends QueryExecutorBase<PsiElement, PsiElement> {
|
||||||
@Override
|
@Override
|
||||||
@@ -48,6 +45,13 @@ public class KotlinDefinitionsSearcher extends QueryExecutorBase<PsiElement, Psi
|
|||||||
if (queryParameters instanceof JetProperty) {
|
if (queryParameters instanceof JetProperty) {
|
||||||
processPropertyImplementations((JetProperty) queryParameters, consumer);
|
processPropertyImplementations((JetProperty) queryParameters, consumer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (queryParameters instanceof JetParameter) {
|
||||||
|
JetParameter parameter = (JetParameter) queryParameters;
|
||||||
|
if (parameter.getValOrVarNode() != null && queryParameters.getParent().getParent() instanceof JetClass) {
|
||||||
|
processPropertyImplementations(parameter, consumer);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void processClassImplementations(final JetClass queryParameters, Processor<PsiElement> consumer) {
|
private static void processClassImplementations(final JetClass queryParameters, Processor<PsiElement> consumer) {
|
||||||
@@ -75,6 +79,18 @@ public class KotlinDefinitionsSearcher extends QueryExecutorBase<PsiElement, Psi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void processPropertyImplementations(@NotNull final JetParameter parameter, @NotNull Processor<PsiElement> consumer) {
|
||||||
|
LightClassUtil.PropertyAccessorsPsiMethods accessorsPsiMethods = ApplicationManager.getApplication().runReadAction(
|
||||||
|
new Computable<LightClassUtil.PropertyAccessorsPsiMethods>() {
|
||||||
|
@Override
|
||||||
|
public LightClassUtil.PropertyAccessorsPsiMethods compute() {
|
||||||
|
return LightClassUtil.getLightClassPropertyMethods(parameter);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
processPropertyImplementationsMethods(accessorsPsiMethods, consumer);
|
||||||
|
}
|
||||||
|
|
||||||
private static void processPropertyImplementations(@NotNull final JetProperty property, @NotNull Processor<PsiElement> consumer) {
|
private static void processPropertyImplementations(@NotNull final JetProperty property, @NotNull Processor<PsiElement> consumer) {
|
||||||
LightClassUtil.PropertyAccessorsPsiMethods accessorsPsiMethods = ApplicationManager.getApplication().runReadAction(
|
LightClassUtil.PropertyAccessorsPsiMethods accessorsPsiMethods = ApplicationManager.getApplication().runReadAction(
|
||||||
new Computable<LightClassUtil.PropertyAccessorsPsiMethods>() {
|
new Computable<LightClassUtil.PropertyAccessorsPsiMethods>() {
|
||||||
@@ -84,11 +100,15 @@ public class KotlinDefinitionsSearcher extends QueryExecutorBase<PsiElement, Psi
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
for (PsiMethod method : accessorsPsiMethods) {
|
processPropertyImplementationsMethods(accessorsPsiMethods, consumer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void processPropertyImplementationsMethods(LightClassUtil.PropertyAccessorsPsiMethods accessors, @NotNull Processor<PsiElement> consumer) {
|
||||||
|
for (PsiMethod method : accessors) {
|
||||||
PsiMethod[] implementations = MethodImplementationsSearch.getMethodImplementations(method);
|
PsiMethod[] implementations = MethodImplementationsSearch.getMethodImplementations(method);
|
||||||
for (PsiMethod implementation : implementations) {
|
for (PsiMethod implementation : implementations) {
|
||||||
PsiElement mirrorElement = implementation instanceof PsiCompiledElement ? ((PsiCompiledElement) implementation).getMirror() : null;
|
PsiElement mirrorElement = implementation instanceof PsiCompiledElement ? ((PsiCompiledElement) implementation).getMirror() : null;
|
||||||
if (mirrorElement instanceof JetProperty) {
|
if (mirrorElement instanceof JetProperty || mirrorElement instanceof JetParameter) {
|
||||||
consumer.process(mirrorElement);
|
consumer.process(mirrorElement);
|
||||||
}
|
}
|
||||||
else if (mirrorElement instanceof JetPropertyAccessor && mirrorElement.getParent() instanceof JetProperty) {
|
else if (mirrorElement instanceof JetPropertyAccessor && mirrorElement.getParent() instanceof JetProperty) {
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
class Test(var <caret>field: Int)
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
class Test(var field: Int, <caret>parameter: Int)
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
fun testFun(<caret>parameter: Int) = 0
|
||||||
@@ -122,6 +122,18 @@ public class JetJavaFacadeTest extends LightCodeInsightFixtureTestCase {
|
|||||||
doTestWrapPropertyAccessor(true);
|
doTestWrapPropertyAccessor(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testWrapConstructorField() {
|
||||||
|
doTestWrapParameter(true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testWrapConstructorParameter() {
|
||||||
|
doTestWrapParameter(false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testWrapFunctionParameter() {
|
||||||
|
doTestWrapParameter(false, false);
|
||||||
|
}
|
||||||
|
|
||||||
public void testEa38770() {
|
public void testEa38770() {
|
||||||
myFixture.configureByFile(getTestName(true) + ".kt");
|
myFixture.configureByFile(getTestName(true) + ".kt");
|
||||||
|
|
||||||
@@ -197,6 +209,16 @@ public class JetJavaFacadeTest extends LightCodeInsightFixtureTestCase {
|
|||||||
checkDeclarationMethodWrapped(shouldBeWrapped, jetFunction, psiMethod);
|
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) {
|
private void doTestWrapProperty(boolean shouldWrapGetter, boolean shouldWrapSetter) {
|
||||||
JetProperty jetProperty = getPreparedElement(JetProperty.class);
|
JetProperty jetProperty = getPreparedElement(JetProperty.class);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user