Generate light type parameters for Kotlin light methods

This commit is contained in:
Alexey Sedunov
2014-01-22 15:13:29 +04:00
parent 598a3214d2
commit 5b2858ef26
5 changed files with 66 additions and 28 deletions
@@ -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();
}
@@ -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<JetTypeParameter> 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);
}
};
@@ -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<PsiTypeParameterList> by Delegates.blockingLazy {
val cacheManager = CachedValuesManager.getManager(method.getProject())
cacheManager.createCachedValue<PsiTypeParameterList>({
val declaration =
if (jetDeclaration is JetPropertyAccessor) jetDeclaration.getParentByType(javaClass<JetProperty>()) 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<PsiTypeParameter> =
getTypeParameterList()?.let { it.getTypeParameters() } ?: PsiTypeParameter.EMPTY_ARRAY
override fun copy(): PsiElement {
return KotlinLightMethodForDeclaration(getManager()!!, method, jetDeclaration.copy() as JetDeclaration, getContainingClass()!!)
}
@@ -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);
}
}
@@ -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<JetTypeParameter> 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<PsiMethod> {
private final PsiMethod getter;
private final PsiMethod setter;