From 5b2858ef26ad29892d04ad990957585928decc4d Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Wed, 22 Jan 2014 15:13:29 +0400 Subject: [PATCH] Generate light type parameters for Kotlin light methods --- .../java/jetAsJava/KotlinLightMethod.java | 1 + ...otlinLightClassForExplicitDeclaration.java | 14 +-------- .../asJava/KotlinLightMethodForDeclaration.kt | 25 ++++++++++++--- .../jet/asJava/KotlinLightTypeParameter.java | 31 ++++++++++++++----- .../jetbrains/jet/asJava/LightClassUtil.java | 23 ++++++++++++-- 5 files changed, 66 insertions(+), 28 deletions(-) diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/jetAsJava/KotlinLightMethod.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/jetAsJava/KotlinLightMethod.java index c29f2725134..9497329c9f3 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/jetAsJava/KotlinLightMethod.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/jetAsJava/KotlinLightMethod.java @@ -22,4 +22,5 @@ import org.jetbrains.jet.lang.psi.JetDeclaration; /** Java method created for Kotlin declaration to make it resolvable in Java */ public interface KotlinLightMethod extends PsiMethod { JetDeclaration getOrigin(); + PsiMethod getDelegate(); } diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightClassForExplicitDeclaration.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightClassForExplicitDeclaration.java index 483089bce85..cd7f2730713 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightClassForExplicitDeclaration.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightClassForExplicitDeclaration.java @@ -32,7 +32,6 @@ import com.intellij.psi.impl.java.stubs.PsiJavaFileStub; import com.intellij.psi.impl.light.LightClass; import com.intellij.psi.impl.light.LightMethod; import com.intellij.psi.impl.light.LightModifierList; -import com.intellij.psi.impl.light.LightTypeParameterListBuilder; import com.intellij.psi.stubs.PsiClassHolderFileStub; import com.intellij.psi.util.CachedValue; import com.intellij.psi.util.CachedValuesManager; @@ -185,18 +184,7 @@ public class KotlinLightClassForExplicitDeclaration extends KotlinWrappingLightC @Nullable @Override protected PsiTypeParameterList compute() { - LightTypeParameterListBuilder builder = new LightTypeParameterListBuilder(getManager(), getLanguage()); - if (classOrObject instanceof JetTypeParameterListOwner) { - JetTypeParameterListOwner typeParameterListOwner = (JetTypeParameterListOwner) classOrObject; - List parameters = typeParameterListOwner.getTypeParameters(); - for (int i = 0; i < parameters.size(); i++) { - JetTypeParameter jetTypeParameter = parameters.get(i); - String name = jetTypeParameter.getName(); - String safeName = name == null ? "__no_name__" : name; - builder.addParameter(new KotlinLightTypeParameter(KotlinLightClassForExplicitDeclaration.this, i, safeName)); - } - } - return builder; + return LightClassUtil.buildLightTypeParameterList(KotlinLightClassForExplicitDeclaration.this, classOrObject); } }; diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightMethodForDeclaration.kt b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightMethodForDeclaration.kt index 288dfa8949e..b7640d91118 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightMethodForDeclaration.kt +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightMethodForDeclaration.kt @@ -23,9 +23,6 @@ import com.intellij.psi.PsiManager import com.intellij.psi.PsiElement import com.intellij.psi.PsiNamedElement import org.jetbrains.jet.lang.psi.JetDeclaration -import com.intellij.psi.PsiParameterList -import org.jetbrains.jet.plugin.JetLanguage -import kotlin.properties.Delegates import org.jetbrains.jet.asJava.light.LightParameter import org.jetbrains.jet.asJava.light.LightParameterListBuilder import org.jetbrains.jet.lang.resolve.java.jetAsJava.KotlinLightMethod @@ -35,8 +32,12 @@ import kotlin.properties.Delegates import com.intellij.psi.util.CachedValuesManager import com.intellij.psi.util.PsiModificationTracker import com.intellij.psi.util.CachedValueProvider -import com.intellij.openapi.application.Result import com.intellij.psi.util.CachedValue +import com.intellij.psi.PsiTypeParameterList +import org.jetbrains.jet.lang.psi.JetPropertyAccessor +import org.jetbrains.jet.lang.psi.psiUtil.getParentByType +import org.jetbrains.jet.lang.psi.JetProperty +import com.intellij.psi.PsiTypeParameter public class KotlinLightMethodForDeclaration(manager: PsiManager, val method: PsiMethod, val jetDeclaration: JetDeclaration, containingClass: PsiClass): LightMethod(manager, method, containingClass), KotlinLightMethod { @@ -55,6 +56,18 @@ public class KotlinLightMethodForDeclaration(manager: PsiManager, val method: Ps }, false) } + private val typeParamsList: CachedValue by Delegates.blockingLazy { + val cacheManager = CachedValuesManager.getManager(method.getProject()) + cacheManager.createCachedValue({ + val declaration = + if (jetDeclaration is JetPropertyAccessor) jetDeclaration.getParentByType(javaClass()) else jetDeclaration + val list = LightClassUtil.buildLightTypeParameterList(this@KotlinLightMethodForDeclaration, jetDeclaration) + CachedValueProvider.Result.create(list, PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT) + }, false) + } + + override fun getDelegate(): PsiMethod = method + override fun getNavigationElement() : PsiElement = jetDeclaration override fun getOriginalElement() : PsiElement = jetDeclaration override fun getOrigin(): JetDeclaration? = jetDeclaration @@ -82,6 +95,10 @@ public class KotlinLightMethodForDeclaration(manager: PsiManager, val method: Ps override fun getParameterList(): PsiParameterList = paramsList.getValue()!! + override fun getTypeParameterList(): PsiTypeParameterList? = typeParamsList.getValue() + override fun getTypeParameters(): Array = + getTypeParameterList()?.let { it.getTypeParameters() } ?: PsiTypeParameter.EMPTY_ARRAY + override fun copy(): PsiElement { return KotlinLightMethodForDeclaration(getManager()!!, method, jetDeclaration.copy() as JetDeclaration, getContainingClass()!!) } diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightTypeParameter.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightTypeParameter.java index 33540a8a4e6..1ad3b4bd5f1 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightTypeParameter.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinLightTypeParameter.java @@ -20,20 +20,22 @@ import com.intellij.psi.*; import com.intellij.psi.impl.light.AbstractLightClass; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.psi.JetClass; +import org.jetbrains.jet.lang.psi.JetTypeParameterListOwner; +import org.jetbrains.jet.lang.resolve.java.jetAsJava.KotlinLightMethod; import org.jetbrains.jet.plugin.JetLanguage; public class KotlinLightTypeParameter extends AbstractLightClass implements PsiTypeParameter { - - private final KotlinLightClassForExplicitDeclaration lightClass; + private final PsiTypeParameterListOwner owner; private final int index; private final String name; protected KotlinLightTypeParameter( - @NotNull KotlinLightClassForExplicitDeclaration lightClass, + @NotNull PsiTypeParameterListOwner owner, int index, @NotNull String name) { - super(lightClass.getManager(), JetLanguage.INSTANCE); - this.lightClass = lightClass; + super(owner.getManager(), JetLanguage.INSTANCE); + this.owner = owner; this.index = index; this.name = name; } @@ -41,13 +43,20 @@ public class KotlinLightTypeParameter extends AbstractLightClass implements PsiT @NotNull @Override public PsiTypeParameter getDelegate() { - return lightClass.getDelegate().getTypeParameters()[index]; + return getOwnerDelegate().getTypeParameters()[index]; + } + + @NotNull + private PsiTypeParameterListOwner getOwnerDelegate() { + if (owner instanceof KotlinLightClass) return ((KotlinLightClass) owner).getDelegate(); + if (owner instanceof KotlinLightMethod) return ((KotlinLightMethod) owner).getDelegate(); + return owner; } @NotNull @Override public PsiElement copy() { - return new KotlinLightTypeParameter(lightClass, index, name); + return new KotlinLightTypeParameter(owner, index, name); } @Override @@ -68,7 +77,7 @@ public class KotlinLightTypeParameter extends AbstractLightClass implements PsiT @Override public PsiTypeParameterListOwner getOwner() { - return lightClass; + return owner; } @Override @@ -103,4 +112,10 @@ public class KotlinLightTypeParameter extends AbstractLightClass implements PsiT public String toString() { return "KotlinLightTypeParameter:" + getName(); } + + @NotNull + @Override + public PsiElement getNavigationElement() { + return ((JetTypeParameterListOwner) owner.getNavigationElement()).getTypeParameters().get(index); + } } 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 2b947aeed31..52690fec624 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 @@ -24,10 +24,9 @@ import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.StandardFileSystems; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiMethod; +import com.intellij.psi.*; import com.intellij.psi.impl.java.stubs.PsiClassStub; +import com.intellij.psi.impl.light.LightTypeParameterListBuilder; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.stubs.PsiFileStub; import com.intellij.psi.stubs.StubElement; @@ -289,6 +288,24 @@ public class LightClassUtil { return new PropertyAccessorsPsiMethods(getterWrapper, setterWrapper); } + @NotNull + public static PsiTypeParameterList buildLightTypeParameterList( + PsiTypeParameterListOwner owner, + JetDeclaration declaration) { + LightTypeParameterListBuilder builder = new LightTypeParameterListBuilder(owner.getManager(), owner.getLanguage()); + if (declaration instanceof JetTypeParameterListOwner) { + JetTypeParameterListOwner typeParameterListOwner = (JetTypeParameterListOwner) declaration; + List parameters = typeParameterListOwner.getTypeParameters(); + for (int i = 0; i < parameters.size(); i++) { + JetTypeParameter jetTypeParameter = parameters.get(i); + String name = jetTypeParameter.getName(); + String safeName = name == null ? "__no_name__" : name; + builder.addParameter(new KotlinLightTypeParameter(owner, i, safeName)); + } + } + return builder; + } + public static class PropertyAccessorsPsiMethods implements Iterable { private final PsiMethod getter; private final PsiMethod setter;