Migrate SAMUtils from PSI to JavaElement
- create JavaTypeSubstitutor as a mirror for PsiSubstitutor - copy-paste MethodSignatureUtil.areSignaturesErasureEqual() and migrate it to JavaTypeSubstitutor - use a pair of method and substitutor instead of 'MethodSignatureBackedByPsiMethod' - add JavaClass.getDefaultType() which goes into JavaPsiFacade and creates an unsubstituted PsiClassType for the class - green code The only PSI usage left is TypeConversionUtil.erasure(), which needs to be copied and migrated somehow
This commit is contained in:
+1
-1
@@ -331,7 +331,7 @@ public final class JavaClassResolver {
|
|||||||
|
|
||||||
trace.record(BindingContext.CLASS, javaClass.getPsi(), classDescriptor);
|
trace.record(BindingContext.CLASS, javaClass.getPsi(), classDescriptor);
|
||||||
|
|
||||||
JavaMethod samInterfaceMethod = SingleAbstractMethodUtils.getSamInterfaceMethod(javaClass, javaClass.getPsi().getProject());
|
JavaMethod samInterfaceMethod = SingleAbstractMethodUtils.getSamInterfaceMethod(javaClass);
|
||||||
if (samInterfaceMethod != null) {
|
if (samInterfaceMethod != null) {
|
||||||
SimpleFunctionDescriptor abstractMethod = resolveFunctionOfSamInterface(samInterfaceMethod, classDescriptor);
|
SimpleFunctionDescriptor abstractMethod = resolveFunctionOfSamInterface(samInterfaceMethod, classDescriptor);
|
||||||
classDescriptor.setFunctionTypeForSamInterface(SingleAbstractMethodUtils.getFunctionTypeForAbstractMethod(abstractMethod));
|
classDescriptor.setFunctionTypeForSamInterface(SingleAbstractMethodUtils.getFunctionTypeForAbstractMethod(abstractMethod));
|
||||||
|
|||||||
+3
-3
@@ -25,8 +25,8 @@ import org.jetbrains.jet.lang.resolve.BindingTrace;
|
|||||||
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
||||||
import org.jetbrains.jet.lang.resolve.java.TypeUsage;
|
import org.jetbrains.jet.lang.resolve.java.TypeUsage;
|
||||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaClass;
|
import org.jetbrains.jet.lang.resolve.java.structure.JavaClass;
|
||||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaClassifierType;
|
|
||||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaClassifier;
|
import org.jetbrains.jet.lang.resolve.java.structure.JavaClassifier;
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.structure.JavaClassifierType;
|
||||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
import org.jetbrains.jet.lang.types.ErrorUtils;
|
import org.jetbrains.jet.lang.types.ErrorUtils;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
@@ -42,7 +42,7 @@ import java.util.List;
|
|||||||
import static org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule.IGNORE_KOTLIN_SOURCES;
|
import static org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule.IGNORE_KOTLIN_SOURCES;
|
||||||
|
|
||||||
public final class JavaSupertypeResolver {
|
public final class JavaSupertypeResolver {
|
||||||
private static final FqName OBJECT_FQ_NAME = new FqName("java.lang.Object");
|
public static final FqName OBJECT_FQ_NAME = new FqName("java.lang.Object");
|
||||||
|
|
||||||
private BindingTrace trace;
|
private BindingTrace trace;
|
||||||
private JavaTypeTransformer typeTransformer;
|
private JavaTypeTransformer typeTransformer;
|
||||||
@@ -116,7 +116,7 @@ public final class JavaSupertypeResolver {
|
|||||||
) {
|
) {
|
||||||
List<JetType> result = new ArrayList<JetType>(supertypes.size());
|
List<JetType> result = new ArrayList<JetType>(supertypes.size());
|
||||||
for (JavaClassifierType type : supertypes) {
|
for (JavaClassifierType type : supertypes) {
|
||||||
JavaClassifier resolved = type.resolve();
|
JavaClassifier resolved = type.getClassifier();
|
||||||
if (resolved != null) {
|
if (resolved != null) {
|
||||||
assert resolved instanceof JavaClass : "Supertype should be a class: " + resolved;
|
assert resolved instanceof JavaClass : "Supertype should be a class: " + resolved;
|
||||||
FqName fqName = ((JavaClass) resolved).getFqName();
|
FqName fqName = ((JavaClass) resolved).getFqName();
|
||||||
|
|||||||
+1
-1
@@ -111,7 +111,7 @@ public class JavaTypeTransformer {
|
|||||||
@NotNull TypeUsage howThisTypeIsUsed,
|
@NotNull TypeUsage howThisTypeIsUsed,
|
||||||
@NotNull TypeVariableResolver typeVariableResolver
|
@NotNull TypeVariableResolver typeVariableResolver
|
||||||
) {
|
) {
|
||||||
JavaClassifier javaClassifier = classifierType.resolve();
|
JavaClassifier javaClassifier = classifierType.getClassifier();
|
||||||
if (javaClassifier == null) {
|
if (javaClassifier == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
+64
-49
@@ -17,10 +17,7 @@
|
|||||||
package org.jetbrains.jet.lang.resolve.java.sam;
|
package org.jetbrains.jet.lang.resolve.java.sam;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.psi.util.TypeConversionUtil;
|
||||||
import com.intellij.psi.*;
|
|
||||||
import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
|
|
||||||
import com.intellij.util.ArrayUtil;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
@@ -32,24 +29,20 @@ import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl;
|
|||||||
import org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils;
|
import org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils;
|
||||||
import org.jetbrains.jet.lang.resolve.java.descriptor.ClassDescriptorFromJvmBytecode;
|
import org.jetbrains.jet.lang.resolve.java.descriptor.ClassDescriptorFromJvmBytecode;
|
||||||
import org.jetbrains.jet.lang.resolve.java.kotlinSignature.SignaturesUtil;
|
import org.jetbrains.jet.lang.resolve.java.kotlinSignature.SignaturesUtil;
|
||||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaClass;
|
import org.jetbrains.jet.lang.resolve.java.resolver.JavaSupertypeResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaClassifier;
|
import org.jetbrains.jet.lang.resolve.java.structure.*;
|
||||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaClassifierType;
|
|
||||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod;
|
|
||||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||||
import org.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.*;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static com.intellij.psi.util.MethodSignatureUtil.areSignaturesErasureEqual;
|
|
||||||
import static org.jetbrains.jet.lang.types.Variance.INVARIANT;
|
import static org.jetbrains.jet.lang.types.Variance.INVARIANT;
|
||||||
|
|
||||||
public class SingleAbstractMethodUtils {
|
public class SingleAbstractMethodUtils {
|
||||||
|
private SingleAbstractMethodUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static List<CallableMemberDescriptor> getAbstractMembers(@NotNull JetType type) {
|
public static List<CallableMemberDescriptor> getAbstractMembers(@NotNull JetType type) {
|
||||||
@@ -158,12 +151,14 @@ public class SingleAbstractMethodUtils {
|
|||||||
JetType parameterTypeUnsubstituted = getFunctionTypeForSamType(samInterface.getDefaultType());
|
JetType parameterTypeUnsubstituted = getFunctionTypeForSamType(samInterface.getDefaultType());
|
||||||
assert parameterTypeUnsubstituted != null : "couldn't get function type for SAM type " + samInterface.getDefaultType();
|
assert parameterTypeUnsubstituted != null : "couldn't get function type for SAM type " + samInterface.getDefaultType();
|
||||||
JetType parameterType = typeParameters.substitutor.substitute(parameterTypeUnsubstituted, Variance.IN_VARIANCE);
|
JetType parameterType = typeParameters.substitutor.substitute(parameterTypeUnsubstituted, Variance.IN_VARIANCE);
|
||||||
assert parameterType != null : "couldn't substitute type: " + parameterType + ", substitutor = " + typeParameters.substitutor;
|
assert parameterType != null : "couldn't substitute type: " + parameterTypeUnsubstituted +
|
||||||
|
", substitutor = " + typeParameters.substitutor;
|
||||||
ValueParameterDescriptor parameter = new ValueParameterDescriptorImpl(
|
ValueParameterDescriptor parameter = new ValueParameterDescriptorImpl(
|
||||||
result, 0, Collections.<AnnotationDescriptor>emptyList(), Name.identifier("function"), parameterType, false, null);
|
result, 0, Collections.<AnnotationDescriptor>emptyList(), Name.identifier("function"), parameterType, false, null);
|
||||||
|
|
||||||
JetType returnType = typeParameters.substitutor.substitute(samInterface.getDefaultType(), Variance.OUT_VARIANCE);
|
JetType returnType = typeParameters.substitutor.substitute(samInterface.getDefaultType(), Variance.OUT_VARIANCE);
|
||||||
assert returnType != null : "couldn't substitute type: " + returnType + ", substitutor = " + typeParameters.substitutor;
|
assert returnType != null : "couldn't substitute type: " + samInterface.getDefaultType() +
|
||||||
|
", substitutor = " + typeParameters.substitutor;
|
||||||
|
|
||||||
result.initialize(
|
result.initialize(
|
||||||
null,
|
null,
|
||||||
@@ -263,7 +258,8 @@ public class SingleAbstractMethodUtils {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
returnType = typeParameters.substitutor.substitute(returnTypeUnsubstituted, Variance.OUT_VARIANCE);
|
returnType = typeParameters.substitutor.substitute(returnTypeUnsubstituted, Variance.OUT_VARIANCE);
|
||||||
assert returnType != null : "couldn't substitute type: " + returnType + ", substitutor = " + typeParameters.substitutor;
|
assert returnType != null : "couldn't substitute type: " + returnTypeUnsubstituted +
|
||||||
|
", substitutor = " + typeParameters.substitutor;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<ValueParameterDescriptor> valueParameters = Lists.newArrayList();
|
List<ValueParameterDescriptor> valueParameters = Lists.newArrayList();
|
||||||
@@ -318,16 +314,13 @@ public class SingleAbstractMethodUtils {
|
|||||||
return getAbstractMethodOfSamType(samInterface.getDefaultType());
|
return getAbstractMethodOfSamType(samInterface.getDefaultType());
|
||||||
}
|
}
|
||||||
|
|
||||||
private SingleAbstractMethodUtils() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isSamInterface(@NotNull JavaClass javaClass) {
|
public static boolean isSamInterface(@NotNull JavaClass javaClass) {
|
||||||
return getSamInterfaceMethod(javaClass, javaClass.getPsi().getProject()) != null;
|
return getSamInterfaceMethod(javaClass) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns null if not SAM interface
|
// Returns null if not SAM interface
|
||||||
@Nullable
|
@Nullable
|
||||||
public static JavaMethod getSamInterfaceMethod(@NotNull JavaClass javaClass, @NotNull Project project) {
|
public static JavaMethod getSamInterfaceMethod(@NotNull JavaClass javaClass) {
|
||||||
FqName fqName = javaClass.getFqName();
|
FqName fqName = javaClass.getFqName();
|
||||||
if (fqName == null || fqName.firstSegmentIs(KotlinBuiltIns.BUILT_INS_PACKAGE_NAME)) {
|
if (fqName == null || fqName.firstSegmentIs(KotlinBuiltIns.BUILT_INS_PACKAGE_NAME)) {
|
||||||
return null;
|
return null;
|
||||||
@@ -336,25 +329,18 @@ public class SingleAbstractMethodUtils {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return findOnlyAbstractMethod(javaClass, project);
|
return findOnlyAbstractMethod(javaClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private static JavaMethod findOnlyAbstractMethod(@NotNull JavaClass javaClass, @NotNull Project project) {
|
private static JavaMethod findOnlyAbstractMethod(@NotNull JavaClass javaClass) {
|
||||||
JavaClassifierType classifierType = new JavaClassifierType(JavaPsiFacade.getElementFactory(project).createType(javaClass.getPsi()));
|
|
||||||
|
|
||||||
OnlyAbstractMethodFinder finder = new OnlyAbstractMethodFinder();
|
OnlyAbstractMethodFinder finder = new OnlyAbstractMethodFinder();
|
||||||
if (finder.find(classifierType)) {
|
if (finder.find(javaClass.getDefaultType())) {
|
||||||
return finder.getFoundMethod();
|
return finder.getFoundMethod();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isVarargMethod(@NotNull PsiMethod method) {
|
|
||||||
PsiParameter lastParameter = ArrayUtil.getLastElement(method.getParameterList().getParameters());
|
|
||||||
return lastParameter != null && lastParameter.getType() instanceof PsiEllipsisType;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class TypeParameters {
|
private static class TypeParameters {
|
||||||
public final List<TypeParameterDescriptor> descriptors;
|
public final List<TypeParameterDescriptor> descriptors;
|
||||||
public final TypeSubstitutor substitutor;
|
public final TypeSubstitutor substitutor;
|
||||||
@@ -374,38 +360,35 @@ public class SingleAbstractMethodUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static class OnlyAbstractMethodFinder {
|
private static class OnlyAbstractMethodFinder {
|
||||||
private MethodSignatureBackedByPsiMethod found;
|
private JavaMethod foundMethod;
|
||||||
|
private JavaTypeSubstitutor foundClassSubstitutor;
|
||||||
|
|
||||||
private boolean find(@NotNull JavaClassifierType classifierType) {
|
private boolean find(@NotNull JavaClassifierType classifierType) {
|
||||||
PsiClassType.ClassResolveResult classResolveResult = classifierType.getPsi().resolveGenerics();
|
JavaTypeSubstitutor classSubstitutor = classifierType.getSubstitutor();
|
||||||
PsiSubstitutor classSubstitutor = classResolveResult.getSubstitutor();
|
JavaClassifier classifier = classifierType.getClassifier();
|
||||||
JavaClassifier javaClassifier = classifierType.resolve();
|
if (classifier == null) {
|
||||||
if (javaClassifier == null) {
|
|
||||||
return false; // can't resolve class -> not a SAM interface
|
return false; // can't resolve class -> not a SAM interface
|
||||||
}
|
}
|
||||||
assert javaClassifier instanceof JavaClass : "Classifier should be a class here: " + javaClassifier;
|
assert classifier instanceof JavaClass : "Classifier should be a class here: " + classifier;
|
||||||
JavaClass javaClass = (JavaClass) javaClassifier;
|
JavaClass javaClass = (JavaClass) classifier;
|
||||||
if (new FqName(CommonClassNames.JAVA_LANG_OBJECT).equals(javaClass.getFqName())) {
|
if (JavaSupertypeResolver.OBJECT_FQ_NAME.equals(javaClass.getFqName())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
for (JavaMethod method : javaClass.getMethods()) {
|
for (JavaMethod method : javaClass.getMethods()) {
|
||||||
PsiMethod psiMethod = method.getPsi();
|
if (DescriptorResolverUtils.isObjectMethod(method.getPsi())) { // e.g., ignore toString() declared in interface
|
||||||
if (DescriptorResolverUtils.isObjectMethod(psiMethod)) { // e.g., ignore toString() declared in interface
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!method.getTypeParameters().isEmpty()) {
|
if (!method.getTypeParameters().isEmpty()) {
|
||||||
return false; // if interface has generic methods, it is not a SAM interface
|
return false; // if interface has generic methods, it is not a SAM interface
|
||||||
}
|
}
|
||||||
|
|
||||||
if (found == null) {
|
if (foundMethod == null) {
|
||||||
found = (MethodSignatureBackedByPsiMethod) psiMethod.getSignature(classSubstitutor);
|
foundMethod = method;
|
||||||
|
foundClassSubstitutor = classSubstitutor;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!found.getName().equals(method.getName().asString())) {
|
|
||||||
return false; // optimizing heuristic
|
if (!areSignaturesErasureEqual(method, classSubstitutor, foundMethod, foundClassSubstitutor)) {
|
||||||
}
|
|
||||||
MethodSignatureBackedByPsiMethod current = (MethodSignatureBackedByPsiMethod) psiMethod.getSignature(classSubstitutor);
|
|
||||||
if (!areSignaturesErasureEqual(current, found) || isVarargMethod(psiMethod) != isVarargMethod(found.getMethod())) {
|
|
||||||
return false; // different signatures
|
return false; // different signatures
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -419,9 +402,41 @@ public class SingleAbstractMethodUtils {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see com.intellij.psi.util.MethodSignatureUtil#areSignaturesErasureEqual
|
||||||
|
*/
|
||||||
|
private static boolean areSignaturesErasureEqual(
|
||||||
|
@NotNull JavaMethod method1,
|
||||||
|
@NotNull JavaTypeSubstitutor substitutor1,
|
||||||
|
@NotNull JavaMethod method2,
|
||||||
|
@NotNull JavaTypeSubstitutor substitutor2
|
||||||
|
) {
|
||||||
|
if (method1.isConstructor() != method2.isConstructor()) return false;
|
||||||
|
if (!method1.isConstructor() && !method1.getName().equals(method2.getName())) return false;
|
||||||
|
|
||||||
|
if (method1.isVararg() != method2.isVararg()) return false;
|
||||||
|
|
||||||
|
Collection<JavaValueParameter> parameters1 = method1.getValueParameters();
|
||||||
|
Collection<JavaValueParameter> parameters2 = method2.getValueParameters();
|
||||||
|
if (parameters1.size() != parameters2.size()) return false;
|
||||||
|
|
||||||
|
for (Iterator<JavaValueParameter> it1 = parameters1.iterator(), it2 = parameters2.iterator(); it1.hasNext(); ) {
|
||||||
|
JavaType type1 = erasure(substitutor1.substitute(it1.next().getType()), substitutor1);
|
||||||
|
JavaType type2 = erasure(substitutor2.substitute(it2.next().getType()), substitutor2);
|
||||||
|
if (!type1.equals(type2)) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static JavaType erasure(@NotNull JavaType type, @NotNull JavaTypeSubstitutor substitutor) {
|
||||||
|
return JavaType.create(TypeConversionUtil.erasure(type.getPsi(), substitutor.getPsi()));
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private JavaMethod getFoundMethod() {
|
private JavaMethod getFoundMethod() {
|
||||||
return found == null ? null : new JavaMethod(found.getMethod());
|
return foundMethod;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-4
@@ -16,10 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.lang.resolve.java.structure;
|
package org.jetbrains.jet.lang.resolve.java.structure;
|
||||||
|
|
||||||
import com.intellij.psi.PsiAnnotation;
|
import com.intellij.psi.*;
|
||||||
import com.intellij.psi.PsiClass;
|
|
||||||
import com.intellij.psi.PsiModifierList;
|
|
||||||
import com.intellij.psi.PsiTypeParameter;
|
|
||||||
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.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@@ -168,4 +165,9 @@ public class JavaClass extends JavaClassifier
|
|||||||
public JavaAnnotation findAnnotation(@NotNull FqName fqName) {
|
public JavaAnnotation findAnnotation(@NotNull FqName fqName) {
|
||||||
return JavaElementUtil.findAnnotation(this, fqName);
|
return JavaElementUtil.findAnnotation(this, fqName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public JavaClassifierType getDefaultType() {
|
||||||
|
return new JavaClassifierType(JavaPsiFacade.getElementFactory(getPsi().getProject()).createType(getPsi()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+32
-3
@@ -30,6 +30,18 @@ import java.util.List;
|
|||||||
import static org.jetbrains.jet.lang.resolve.java.structure.JavaElementCollectionFromPsiArrayUtil.types;
|
import static org.jetbrains.jet.lang.resolve.java.structure.JavaElementCollectionFromPsiArrayUtil.types;
|
||||||
|
|
||||||
public class JavaClassifierType extends JavaType {
|
public class JavaClassifierType extends JavaType {
|
||||||
|
private static class ResolutionResult {
|
||||||
|
private final JavaClassifier classifier;
|
||||||
|
private final JavaTypeSubstitutor substitutor;
|
||||||
|
|
||||||
|
private ResolutionResult(@Nullable JavaClassifier classifier, @NotNull JavaTypeSubstitutor substitutor) {
|
||||||
|
this.classifier = classifier;
|
||||||
|
this.substitutor = substitutor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResolutionResult resolutionResult;
|
||||||
|
|
||||||
public JavaClassifierType(@NotNull PsiClassType psiClassType) {
|
public JavaClassifierType(@NotNull PsiClassType psiClassType) {
|
||||||
super(psiClassType);
|
super(psiClassType);
|
||||||
}
|
}
|
||||||
@@ -41,9 +53,26 @@ public class JavaClassifierType extends JavaType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public JavaClassifier resolve() {
|
public JavaClassifier getClassifier() {
|
||||||
PsiClass psiClass = getPsi().resolve();
|
resolve();
|
||||||
return psiClass == null ? null : JavaClassifier.create(psiClass);
|
return resolutionResult.classifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public JavaTypeSubstitutor getSubstitutor() {
|
||||||
|
resolve();
|
||||||
|
return resolutionResult.substitutor;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resolve() {
|
||||||
|
if (resolutionResult == null) {
|
||||||
|
PsiClassType.ClassResolveResult result = getPsi().resolveGenerics();
|
||||||
|
PsiClass psiClass = result.getElement();
|
||||||
|
resolutionResult = new ResolutionResult(
|
||||||
|
psiClass == null ? null : JavaClassifier.create(psiClass),
|
||||||
|
new JavaTypeSubstitutor(result.getSubstitutor())
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -66,4 +66,9 @@ public abstract class JavaType {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
return obj instanceof JavaType && getPsi().equals(((JavaType) obj).getPsi());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2013 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.lang.resolve.java.structure;
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiSubstitutor;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class JavaTypeSubstitutor {
|
||||||
|
private final PsiSubstitutor psiSubstitutor;
|
||||||
|
|
||||||
|
public JavaTypeSubstitutor(@NotNull PsiSubstitutor psiSubstitutor) {
|
||||||
|
this.psiSubstitutor = psiSubstitutor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public PsiSubstitutor getPsi() {
|
||||||
|
return psiSubstitutor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public JavaType substitute(@NotNull JavaType type) {
|
||||||
|
return JavaType.create(psiSubstitutor.substitute(type.getPsi()));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user