JavaDescriptorResolver refactoring

* kill JavaDescriptorResolver.typeParameterDescriptorCache
* use ClassOrNamespaceDescriptor instead of DeclarationDescriptor

Code is a bit ugly now, but simpler than before.
This commit is contained in:
Stepan Koltsov
2012-01-31 22:48:55 +04:00
parent c88940c07c
commit e075bec4c0
30 changed files with 485 additions and 217 deletions
@@ -6,6 +6,7 @@ import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiModifier; import com.intellij.psi.PsiModifier;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassOrNamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor; import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
@@ -14,6 +15,8 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import java.util.*; import java.util.*;
/** /**
* Class static of instance members.
*
* @author abreslav * @author abreslav
*/ */
public class JavaClassMembersScope extends JavaClassOrPackageScope { public class JavaClassMembersScope extends JavaClassOrPackageScope {
@@ -23,7 +26,7 @@ public class JavaClassMembersScope extends JavaClassOrPackageScope {
private Collection<DeclarationDescriptor> allDescriptors; private Collection<DeclarationDescriptor> allDescriptors;
public JavaClassMembersScope( public JavaClassMembersScope(
@NotNull DeclarationDescriptor classOrNamespaceDescriptor, @NotNull ClassOrNamespaceDescriptor classOrNamespaceDescriptor,
@NotNull PsiClass psiClass, @NotNull PsiClass psiClass,
@NotNull JavaSemanticServices semanticServices, @NotNull JavaSemanticServices semanticServices,
boolean staticMembers) { boolean staticMembers) {
@@ -1,8 +1,8 @@
package org.jetbrains.jet.lang.resolve.java; package org.jetbrains.jet.lang.resolve.java;
import com.intellij.psi.PsiClass;
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.ClassOrNamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor; import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
@@ -17,10 +17,10 @@ import java.util.Set;
public abstract class JavaClassOrPackageScope extends JetScopeImpl { public abstract class JavaClassOrPackageScope extends JetScopeImpl {
@NotNull @NotNull
protected final DeclarationDescriptor descriptor; protected final ClassOrNamespaceDescriptor descriptor;
protected final JavaSemanticServices semanticServices; protected final JavaSemanticServices semanticServices;
protected JavaClassOrPackageScope(@NotNull DeclarationDescriptor descriptor, @NotNull JavaSemanticServices semanticServices) { protected JavaClassOrPackageScope(@NotNull ClassOrNamespaceDescriptor descriptor, @NotNull JavaSemanticServices semanticServices) {
this.descriptor = descriptor; this.descriptor = descriptor;
this.semanticServices = semanticServices; this.semanticServices = semanticServices;
} }
@@ -66,25 +66,30 @@ public class JavaDescriptorResolver {
KOTLIN, KOTLIN,
} }
private static class TypeParameterDescriptorInitialization { public static class TypeParameterDescriptorInitialization {
@NotNull
private final TypeParameterDescriptorOrigin origin; private final TypeParameterDescriptorOrigin origin;
private final TypeParameterDescriptor descriptor; @NotNull
final TypeParameterDescriptor descriptor;
final PsiTypeParameter psiTypeParameter;
@Nullable @Nullable
private final List<JetType> upperBoundsForKotlin; private final List<JetType> upperBoundsForKotlin;
@Nullable @Nullable
private final List<JetType> lowerBoundsForKotlin; private final List<JetType> lowerBoundsForKotlin;
private TypeParameterDescriptorInitialization(TypeParameterDescriptor descriptor) { private TypeParameterDescriptorInitialization(@NotNull TypeParameterDescriptor descriptor, @NotNull PsiTypeParameter psiTypeParameter) {
this.origin = TypeParameterDescriptorOrigin.JAVA; this.origin = TypeParameterDescriptorOrigin.JAVA;
this.descriptor = descriptor; this.descriptor = descriptor;
this.psiTypeParameter = psiTypeParameter;
this.upperBoundsForKotlin = null; this.upperBoundsForKotlin = null;
this.lowerBoundsForKotlin = null; this.lowerBoundsForKotlin = null;
} }
private TypeParameterDescriptorInitialization(TypeParameterDescriptor descriptor, private TypeParameterDescriptorInitialization(@NotNull TypeParameterDescriptor descriptor, @NotNull PsiTypeParameter psiTypeParameter,
List<JetType> upperBoundsForKotlin, List<JetType> lowerBoundsForKotlin) { List<JetType> upperBoundsForKotlin, List<JetType> lowerBoundsForKotlin) {
this.origin = TypeParameterDescriptorOrigin.KOTLIN; this.origin = TypeParameterDescriptorOrigin.KOTLIN;
this.descriptor = descriptor; this.descriptor = descriptor;
this.psiTypeParameter = psiTypeParameter;
this.upperBoundsForKotlin = upperBoundsForKotlin; this.upperBoundsForKotlin = upperBoundsForKotlin;
this.lowerBoundsForKotlin = lowerBoundsForKotlin; this.lowerBoundsForKotlin = lowerBoundsForKotlin;
} }
@@ -97,10 +102,38 @@ public class JavaDescriptorResolver {
private Map<String, NamedMembers> namedMembersMap; private Map<String, NamedMembers> namedMembersMap;
} }
static abstract class ResolverClassData extends ResolverScopeData {
@NotNull
public abstract ClassDescriptor getClassDescriptor();
}
/** Class with instance members */ /** Class with instance members */
private static class ResolverClassData extends ResolverScopeData { static class ResolverBinaryClassData extends ResolverClassData {
ResolverBinaryClassData() {
}
private MutableClassDescriptorLite classDescriptor; private MutableClassDescriptorLite classDescriptor;
List<TypeParameterDescriptorInitialization> typeParameters;
@Override
@NotNull
public ClassDescriptor getClassDescriptor() {
return classDescriptor;
}
}
static class ResolverSrcClassData extends ResolverClassData {
@NotNull
private final ClassDescriptor classDescriptor;
ResolverSrcClassData(@NotNull ClassDescriptor classDescriptor) {
this.classDescriptor = classDescriptor;
}
@Override
@NotNull @NotNull
public ClassDescriptor getClassDescriptor() { public ClassDescriptor getClassDescriptor() {
return classDescriptor; return classDescriptor;
@@ -117,11 +150,10 @@ public class JavaDescriptorResolver {
} }
} }
protected final Map<String, ResolverClassData> classDescriptorCache = Maps.newHashMap(); protected final Map<String, ResolverBinaryClassData> classDescriptorCache = Maps.newHashMap();
protected final Map<String, ResolverNamespaceData> namespaceDescriptorCacheByFqn = Maps.newHashMap(); protected final Map<String, ResolverNamespaceData> namespaceDescriptorCacheByFqn = Maps.newHashMap();
protected final Map<PsiElement, ResolverNamespaceData> namespaceDescriptorCache = Maps.newHashMap(); protected final Map<PsiElement, ResolverNamespaceData> namespaceDescriptorCache = Maps.newHashMap();
private final Map<PsiTypeParameter, TypeParameterDescriptorInitialization> typeParameterDescriptorCache = Maps.newHashMap();
protected final Map<PsiMethod, FunctionDescriptor> methodDescriptorCache = Maps.newHashMap(); protected final Map<PsiMethod, FunctionDescriptor> methodDescriptorCache = Maps.newHashMap();
protected final JavaPsiFacade javaFacade; protected final JavaPsiFacade javaFacade;
protected final GlobalSearchScope javaSearchScope; protected final GlobalSearchScope javaSearchScope;
@@ -141,7 +173,7 @@ public class JavaDescriptorResolver {
} }
@Nullable @Nullable
public ClassDescriptor resolveClass(@NotNull PsiClass psiClass) { ResolverClassData resolveClassData(@NotNull PsiClass psiClass) {
String qualifiedName = psiClass.getQualifiedName(); String qualifiedName = psiClass.getQualifiedName();
if (qualifiedName.endsWith(JvmAbi.TRAIT_IMPL_SUFFIX)) { if (qualifiedName.endsWith(JvmAbi.TRAIT_IMPL_SUFFIX)) {
@@ -152,16 +184,26 @@ public class JavaDescriptorResolver {
// First, let's check that this is a real Java class, not a Java's view on a Kotlin class: // First, let's check that this is a real Java class, not a Java's view on a Kotlin class:
ClassDescriptor kotlinClassDescriptor = semanticServices.getKotlinClassDescriptor(qualifiedName); ClassDescriptor kotlinClassDescriptor = semanticServices.getKotlinClassDescriptor(qualifiedName);
if (kotlinClassDescriptor != null) { if (kotlinClassDescriptor != null) {
return kotlinClassDescriptor; return new ResolverSrcClassData(kotlinClassDescriptor);
} }
// Not let's take a descriptor of a Java class // Not let's take a descriptor of a Java class
ResolverClassData classData = classDescriptorCache.get(qualifiedName); ResolverBinaryClassData classData = classDescriptorCache.get(qualifiedName);
if (classData == null) { if (classData == null) {
classData = createJavaClassDescriptor(psiClass); classData = createJavaClassDescriptor(psiClass);
classDescriptorCache.put(qualifiedName, classData); classDescriptorCache.put(qualifiedName, classData);
} }
return classData.getClassDescriptor(); return classData;
}
@Nullable
public ClassDescriptor resolveClass(@NotNull PsiClass psiClass) {
ResolverClassData classData = resolveClassData(psiClass);
if (classData != null) {
return classData.getClassDescriptor();
} else {
return null;
}
} }
@Nullable @Nullable
@@ -179,7 +221,7 @@ public class JavaDescriptorResolver {
} }
// Not let's take a descriptor of a Java class // Not let's take a descriptor of a Java class
ResolverClassData classData = classDescriptorCache.get(qualifiedName); ResolverBinaryClassData classData = classDescriptorCache.get(qualifiedName);
if (classData == null) { if (classData == null) {
PsiClass psiClass = findClass(qualifiedName); PsiClass psiClass = findClass(qualifiedName);
if (psiClass == null) { if (psiClass == null) {
@@ -190,19 +232,19 @@ public class JavaDescriptorResolver {
return classData.getClassDescriptor(); return classData.getClassDescriptor();
} }
private ResolverClassData createJavaClassDescriptor(@NotNull final PsiClass psiClass) { private ResolverBinaryClassData createJavaClassDescriptor(@NotNull final PsiClass psiClass) {
assert !classDescriptorCache.containsKey(psiClass.getQualifiedName()) : psiClass.getQualifiedName(); assert !classDescriptorCache.containsKey(psiClass.getQualifiedName()) : psiClass.getQualifiedName();
classDescriptorCache.put(psiClass.getQualifiedName(), null); // TODO classDescriptorCache.put(psiClass.getQualifiedName(), null); // TODO
String name = psiClass.getName(); String name = psiClass.getName();
ResolverClassData classData = new ResolverClassData(); ResolverBinaryClassData classData = new ResolverBinaryClassData();
ClassKind kind = psiClass.isInterface() ? (psiClass.isAnnotationType() ? ClassKind.ANNOTATION_CLASS : ClassKind.TRAIT) : ClassKind.CLASS; ClassKind kind = psiClass.isInterface() ? (psiClass.isAnnotationType() ? ClassKind.ANNOTATION_CLASS : ClassKind.TRAIT) : ClassKind.CLASS;
classData.classDescriptor = new MutableClassDescriptorLite( classData.classDescriptor = new MutableClassDescriptorLite(
resolveParentDescriptor(psiClass), kind resolveParentDescriptor(psiClass), kind
); );
classData.classDescriptor.setName(name); classData.classDescriptor.setName(name);
class OuterClassTypeVariableResolver implements TypeVariableResolver { class OuterClassTypeVariableByNameResolver implements TypeVariableByNameResolver {
@NotNull @NotNull
@Override @Override
@@ -213,7 +255,13 @@ public class JavaDescriptorResolver {
List<JetType> supertypes = new ArrayList<JetType>(); List<JetType> supertypes = new ArrayList<JetType>();
List<TypeParameterDescriptor> typeParameters = resolveClassTypeParameters(psiClass, classData, new OuterClassTypeVariableResolver()); classData.typeParameters = createUninitializedClassTypeParameters(psiClass, classData, new OuterClassTypeVariableByNameResolver());
List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>();
for (TypeParameterDescriptorInitialization typeParameter : classData.typeParameters) {
typeParameters.add(typeParameter.descriptor);
}
classData.classDescriptor.setTypeParameterDescriptors(typeParameters); classData.classDescriptor.setTypeParameterDescriptors(typeParameters);
classData.classDescriptor.setSupertypes(supertypes); classData.classDescriptor.setSupertypes(supertypes);
classData.classDescriptor.setVisibility(resolveVisibilityFromPsiModifiers(psiClass)); classData.classDescriptor.setVisibility(resolveVisibilityFromPsiModifiers(psiClass));
@@ -225,10 +273,12 @@ public class JavaDescriptorResolver {
classDescriptorCache.put(psiClass.getQualifiedName(), classData); classDescriptorCache.put(psiClass.getQualifiedName(), classData);
classData.classDescriptor.setScopeForMemberLookup(new JavaClassMembersScope(classData.classDescriptor, psiClass, semanticServices, false)); classData.classDescriptor.setScopeForMemberLookup(new JavaClassMembersScope(classData.classDescriptor, psiClass, semanticServices, false));
initializeTypeParameters(psiClass); initializeTypeParameters(classData.typeParameters, new TypeVariableResoverFromTypeDescriptorsInitialization(new ArrayList<TypeParameterDescriptorInitialization>(), null));
TypeVariableResoverFromTypeDescriptorsInitialization resolverForTypeParameters = new TypeVariableResoverFromTypeDescriptorsInitialization(classData.typeParameters, null);
// TODO: ugly hack: tests crash if initializeTypeParameters called with class containing proper supertypes // TODO: ugly hack: tests crash if initializeTypeParameters called with class containing proper supertypes
supertypes.addAll(getSupertypes(new PsiClassWrapper(psiClass), classData.classDescriptor.getTypeConstructor().getParameters())); supertypes.addAll(getSupertypes(new PsiClassWrapper(psiClass), classData.typeParameters));
if (psiClass.isInterface()) { if (psiClass.isInterface()) {
//classData.classDescriptor.setSuperclassType(JetStandardClasses.getAnyType()); // TODO : Make it java.lang.Object //classData.classDescriptor.setSuperclassType(JetStandardClasses.getAnyType()); // TODO : Make it java.lang.Object
@@ -238,7 +288,7 @@ public class JavaDescriptorResolver {
assert extendsListTypes.length == 0 || extendsListTypes.length == 1; assert extendsListTypes.length == 0 || extendsListTypes.length == 1;
JetType superclassType = extendsListTypes.length == 0 JetType superclassType = extendsListTypes.length == 0
? JetStandardClasses.getAnyType() ? JetStandardClasses.getAnyType()
: semanticServices.getTypeTransformer().transformToType(extendsListTypes[0]); : semanticServices.getTypeTransformer().transformToType(extendsListTypes[0], resolverForTypeParameters);
//classData.classDescriptor.setSuperclassType(superclassType); //classData.classDescriptor.setSuperclassType(superclassType);
} }
@@ -280,7 +330,7 @@ public class JavaDescriptorResolver {
// if the last method of the @interface is an array, we convert it into a vararg // if the last method of the @interface is an array, we convert it into a vararg
JetType varargElementType = null; JetType varargElementType = null;
if (i == methods.length - 1 && (returnType instanceof PsiArrayType)) { if (i == methods.length - 1 && (returnType instanceof PsiArrayType)) {
varargElementType = semanticServices.getTypeTransformer().transformToType(((PsiArrayType) returnType).getComponentType()); varargElementType = semanticServices.getTypeTransformer().transformToType(((PsiArrayType) returnType).getComponentType(), resolverForTypeParameters);
} }
valueParameters.add(new ValueParameterDescriptorImpl( valueParameters.add(new ValueParameterDescriptorImpl(
@@ -289,7 +339,7 @@ public class JavaDescriptorResolver {
Collections.<AnnotationDescriptor>emptyList(), Collections.<AnnotationDescriptor>emptyList(),
method.getName(), method.getName(),
false, false,
semanticServices.getTypeTransformer().transformToType(returnType), semanticServices.getTypeTransformer().transformToType(returnType, resolverForTypeParameters),
annotationMethod.getDefaultValue() != null, annotationMethod.getDefaultValue() != null,
varargElementType)); varargElementType));
} }
@@ -315,7 +365,7 @@ public class JavaDescriptorResolver {
false); false);
ValueParameterDescriptors valueParameterDescriptors = resolveParameterDescriptors(constructorDescriptor, ValueParameterDescriptors valueParameterDescriptors = resolveParameterDescriptors(constructorDescriptor,
constructor.getParameters(), constructor.getParameters(),
new TypeParameterListTypeVariableResolver(typeParameters) // TODO: outer too new TypeVariableResoverFromTypeDescriptorsInitialization(classData.typeParameters, null) // TODO: outer too
); );
if (valueParameterDescriptors.receiverType != null) { if (valueParameterDescriptors.receiverType != null) {
throw new IllegalStateException(); throw new IllegalStateException();
@@ -333,13 +383,13 @@ public class JavaDescriptorResolver {
return classData; return classData;
} }
private List<TypeParameterDescriptor> resolveClassTypeParameters(PsiClass psiClass, ResolverClassData classData, TypeVariableResolver typeVariableResolver) { private List<TypeParameterDescriptorInitialization> createUninitializedClassTypeParameters(PsiClass psiClass, ResolverBinaryClassData classData, TypeVariableByNameResolver typeVariableByNameResolver) {
JetClassAnnotation jetClassAnnotation = JetClassAnnotation.get(psiClass); JetClassAnnotation jetClassAnnotation = JetClassAnnotation.get(psiClass);
classData.kotlin = jetClassAnnotation.isDefined(); classData.kotlin = jetClassAnnotation.isDefined();
if (jetClassAnnotation.signature().length() > 0) { if (jetClassAnnotation.signature().length() > 0) {
return resolveClassTypeParametersFromJetSignature( return resolveClassTypeParametersFromJetSignature(
jetClassAnnotation.signature(), psiClass, classData.classDescriptor, typeVariableResolver); jetClassAnnotation.signature(), psiClass, classData.classDescriptor, typeVariableByNameResolver);
} }
return makeUninitializedTypeParameters(classData.classDescriptor, psiClass.getTypeParameters()); return makeUninitializedTypeParameters(classData.classDescriptor, psiClass.getTypeParameters());
@@ -380,10 +430,10 @@ public class JavaDescriptorResolver {
private final boolean reified; private final boolean reified;
private final int index; private final int index;
private final TypeInfoVariance variance; private final TypeInfoVariance variance;
private final TypeVariableResolver typeVariableResolver; private final TypeVariableByNameResolver typeVariableByNameResolver;
protected JetSignatureTypeParameterVisitor(DeclarationDescriptor containingDeclaration, PsiTypeParameterListOwner psiOwner, protected JetSignatureTypeParameterVisitor(DeclarationDescriptor containingDeclaration, PsiTypeParameterListOwner psiOwner,
String name, boolean reified, int index, TypeInfoVariance variance, TypeVariableResolver typeVariableResolver) String name, boolean reified, int index, TypeInfoVariance variance, TypeVariableByNameResolver typeVariableByNameResolver)
{ {
if (name.isEmpty()) { if (name.isEmpty()) {
throw new IllegalStateException(); throw new IllegalStateException();
@@ -395,7 +445,7 @@ public class JavaDescriptorResolver {
this.reified = reified; this.reified = reified;
this.index = index; this.index = index;
this.variance = variance; this.variance = variance;
this.typeVariableResolver = typeVariableResolver; this.typeVariableByNameResolver = typeVariableByNameResolver;
} }
List<JetType> upperBounds = new ArrayList<JetType>(); List<JetType> upperBounds = new ArrayList<JetType>();
@@ -403,7 +453,7 @@ public class JavaDescriptorResolver {
@Override @Override
public JetSignatureVisitor visitClassBound() { public JetSignatureVisitor visitClassBound() {
return new JetTypeJetSignatureReader(semanticServices, semanticServices.getJetSemanticServices().getStandardLibrary(), typeVariableResolver) { return new JetTypeJetSignatureReader(semanticServices, semanticServices.getJetSemanticServices().getStandardLibrary(), typeVariableByNameResolver) {
@Override @Override
protected void done(@NotNull JetType jetType) { protected void done(@NotNull JetType jetType) {
if (isJavaLangObject(jetType)) { if (isJavaLangObject(jetType)) {
@@ -416,7 +466,7 @@ public class JavaDescriptorResolver {
@Override @Override
public JetSignatureVisitor visitInterfaceBound() { public JetSignatureVisitor visitInterfaceBound() {
return new JetTypeJetSignatureReader(semanticServices, semanticServices.getJetSemanticServices().getStandardLibrary(), typeVariableResolver) { return new JetTypeJetSignatureReader(semanticServices, semanticServices.getJetSemanticServices().getStandardLibrary(), typeVariableByNameResolver) {
@Override @Override
protected void done(@NotNull JetType jetType) { protected void done(@NotNull JetType jetType) {
upperBounds.add(jetType); upperBounds.add(jetType);
@@ -434,31 +484,31 @@ public class JavaDescriptorResolver {
name, name,
index); index);
PsiTypeParameter psiTypeParameter = getPsiTypeParameterByName(psiOwner, name); PsiTypeParameter psiTypeParameter = getPsiTypeParameterByName(psiOwner, name);
typeParameterDescriptorCache.put(psiTypeParameter, new TypeParameterDescriptorInitialization(typeParameter, upperBounds, lowerBounds)); TypeParameterDescriptorInitialization typeParameterDescriptorInitialization = new TypeParameterDescriptorInitialization(typeParameter, psiTypeParameter, upperBounds, lowerBounds);
done(typeParameter); done(typeParameterDescriptorInitialization);
} }
protected abstract void done(TypeParameterDescriptor typeParameterDescriptor); protected abstract void done(@NotNull TypeParameterDescriptorInitialization typeParameterDescriptor);
} }
/** /**
* @see #resolveMethodTypeParametersFromJetSignature(String, FunctionDescriptor) * @see #resolveMethodTypeParametersFromJetSignature(String, FunctionDescriptor)
*/ */
private List<TypeParameterDescriptor> resolveClassTypeParametersFromJetSignature(String jetSignature, final PsiClass clazz, private List<TypeParameterDescriptorInitialization> resolveClassTypeParametersFromJetSignature(String jetSignature, final PsiClass clazz,
final ClassDescriptor classDescriptor, final TypeVariableResolver outerClassTypeVariableResolver) { final ClassDescriptor classDescriptor, final TypeVariableByNameResolver outerClassTypeVariableByNameResolver) {
final List<TypeParameterDescriptor> r = new ArrayList<TypeParameterDescriptor>(); final List<TypeParameterDescriptorInitialization> r = new ArrayList<TypeParameterDescriptorInitialization>();
class MyTypeVariableResolver implements TypeVariableResolver { class MyTypeVariableByNameResolver implements TypeVariableByNameResolver {
@NotNull @NotNull
@Override @Override
public TypeParameterDescriptor getTypeVariable(@NotNull String name) { public TypeParameterDescriptor getTypeVariable(@NotNull String name) {
for (TypeParameterDescriptor typeParameter : r) { for (TypeParameterDescriptorInitialization typeParameter : r) {
if (typeParameter.getName().equals(name)) { if (typeParameter.descriptor.getName().equals(name)) {
return typeParameter; return typeParameter.descriptor;
} }
} }
return outerClassTypeVariableResolver.getTypeVariable(name); return outerClassTypeVariableByNameResolver.getTypeVariable(name);
} }
} }
@@ -467,9 +517,9 @@ public class JavaDescriptorResolver {
@Override @Override
public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance, boolean reified) { public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance, boolean reified) {
return new JetSignatureTypeParameterVisitor(classDescriptor, clazz, name, reified, formalTypeParameterIndex++, variance, new MyTypeVariableResolver()) { return new JetSignatureTypeParameterVisitor(classDescriptor, clazz, name, reified, formalTypeParameterIndex++, variance, new MyTypeVariableByNameResolver()) {
@Override @Override
protected void done(TypeParameterDescriptor typeParameterDescriptor) { protected void done(TypeParameterDescriptorInitialization typeParameterDescriptor) {
r.add(typeParameterDescriptor); r.add(typeParameterDescriptor);
} }
}; };
@@ -501,18 +551,17 @@ public class JavaDescriptorResolver {
return resolveNamespace(packageName); return resolveNamespace(packageName);
} }
private List<TypeParameterDescriptor> makeUninitializedTypeParameters(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameter[] typeParameters) { private List<TypeParameterDescriptorInitialization> makeUninitializedTypeParameters(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameter[] typeParameters) {
List<TypeParameterDescriptor> result = Lists.newArrayList(); List<TypeParameterDescriptorInitialization> result = Lists.newArrayList();
for (PsiTypeParameter typeParameter : typeParameters) { for (PsiTypeParameter typeParameter : typeParameters) {
TypeParameterDescriptor typeParameterDescriptor = makeUninitializedTypeParameter(containingDeclaration, typeParameter); TypeParameterDescriptorInitialization typeParameterDescriptor = makeUninitializedTypeParameter(containingDeclaration, typeParameter);
result.add(typeParameterDescriptor); result.add(typeParameterDescriptor);
} }
return result; return result;
} }
@NotNull @NotNull
private TypeParameterDescriptor makeUninitializedTypeParameter(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameter psiTypeParameter) { private TypeParameterDescriptorInitialization makeUninitializedTypeParameter(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameter psiTypeParameter) {
assert typeParameterDescriptorCache.get(psiTypeParameter) == null : psiTypeParameter.getText();
TypeParameterDescriptor typeParameterDescriptor = TypeParameterDescriptor.createForFurtherModification( TypeParameterDescriptor typeParameterDescriptor = TypeParameterDescriptor.createForFurtherModification(
containingDeclaration, containingDeclaration,
Collections.<AnnotationDescriptor>emptyList(), // TODO Collections.<AnnotationDescriptor>emptyList(), // TODO
@@ -521,61 +570,52 @@ public class JavaDescriptorResolver {
psiTypeParameter.getName(), psiTypeParameter.getName(),
psiTypeParameter.getIndex() psiTypeParameter.getIndex()
); );
typeParameterDescriptorCache.put(psiTypeParameter, new TypeParameterDescriptorInitialization(typeParameterDescriptor)); return new TypeParameterDescriptorInitialization(typeParameterDescriptor, psiTypeParameter);
return typeParameterDescriptor;
} }
private void initializeTypeParameter(PsiTypeParameter typeParameter, TypeParameterDescriptorInitialization typeParameterDescriptorInitialization) { private void initializeTypeParameter(TypeParameterDescriptorInitialization typeParameter, TypeVariableByPsiResolver typeVariableByPsiResolver) {
TypeParameterDescriptor typeParameterDescriptor = typeParameterDescriptorInitialization.descriptor; TypeParameterDescriptor typeParameterDescriptor = typeParameter.descriptor;
if (typeParameterDescriptorInitialization.origin == TypeParameterDescriptorOrigin.KOTLIN) { if (typeParameter.origin == TypeParameterDescriptorOrigin.KOTLIN) {
List<?> upperBounds = typeParameterDescriptorInitialization.upperBoundsForKotlin; List<?> upperBounds = typeParameter.upperBoundsForKotlin;
if (upperBounds.size() == 0){ if (upperBounds.size() == 0){
typeParameterDescriptor.addUpperBound(JetStandardClasses.getNullableAnyType()); typeParameterDescriptor.addUpperBound(JetStandardClasses.getNullableAnyType());
} else { } else {
for (JetType upperBound : typeParameterDescriptorInitialization.upperBoundsForKotlin) { for (JetType upperBound : typeParameter.upperBoundsForKotlin) {
typeParameterDescriptor.addUpperBound(upperBound); typeParameterDescriptor.addUpperBound(upperBound);
} }
} }
// TODO: lower bounds // TODO: lower bounds
} else { } else {
PsiClassType[] referencedTypes = typeParameter.getExtendsList().getReferencedTypes(); PsiClassType[] referencedTypes = typeParameter.psiTypeParameter.getExtendsList().getReferencedTypes();
if (referencedTypes.length == 0){ if (referencedTypes.length == 0){
typeParameterDescriptor.addUpperBound(JetStandardClasses.getNullableAnyType()); typeParameterDescriptor.addUpperBound(JetStandardClasses.getNullableAnyType());
} }
else if (referencedTypes.length == 1) { else if (referencedTypes.length == 1) {
typeParameterDescriptor.addUpperBound(semanticServices.getTypeTransformer().transformToType(referencedTypes[0])); typeParameterDescriptor.addUpperBound(semanticServices.getTypeTransformer().transformToType(referencedTypes[0], typeVariableByPsiResolver));
} }
else { else {
for (PsiClassType referencedType : referencedTypes) { for (PsiClassType referencedType : referencedTypes) {
typeParameterDescriptor.addUpperBound(semanticServices.getTypeTransformer().transformToType(referencedType)); typeParameterDescriptor.addUpperBound(semanticServices.getTypeTransformer().transformToType(referencedType, typeVariableByPsiResolver));
} }
} }
} }
typeParameterDescriptor.setInitialized(); typeParameterDescriptor.setInitialized();
} }
private void initializeTypeParameters(PsiTypeParameterListOwner typeParameterListOwner) { private void initializeTypeParameters(List<TypeParameterDescriptorInitialization> typeParametersInitialization, TypeVariableResolver typeVariableByPsiResolver) {
for (PsiTypeParameter psiTypeParameter : typeParameterListOwner.getTypeParameters()) { List<TypeParameterDescriptorInitialization> prevTypeParameters = new ArrayList<TypeParameterDescriptorInitialization>();
initializeTypeParameter(psiTypeParameter, resolveTypeParameterInitialization(psiTypeParameter)); for (TypeParameterDescriptorInitialization psiTypeParameter : typeParametersInitialization) {
prevTypeParameters.add(psiTypeParameter);
initializeTypeParameter(psiTypeParameter, new TypeVariableResoverFromTypeDescriptorsInitialization(prevTypeParameters, typeVariableByPsiResolver));
} }
} }
@NotNull private Collection<? extends JetType> getSupertypes(PsiClassWrapper psiClass, List<TypeParameterDescriptorInitialization> typeParameters) {
private TypeParameterDescriptorInitialization resolveTypeParameter(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameter psiTypeParameter) {
TypeParameterDescriptorInitialization typeParameterDescriptor = typeParameterDescriptorCache.get(psiTypeParameter);
if (typeParameterDescriptor == null) {
// TODO: report properly without crashing compiler
throw new IllegalStateException("failed to resolve type parameter: " + psiTypeParameter.getName());
}
return typeParameterDescriptor;
}
private Collection<? extends JetType> getSupertypes(PsiClassWrapper psiClass, List<TypeParameterDescriptor> typeParameters) {
final List<JetType> result = new ArrayList<JetType>(); final List<JetType> result = new ArrayList<JetType>();
if (psiClass.getJetClass().signature().length() > 0) { if (psiClass.getJetClass().signature().length() > 0) {
final TypeParameterListTypeVariableResolver typeVariableResolver = new TypeParameterListTypeVariableResolver(typeParameters); final TypeVariableResolver typeVariableResolver = new TypeVariableResoverFromTypeDescriptorsInitialization(typeParameters, null);
new JetSignatureReader(psiClass.getJetClass().signature()).accept(new JetSignatureExceptionsAdapter() { new JetSignatureReader(psiClass.getJetClass().signature()).accept(new JetSignatureExceptionsAdapter() {
@Override @Override
@@ -609,8 +649,8 @@ public class JavaDescriptorResolver {
} }
}); });
} else { } else {
transformSupertypeList(result, psiClass.getPsiClass().getExtendsListTypes()); transformSupertypeList(result, psiClass.getPsiClass().getExtendsListTypes(), new TypeVariableResoverFromTypeDescriptorsInitialization(typeParameters, null));
transformSupertypeList(result, psiClass.getPsiClass().getImplementsListTypes()); transformSupertypeList(result, psiClass.getPsiClass().getImplementsListTypes(), new TypeVariableResoverFromTypeDescriptorsInitialization(typeParameters, null));
} }
if (result.isEmpty()) { if (result.isEmpty()) {
result.add(JetStandardClasses.getAnyType()); result.add(JetStandardClasses.getAnyType());
@@ -618,14 +658,14 @@ public class JavaDescriptorResolver {
return result; return result;
} }
private void transformSupertypeList(List<JetType> result, PsiClassType[] extendsListTypes) { private void transformSupertypeList(List<JetType> result, PsiClassType[] extendsListTypes, TypeVariableResolver typeVariableResolver) {
for (PsiClassType type : extendsListTypes) { for (PsiClassType type : extendsListTypes) {
PsiClass resolved = type.resolve(); PsiClass resolved = type.resolve();
if (resolved != null && resolved.getQualifiedName().equals(JvmStdlibNames.JET_OBJECT.getFqName())) { if (resolved != null && resolved.getQualifiedName().equals(JvmStdlibNames.JET_OBJECT.getFqName())) {
continue; continue;
} }
JetType transform = semanticServices.getTypeTransformer().transformToType(type); JetType transform = semanticServices.getTypeTransformer().transformToType(type, typeVariableResolver);
result.add(TypeUtils.makeNotNullable(transform)); result.add(TypeUtils.makeNotNullable(transform));
} }
@@ -817,7 +857,7 @@ public class JavaDescriptorResolver {
if (typeFromAnnotation.length() > 0) { if (typeFromAnnotation.length() > 0) {
outType = semanticServices.getTypeTransformer().transformToType(typeFromAnnotation, typeVariableResolver); outType = semanticServices.getTypeTransformer().transformToType(typeFromAnnotation, typeVariableResolver);
} else { } else {
outType = semanticServices.getTypeTransformer().transformToType(psiType); outType = semanticServices.getTypeTransformer().transformToType(psiType, typeVariableResolver);
} }
JetType varargElementType; JetType varargElementType;
@@ -843,7 +883,7 @@ public class JavaDescriptorResolver {
} }
} }
public Set<VariableDescriptor> resolveFieldGroupByName(@NotNull DeclarationDescriptor owner, PsiClass psiClass, String fieldName, boolean staticMembers) { public Set<VariableDescriptor> resolveFieldGroupByName(@NotNull ClassOrNamespaceDescriptor owner, PsiClass psiClass, String fieldName, boolean staticMembers) {
ResolverScopeData scopeData = getResolverScopeData(owner, new PsiClassWrapper(psiClass)); ResolverScopeData scopeData = getResolverScopeData(owner, new PsiClassWrapper(psiClass));
NamedMembers namedMembers = scopeData.namedMembersMap.get(fieldName); NamedMembers namedMembers = scopeData.namedMembersMap.get(fieldName);
@@ -851,13 +891,13 @@ public class JavaDescriptorResolver {
return Collections.emptySet(); return Collections.emptySet();
} }
resolveNamedGroupProperties(owner, staticMembers, namedMembers, fieldName); resolveNamedGroupProperties(owner, scopeData, staticMembers, namedMembers, fieldName);
return namedMembers.propertyDescriptors; return namedMembers.propertyDescriptors;
} }
@NotNull @NotNull
public Set<VariableDescriptor> resolveFieldGroup(@NotNull DeclarationDescriptor owner, PsiClass psiClass, boolean staticMembers) { public Set<VariableDescriptor> resolveFieldGroup(@NotNull ClassOrNamespaceDescriptor owner, PsiClass psiClass, boolean staticMembers) {
ResolverScopeData scopeData = getResolverScopeData(owner, new PsiClassWrapper(psiClass)); ResolverScopeData scopeData = getResolverScopeData(owner, new PsiClassWrapper(psiClass));
@@ -871,7 +911,7 @@ public class JavaDescriptorResolver {
String propertyName = entry.getKey(); String propertyName = entry.getKey();
resolveNamedGroupProperties(owner, staticMembers, namedMembers, propertyName); resolveNamedGroupProperties(owner, scopeData, staticMembers, namedMembers, propertyName);
descriptors.addAll(namedMembers.propertyDescriptors); descriptors.addAll(namedMembers.propertyDescriptors);
} }
return descriptors; return descriptors;
@@ -905,7 +945,10 @@ public class JavaDescriptorResolver {
return Pair.create(type, receiverType); return Pair.create(type, receiverType);
} }
private void resolveNamedGroupProperties(DeclarationDescriptor owner, boolean staticMembers, NamedMembers namedMembers, String propertyName) { private void resolveNamedGroupProperties(
@NotNull ClassOrNamespaceDescriptor owner,
@NotNull ResolverScopeData scopeData,
boolean staticMembers, NamedMembers namedMembers, String propertyName) {
if (namedMembers.propertyDescriptors != null) { if (namedMembers.propertyDescriptors != null) {
return; return;
} }
@@ -915,14 +958,14 @@ public class JavaDescriptorResolver {
return; return;
} }
final List<TypeParameterDescriptor> classTypeParameters; final List<TypeParameterDescriptorInitialization> classTypeParameterDescriptorInitialization;
if (!staticMembers) { if (scopeData instanceof ResolverBinaryClassData) {
classTypeParameters = ((ClassDescriptor) owner).getTypeConstructor().getParameters(); classTypeParameterDescriptorInitialization = ((ResolverBinaryClassData) scopeData).typeParameters;
} else { } else {
classTypeParameters = new ArrayList<TypeParameterDescriptor>(0); classTypeParameterDescriptorInitialization = new ArrayList<TypeParameterDescriptorInitialization>(0);
} }
TypeParameterListTypeVariableResolver typeVariableResolver = new TypeParameterListTypeVariableResolver(classTypeParameters); TypeVariableResolver typeVariableResolver = new TypeVariableResoverFromTypeDescriptorsInitialization(classTypeParameterDescriptorInitialization, null);
class GroupingValue { class GroupingValue {
PropertyAccessorData getter; PropertyAccessorData getter;
@@ -1015,33 +1058,38 @@ public class JavaDescriptorResolver {
propertyDescriptor.initialize(getterDescriptor, setterDescriptor); propertyDescriptor.initialize(getterDescriptor, setterDescriptor);
List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(0); List<TypeParameterDescriptorInitialization> typeParametersInitialization = new ArrayList<TypeParameterDescriptorInitialization>(0);
if (members.setter != null) { if (members.setter != null) {
PsiMethodWrapper method = (PsiMethodWrapper) members.setter.getMember(); PsiMethodWrapper method = (PsiMethodWrapper) members.setter.getMember();
if (anyMember == members.setter) { if (anyMember == members.setter) {
typeParameters = resolveMethodTypeParameters(method, setterDescriptor, typeVariableResolver); typeParametersInitialization = resolveMethodTypeParameters(method, setterDescriptor, typeVariableResolver);
} }
} }
if (members.getter != null) { if (members.getter != null) {
PsiMethodWrapper method = (PsiMethodWrapper) members.getter.getMember(); PsiMethodWrapper method = (PsiMethodWrapper) members.getter.getMember();
if (anyMember == members.getter) { if (anyMember == members.getter) {
typeParameters = resolveMethodTypeParameters(method, getterDescriptor, typeVariableResolver); typeParametersInitialization = resolveMethodTypeParameters(method, getterDescriptor, typeVariableResolver);
} }
} }
List<TypeParameterDescriptor> typeParametersForReceiver = new ArrayList<TypeParameterDescriptor>(); List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>();
typeParametersForReceiver.addAll(classTypeParameters); for (TypeParameterDescriptorInitialization typeParameter : typeParametersInitialization) {
typeParametersForReceiver.addAll(typeParameters); typeParameters.add(typeParameter.descriptor);
TypeVariableResolver typeVariableResolverForPropertyInternals = new TypeParameterListTypeVariableResolver(typeParametersForReceiver); }
List<TypeParameterDescriptorInitialization> typeParametersForReceiver = new ArrayList<TypeParameterDescriptorInitialization>();
typeParametersForReceiver.addAll(classTypeParameterDescriptorInitialization);
typeParametersForReceiver.addAll(typeParametersInitialization);
TypeVariableResolver typeVariableResolverForPropertyInternals = new TypeVariableResoverFromTypeDescriptorsInitialization(typeParametersForReceiver, null);
JetType propertyType; JetType propertyType;
if (anyMember.getType().getTypeString().length() > 0) { if (anyMember.getType().getTypeString().length() > 0) {
propertyType = semanticServices.getTypeTransformer().transformToType(anyMember.getType().getTypeString(), typeVariableResolverForPropertyInternals); propertyType = semanticServices.getTypeTransformer().transformToType(anyMember.getType().getTypeString(), typeVariableResolverForPropertyInternals);
} else { } else {
propertyType = semanticServices.getTypeTransformer().transformToType(anyMember.getType().getPsiType()); propertyType = semanticServices.getTypeTransformer().transformToType(anyMember.getType().getPsiType(), typeVariableResolverForPropertyInternals);
} }
JetType receiverType; JetType receiverType;
@@ -1050,7 +1098,7 @@ public class JavaDescriptorResolver {
} else if (anyMember.getReceiverType().getTypeString().length() > 0) { } else if (anyMember.getReceiverType().getTypeString().length() > 0) {
receiverType = semanticServices.getTypeTransformer().transformToType(anyMember.getReceiverType().getTypeString(), typeVariableResolverForPropertyInternals); receiverType = semanticServices.getTypeTransformer().transformToType(anyMember.getReceiverType().getTypeString(), typeVariableResolverForPropertyInternals);
} else { } else {
receiverType = semanticServices.getTypeTransformer().transformToType(anyMember.getReceiverType().getPsiType()); receiverType = semanticServices.getTypeTransformer().transformToType(anyMember.getReceiverType().getPsiType(), typeVariableResolverForPropertyInternals);
} }
propertyDescriptor.setType( propertyDescriptor.setType(
@@ -1074,7 +1122,7 @@ public class JavaDescriptorResolver {
namedMembers.propertyDescriptors = r; namedMembers.propertyDescriptors = r;
} }
private void resolveNamedGroupFunctions(DeclarationDescriptor owner, PsiClass psiClass, TypeSubstitutor typeSubstitutorForGenericSuperclasses, NamedMembers namedMembers) { private void resolveNamedGroupFunctions(ClassOrNamespaceDescriptor owner, PsiClass psiClass, TypeSubstitutor typeSubstitutorForGenericSuperclasses, NamedMembers namedMembers) {
if (namedMembers.functionDescriptors != null) { if (namedMembers.functionDescriptors != null) {
return; return;
} }
@@ -1094,7 +1142,7 @@ public class JavaDescriptorResolver {
namedMembers.functionDescriptors = functionDescriptors; namedMembers.functionDescriptors = functionDescriptors;
} }
private ResolverScopeData getResolverScopeData(DeclarationDescriptor owner, PsiClassWrapper psiClass) { private ResolverScopeData getResolverScopeData(ClassOrNamespaceDescriptor owner, PsiClassWrapper psiClass) {
ResolverScopeData scopeData; ResolverScopeData scopeData;
boolean staticMembers; boolean staticMembers;
if (owner instanceof JavaNamespaceDescriptor) { if (owner instanceof JavaNamespaceDescriptor) {
@@ -1118,8 +1166,7 @@ public class JavaDescriptorResolver {
} }
@NotNull @NotNull
public Set<FunctionDescriptor> resolveFunctionGroup(@NotNull DeclarationDescriptor descriptor, @NotNull PsiClass psiClass, public Set<FunctionDescriptor> resolveFunctionGroup(@NotNull ClassOrNamespaceDescriptor descriptor, @NotNull PsiClass psiClass, @NotNull String methodName, boolean staticMembers) {
@NotNull String methodName, boolean staticMembers) {
ResolverScopeData resolverScopeData = getResolverScopeData(descriptor, new PsiClassWrapper(psiClass)); ResolverScopeData resolverScopeData = getResolverScopeData(descriptor, new PsiClassWrapper(psiClass));
@@ -1152,28 +1199,30 @@ public class JavaDescriptorResolver {
return typeSubstitutor; return typeSubstitutor;
} }
private static class TypeParameterListTypeVariableResolver implements TypeVariableResolver { // this method won't be necessary as soon as we resolve only local methods
private void getAllTypeParameterDescriptorInitialization(PsiClass psiClass, List<TypeParameterDescriptorInitialization> dest) {
ResolverClassData classData = resolveClassData(psiClass);
private final List<TypeParameterDescriptor> typeParameters; if (classData instanceof ResolverSrcClassData) {
// TODO hack
private TypeParameterListTypeVariableResolver(List<TypeParameterDescriptor> typeParameters) { return;
this.typeParameters = typeParameters;
} }
@NotNull ResolverBinaryClassData binaryClassData = (ResolverBinaryClassData) classData;
@Override if (binaryClassData == null) {
public TypeParameterDescriptor getTypeVariable(@NotNull String name) { return;
for (TypeParameterDescriptor typeParameter : typeParameters) { }
if (typeParameter.getName().equals(name)) { if (binaryClassData.typeParameters == null) {
return typeParameter; throw new RuntimeException();
} }
} dest.addAll(binaryClassData.typeParameters);
throw new IllegalStateException("unresolver variable: " + name); // TODO: report properly for (PsiClass supr : psiClass.getSupers()) {
getAllTypeParameterDescriptorInitialization(supr, dest);
} }
} }
@Nullable @Nullable
private FunctionDescriptor resolveMethodToFunctionDescriptor(DeclarationDescriptor owner, PsiClass psiClass, TypeSubstitutor typeSubstitutorForGenericSuperclasses, PsiMethodWrapper method) { private FunctionDescriptor resolveMethodToFunctionDescriptor(ClassOrNamespaceDescriptor owner, PsiClass psiClass, TypeSubstitutor typeSubstitutorForGenericSuperclasses, PsiMethodWrapper method) {
PsiType returnType = method.getReturnType(); PsiType returnType = method.getReturnType();
if (returnType == null) { if (returnType == null) {
@@ -1187,6 +1236,8 @@ public class JavaDescriptorResolver {
return functionDescriptor; return functionDescriptor;
} }
ResolverScopeData scopeData = getResolverScopeData(owner, new PsiClassWrapper(psiClass));
boolean kotlin; boolean kotlin;
if (owner instanceof JavaNamespaceDescriptor) { if (owner instanceof JavaNamespaceDescriptor) {
JavaNamespaceDescriptor javaNamespaceDescriptor = (JavaNamespaceDescriptor) owner; JavaNamespaceDescriptor javaNamespaceDescriptor = (JavaNamespaceDescriptor) owner;
@@ -1196,7 +1247,7 @@ public class JavaDescriptorResolver {
} }
kotlin = namespaceData.kotlin; kotlin = namespaceData.kotlin;
} else { } else {
ResolverClassData classData = classDescriptorCache.get(psiClass.getQualifiedName()); ResolverBinaryClassData classData = classDescriptorCache.get(psiClass.getQualifiedName());
if (classData == null) { if (classData == null) {
throw new IllegalStateException("classData not found by name " + psiClass.getQualifiedName()); throw new IllegalStateException("classData not found by name " + psiClass.getQualifiedName());
} }
@@ -1231,14 +1282,19 @@ public class JavaDescriptorResolver {
DeclarationDescriptor classDescriptor; DeclarationDescriptor classDescriptor;
final List<TypeParameterDescriptor> classTypeParameters; final List<TypeParameterDescriptor> classTypeParameters;
if (method.isStatic()) { final List<TypeParameterDescriptorInitialization> classTypeParameterDescriptorsInitialization;
classDescriptor = resolveNamespace(method.getPsiMethod().getContainingClass()); if (scopeData instanceof ResolverBinaryClassData) {
classTypeParameters = Collections.emptyList();
}
else {
ClassDescriptor classClassDescriptor = resolveClass(method.getPsiMethod().getContainingClass()); ClassDescriptor classClassDescriptor = resolveClass(method.getPsiMethod().getContainingClass());
classDescriptor = classClassDescriptor; classDescriptor = classClassDescriptor;
classTypeParameters = classClassDescriptor.getTypeConstructor().getParameters(); classTypeParameters = classClassDescriptor.getTypeConstructor().getParameters();
classTypeParameterDescriptorsInitialization = new ArrayList<TypeParameterDescriptorInitialization>();
getAllTypeParameterDescriptorInitialization(psiClass, classTypeParameterDescriptorsInitialization);
//classTypeParameterDescriptorsInitialization = ((ResolverClassData) scopeData).typeParameters;
}
else {
classDescriptor = resolveNamespace(method.getPsiMethod().getContainingClass());
classTypeParameters = new ArrayList<TypeParameterDescriptor>(0);
classTypeParameterDescriptorsInitialization = new ArrayList<TypeParameterDescriptorInitialization>(0);
} }
if (classDescriptor == null) { if (classDescriptor == null) {
return null; return null;
@@ -1251,18 +1307,37 @@ public class JavaDescriptorResolver {
methodDescriptorCache.put(method.getPsiMethod(), functionDescriptorImpl); methodDescriptorCache.put(method.getPsiMethod(), functionDescriptorImpl);
// TODO: add outer classes // TODO: add outer classes
TypeParameterListTypeVariableResolver typeVariableResolverForParameters = new TypeParameterListTypeVariableResolver(classTypeParameters); TypeVariableResolver typeVariableResolverForParameters = new TypeVariableResoverFromTypeDescriptorsInitialization(classTypeParameterDescriptorsInitialization, null);
final List<TypeParameterDescriptor> methodTypeParameters = resolveMethodTypeParameters(method, functionDescriptorImpl, typeVariableResolverForParameters); final List<TypeParameterDescriptorInitialization> methodTypeParametersInitialization = resolveMethodTypeParameters(method, functionDescriptorImpl, typeVariableResolverForParameters);
List<TypeParameterDescriptor> methodTypeParameters = new ArrayList<TypeParameterDescriptor>();
for (TypeParameterDescriptorInitialization typeParameterDescriptorInitialization : methodTypeParametersInitialization) {
methodTypeParameters.add(typeParameterDescriptorInitialization.descriptor);
}
class MethodTypeVariableResolver implements TypeVariableResolver { class MethodTypeVariableResolver implements TypeVariableResolver {
@NotNull
@Override
public TypeParameterDescriptor getTypeVariable(@NotNull PsiTypeParameter psiTypeParameter) {
for (TypeParameterDescriptorInitialization typeParameter : methodTypeParametersInitialization) {
if (typeParameter.psiTypeParameter == psiTypeParameter) {
return typeParameter.descriptor;
}
}
for (TypeParameterDescriptorInitialization typeParameter : classTypeParameterDescriptorsInitialization) {
if (typeParameter.psiTypeParameter == psiTypeParameter) {
return typeParameter.descriptor;
}
}
throw new IllegalStateException("unresolved PsiTypeParameter: " + psiTypeParameter.getName()); // TODO: report properly
}
@NotNull @NotNull
@Override @Override
public TypeParameterDescriptor getTypeVariable(@NotNull String name) { public TypeParameterDescriptor getTypeVariable(@NotNull String name) {
for (TypeParameterDescriptor typeParameter : methodTypeParameters) { for (TypeParameterDescriptorInitialization typeParameter : methodTypeParametersInitialization) {
if (typeParameter.getName().equals(name)) { if (typeParameter.descriptor.getName().equals(name)) {
return typeParameter; return typeParameter.descriptor;
} }
} }
for (TypeParameterDescriptor typeParameter : classTypeParameters) { for (TypeParameterDescriptor typeParameter : classTypeParameters) {
@@ -1272,6 +1347,7 @@ public class JavaDescriptorResolver {
} }
throw new IllegalStateException("unresolver variable: " + name); // TODO: report properly throw new IllegalStateException("unresolver variable: " + name); // TODO: report properly
} }
} }
@@ -1293,12 +1369,12 @@ public class JavaDescriptorResolver {
return substitutedFunctionDescriptor; return substitutedFunctionDescriptor;
} }
public List<FunctionDescriptor> resolveMethods(PsiClass psiClass, DeclarationDescriptor containingDeclaration) { public List<FunctionDescriptor> resolveMethods(PsiClass psiClass, ClassOrNamespaceDescriptor containingDeclaration) {
ResolverScopeData scopeData = getResolverScopeData(containingDeclaration, new PsiClassWrapper(psiClass)); ResolverScopeData scopeData = getResolverScopeData(containingDeclaration, new PsiClassWrapper(psiClass));
TypeSubstitutor substitutorForGenericSupertypes; TypeSubstitutor substitutorForGenericSupertypes;
if (scopeData instanceof ResolverClassData) { if (scopeData instanceof ResolverBinaryClassData) {
substitutorForGenericSupertypes = createSubstitutorForGenericSupertypes(((ResolverClassData) scopeData).classDescriptor); substitutorForGenericSupertypes = createSubstitutorForGenericSupertypes(((ResolverBinaryClassData) scopeData).classDescriptor);
} else { } else {
substitutorForGenericSupertypes = TypeSubstitutor.EMPTY; substitutorForGenericSupertypes = TypeSubstitutor.EMPTY;
} }
@@ -1313,41 +1389,42 @@ public class JavaDescriptorResolver {
return functions; return functions;
} }
private List<TypeParameterDescriptor> resolveMethodTypeParameters( private List<TypeParameterDescriptorInitialization> resolveMethodTypeParameters(
@NotNull PsiMethodWrapper method, @NotNull PsiMethodWrapper method,
@NotNull DeclarationDescriptor functionDescriptor, @NotNull DeclarationDescriptor functionDescriptor,
@NotNull TypeVariableResolver classTypeVariableResolver) { @NotNull TypeVariableResolver classTypeVariableResolver
) {
List<TypeParameterDescriptorInitialization> typeParameters;
if (method.getJetMethod().typeParameters().length() > 0) { if (method.getJetMethod().typeParameters().length() > 0) {
List<TypeParameterDescriptor> r = resolveMethodTypeParametersFromJetSignature( typeParameters = resolveMethodTypeParametersFromJetSignature(
method.getJetMethod().typeParameters(), method.getPsiMethod(), functionDescriptor, classTypeVariableResolver); method.getJetMethod().typeParameters(), method.getPsiMethod(), functionDescriptor, classTypeVariableResolver);
initializeTypeParameters(method.getPsiMethod()); } else {
return r; typeParameters = makeUninitializedTypeParameters(functionDescriptor, method.getPsiMethod().getTypeParameters());
} }
List<TypeParameterDescriptor> typeParameters = makeUninitializedTypeParameters(functionDescriptor, method.getPsiMethod().getTypeParameters()); initializeTypeParameters(typeParameters, classTypeVariableResolver);
initializeTypeParameters(method.getPsiMethod());
return typeParameters; return typeParameters;
} }
/** /**
* @see #resolveClassTypeParametersFromJetSignature(String, com.intellij.psi.PsiClass, MutableClassDescriptorLite) * @see #resolveClassTypeParametersFromJetSignature(String, com.intellij.psi.PsiClass, MutableClassDescriptorLite)
*/ */
private List<TypeParameterDescriptor> resolveMethodTypeParametersFromJetSignature(String jetSignature, final PsiMethod method, private List<TypeParameterDescriptorInitialization> resolveMethodTypeParametersFromJetSignature(String jetSignature, final PsiMethod method,
final DeclarationDescriptor functionDescriptor, final TypeVariableResolver classTypeVariableResolver) final DeclarationDescriptor functionDescriptor, final TypeVariableByNameResolver classTypeVariableByNameResolver)
{ {
final List<TypeParameterDescriptor> r = new ArrayList<TypeParameterDescriptor>(); final List<TypeParameterDescriptorInitialization> r = new ArrayList<TypeParameterDescriptorInitialization>();
class MyTypeVariableResolver implements TypeVariableResolver { class MyTypeVariableByNameResolver implements TypeVariableByNameResolver {
@NotNull @NotNull
@Override @Override
public TypeParameterDescriptor getTypeVariable(@NotNull String name) { public TypeParameterDescriptor getTypeVariable(@NotNull String name) {
for (TypeParameterDescriptor typeParameter : r) { for (TypeParameterDescriptorInitialization typeParameter : r) {
if (typeParameter.getName().equals(name)) { if (typeParameter.descriptor.getName().equals(name)) {
return typeParameter; return typeParameter.descriptor;
} }
} }
return classTypeVariableResolver.getTypeVariable(name); return classTypeVariableByNameResolver.getTypeVariable(name);
} }
} }
@@ -1357,9 +1434,9 @@ public class JavaDescriptorResolver {
@Override @Override
public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance, boolean reified) { public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance, boolean reified) {
return new JetSignatureTypeParameterVisitor(functionDescriptor, method, name, reified, formalTypeParameterIndex++, variance, new MyTypeVariableResolver()) { return new JetSignatureTypeParameterVisitor(functionDescriptor, method, name, reified, formalTypeParameterIndex++, variance, new MyTypeVariableByNameResolver()) {
@Override @Override
protected void done(TypeParameterDescriptor typeParameterDescriptor) { protected void done(TypeParameterDescriptorInitialization typeParameterDescriptor) {
r.add(typeParameterDescriptor); r.add(typeParameterDescriptor);
} }
}; };
@@ -1369,7 +1446,8 @@ public class JavaDescriptorResolver {
return r; return r;
} }
private JetType makeReturnType(PsiType returnType, PsiMethodWrapper method, TypeVariableResolver typeVariableResolver) { private JetType makeReturnType(PsiType returnType, PsiMethodWrapper method,
@NotNull TypeVariableResolver typeVariableResolver) {
String returnTypeFromAnnotation = method.getJetMethod().returnType(); String returnTypeFromAnnotation = method.getJetMethod().returnType();
@@ -1377,7 +1455,7 @@ public class JavaDescriptorResolver {
if (returnTypeFromAnnotation.length() > 0) { if (returnTypeFromAnnotation.length() > 0) {
transformedType = semanticServices.getTypeTransformer().transformToType(returnTypeFromAnnotation, typeVariableResolver); transformedType = semanticServices.getTypeTransformer().transformToType(returnTypeFromAnnotation, typeVariableResolver);
} else { } else {
transformedType = semanticServices.getTypeTransformer().transformToType(returnType); transformedType = semanticServices.getTypeTransformer().transformToType(returnType, typeVariableResolver);
} }
if (method.getJetMethod().returnTypeNullable()) { if (method.getJetMethod().returnTypeNullable()) {
return TypeUtils.makeNullableAsSpecified(transformedType, true); return TypeUtils.makeNullableAsSpecified(transformedType, true);
@@ -1393,41 +1471,14 @@ public class JavaDescriptorResolver {
(modifierListOwner.hasModifierProperty(PsiModifier.PROTECTED) ? Visibility.PROTECTED : Visibility.INTERNAL)); (modifierListOwner.hasModifierProperty(PsiModifier.PROTECTED) ? Visibility.PROTECTED : Visibility.INTERNAL));
} }
@NotNull
private TypeParameterDescriptorInitialization resolveTypeParameterInitialization(PsiTypeParameter typeParameter) {
PsiTypeParameterListOwner owner = typeParameter.getOwner();
if (owner instanceof PsiClass) {
PsiClass psiClass = (PsiClass) owner;
return resolveTypeParameter(resolveClass(psiClass), typeParameter);
}
if (owner instanceof PsiMethod) {
PsiMethod psiMethod = (PsiMethod) owner;
PsiClass containingClass = psiMethod.getContainingClass();
DeclarationDescriptor ownerOwner;
TypeSubstitutor substitutorForGenericSupertypes;
if (psiMethod.hasModifierProperty(PsiModifier.STATIC)) {
substitutorForGenericSupertypes = TypeSubstitutor.EMPTY;
return resolveTypeParameter(JAVA_METHOD_TYPE_PARAMETER_PARENT, typeParameter);
}
else {
ClassDescriptor classDescriptor = resolveClass(containingClass);
ownerOwner = classDescriptor;
substitutorForGenericSupertypes = semanticServices.getDescriptorResolver().createSubstitutorForGenericSupertypes(classDescriptor);
}
FunctionDescriptor functionDescriptor = resolveMethodToFunctionDescriptor(ownerOwner, containingClass, substitutorForGenericSupertypes, new PsiMethodWrapper(psiMethod));
return resolveTypeParameter(functionDescriptor, typeParameter);
}
throw new IllegalStateException("Unknown parent type: " + owner);
}
public TypeParameterDescriptor resolveTypeParameter(PsiTypeParameter typeParameter) {
return resolveTypeParameterInitialization(typeParameter).descriptor;
}
public List<ClassDescriptor> resolveInnerClasses(DeclarationDescriptor owner, PsiClass psiClass, boolean staticMembers) { public List<ClassDescriptor> resolveInnerClasses(DeclarationDescriptor owner, PsiClass psiClass, boolean staticMembers) {
PsiClass[] innerPsiClasses = psiClass.getInnerClasses(); PsiClass[] innerPsiClasses = psiClass.getInnerClasses();
List<ClassDescriptor> r = new ArrayList<ClassDescriptor>(innerPsiClasses.length); List<ClassDescriptor> r = new ArrayList<ClassDescriptor>(innerPsiClasses.length);
for (PsiClass innerPsiClass : innerPsiClasses) { for (PsiClass innerPsiClass : innerPsiClasses) {
if (innerPsiClass.hasModifierProperty(PsiModifier.PRIVATE)) {
// TODO: hack against inner classes
continue;
}
r.add(resolveClass(innerPsiClass)); r.add(resolveClass(innerPsiClass));
} }
return r; return r;
@@ -22,7 +22,7 @@ public class JavaPackageScope extends JavaClassOrPackageScope {
public JavaPackageScope( public JavaPackageScope(
@NotNull String packageFQN, @NotNull String packageFQN,
@NotNull DeclarationDescriptor containingDescriptor, @NotNull NamespaceDescriptor containingDescriptor,
@NotNull JavaSemanticServices semanticServices) { @NotNull JavaSemanticServices semanticServices) {
super(containingDescriptor, semanticServices); super(containingDescriptor, semanticServices);
this.packageFQN = packageFQN; this.packageFQN = packageFQN;
@@ -33,7 +33,9 @@ public class JavaTypeTransformer {
} }
@NotNull @NotNull
public TypeProjection transformToTypeProjection(@NotNull final PsiType javaType, @NotNull final TypeParameterDescriptor typeParameterDescriptor) { public TypeProjection transformToTypeProjection(@NotNull final PsiType javaType,
@NotNull final TypeParameterDescriptor typeParameterDescriptor,
@NotNull final TypeVariableByPsiResolver typeVariableByPsiResolver) {
TypeProjection result = javaType.accept(new PsiTypeVisitor<TypeProjection>() { TypeProjection result = javaType.accept(new PsiTypeVisitor<TypeProjection>() {
@Override @Override
@@ -50,21 +52,21 @@ public class JavaTypeTransformer {
PsiType bound = wildcardType.getBound(); PsiType bound = wildcardType.getBound();
assert bound != null; assert bound != null;
return new TypeProjection(variance, transformToType(bound)); return new TypeProjection(variance, transformToType(bound, typeVariableByPsiResolver));
} }
@Override @Override
public TypeProjection visitType(PsiType type) { public TypeProjection visitType(PsiType type) {
return new TypeProjection(transformToType(type)); return new TypeProjection(transformToType(type, typeVariableByPsiResolver));
} }
}); });
return result; return result;
} }
@NotNull @NotNull
public JetType transformToType(@NotNull String kotlinSignature, TypeVariableResolver typeVariableResolver) { public JetType transformToType(@NotNull String kotlinSignature, TypeVariableByNameResolver typeVariableByNameResolver) {
final JetType[] r = new JetType[1]; final JetType[] r = new JetType[1];
JetTypeJetSignatureReader reader = new JetTypeJetSignatureReader(javaSemanticServices, standardLibrary, typeVariableResolver) { JetTypeJetSignatureReader reader = new JetTypeJetSignatureReader(javaSemanticServices, standardLibrary, typeVariableByNameResolver) {
@Override @Override
protected void done(@NotNull JetType jetType) { protected void done(@NotNull JetType jetType) {
r[0] = jetType; r[0] = jetType;
@@ -75,7 +77,8 @@ public class JavaTypeTransformer {
} }
@NotNull @NotNull
public JetType transformToType(@NotNull PsiType javaType) { public JetType transformToType(@NotNull PsiType javaType,
@NotNull final TypeVariableByPsiResolver typeVariableByPsiResolver) {
return javaType.accept(new PsiTypeVisitor<JetType>() { return javaType.accept(new PsiTypeVisitor<JetType>() {
@Override @Override
public JetType visitClassType(PsiClassType classType) { public JetType visitClassType(PsiClassType classType) {
@@ -87,7 +90,7 @@ public class JavaTypeTransformer {
if (psiClass instanceof PsiTypeParameter) { if (psiClass instanceof PsiTypeParameter) {
PsiTypeParameter typeParameter = (PsiTypeParameter) psiClass; PsiTypeParameter typeParameter = (PsiTypeParameter) psiClass;
TypeParameterDescriptor typeParameterDescriptor = resolver.resolveTypeParameter(typeParameter); TypeParameterDescriptor typeParameterDescriptor = typeVariableByPsiResolver.getTypeVariable(typeParameter);
// return TypeUtils.makeNullable(typeParameterDescriptor.getDefaultType()); // return TypeUtils.makeNullable(typeParameterDescriptor.getDefaultType());
return typeParameterDescriptor.getDefaultType(); return typeParameterDescriptor.getDefaultType();
} }
@@ -97,34 +100,65 @@ public class JavaTypeTransformer {
return jetAnalog; return jetAnalog;
} }
ClassDescriptor descriptor = resolver.resolveClass(psiClass); final JavaDescriptorResolver.ResolverClassData classData = resolver.resolveClassData(psiClass);
if (descriptor == null) { if (classData == null) {
return ErrorUtils.createErrorType("Unresolve java class: " + classType.getPresentableText()); return ErrorUtils.createErrorType("Unresolve java class: " + classType.getPresentableText());
} }
List<TypeProjection> arguments = Lists.newArrayList(); List<TypeProjection> arguments = Lists.newArrayList();
if (classType.isRaw()) { if (classType.isRaw()) {
List<TypeParameterDescriptor> parameters = descriptor.getTypeConstructor().getParameters(); List<TypeParameterDescriptor> parameters = classData.getClassDescriptor().getTypeConstructor().getParameters();
for (TypeParameterDescriptor parameter : parameters) { for (TypeParameterDescriptor parameter : parameters) {
arguments.add(TypeUtils.makeStarProjection(parameter)); arguments.add(TypeUtils.makeStarProjection(parameter));
} }
} }
else { else {
List<TypeParameterDescriptor> parameters = descriptor.getTypeConstructor().getParameters(); List<TypeParameterDescriptor> parameters = classData.getClassDescriptor().getTypeConstructor().getParameters();
PsiType[] psiArguments = classType.getParameters(); PsiType[] psiArguments = classType.getParameters();
if (parameters.size() != psiArguments.length) {
throw new IllegalStateException();
}
for (int i = 0; i < parameters.size(); i++) { for (int i = 0; i < parameters.size(); i++) {
PsiType psiArgument = psiArguments[i]; PsiType psiArgument = psiArguments[i];
TypeParameterDescriptor typeParameterDescriptor = parameters.get(i); TypeParameterDescriptor typeParameterDescriptor = parameters.get(i);
arguments.add(transformToTypeProjection(psiArgument, typeParameterDescriptor)); TypeVariableResolver typeVariableByPsiResolver2 = new TypeVariableResolver() {
@NotNull
@Override
public TypeParameterDescriptor getTypeVariable(@NotNull String name) {
throw new RuntimeException(); // TODO
}
@NotNull
@Override
public TypeParameterDescriptor getTypeVariable(@NotNull PsiTypeParameter psiTypeParameter) {
if (classData instanceof JavaDescriptorResolver.ResolverSrcClassData) {
// hack for TypeInfoImpl
for (TypeParameterDescriptor typeParameter : classData.getClassDescriptor().getTypeConstructor().getParameters()) {
if (psiTypeParameter.getName().equals(typeParameter.getName())) {
// TODO?
return typeParameter;
}
}
throw new IllegalStateException();
} else if (classData instanceof JavaDescriptorResolver.ResolverBinaryClassData) {
return new TypeVariableByPsiResolverImpl(((JavaDescriptorResolver.ResolverBinaryClassData) classData).typeParameters, typeVariableByPsiResolver).getTypeVariable(psiTypeParameter);
} else {
throw new IllegalStateException();
}
}
};
arguments.add(transformToTypeProjection(psiArgument, typeParameterDescriptor, typeVariableByPsiResolver2));
} }
} }
return new JetTypeImpl( return new JetTypeImpl(
Collections.<AnnotationDescriptor>emptyList(), Collections.<AnnotationDescriptor>emptyList(),
descriptor.getTypeConstructor(), classData.getClassDescriptor().getTypeConstructor(),
true, true,
arguments, arguments,
descriptor.getMemberScope(arguments)); classData.getClassDescriptor().getMemberScope(arguments));
} }
} }
@@ -145,7 +179,7 @@ public class JavaTypeTransformer {
return TypeUtils.makeNullable(jetType); return TypeUtils.makeNullable(jetType);
} }
JetType type = transformToType(componentType); JetType type = transformToType(componentType, typeVariableByPsiResolver);
return TypeUtils.makeNullable(standardLibrary.getArrayType(type)); return TypeUtils.makeNullable(standardLibrary.getArrayType(type));
} }
@@ -28,13 +28,13 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd
private final JavaSemanticServices javaSemanticServices; private final JavaSemanticServices javaSemanticServices;
private final JavaDescriptorResolver javaDescriptorResolver; private final JavaDescriptorResolver javaDescriptorResolver;
private final JetStandardLibrary jetStandardLibrary; private final JetStandardLibrary jetStandardLibrary;
private final TypeVariableResolver typeVariableResolver; private final TypeVariableByNameResolver typeVariableByNameResolver;
public JetTypeJetSignatureReader(JavaSemanticServices javaSemanticServices, JetStandardLibrary jetStandardLibrary, TypeVariableResolver typeVariableResolver) { public JetTypeJetSignatureReader(JavaSemanticServices javaSemanticServices, JetStandardLibrary jetStandardLibrary, TypeVariableByNameResolver typeVariableByNameResolver) {
this.javaSemanticServices = javaSemanticServices; this.javaSemanticServices = javaSemanticServices;
this.javaDescriptorResolver = javaSemanticServices.getDescriptorResolver(); this.javaDescriptorResolver = javaSemanticServices.getDescriptorResolver();
this.jetStandardLibrary = jetStandardLibrary; this.jetStandardLibrary = jetStandardLibrary;
this.typeVariableResolver = typeVariableResolver; this.typeVariableByNameResolver = typeVariableByNameResolver;
} }
@@ -122,7 +122,7 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd
@Override @Override
public JetSignatureVisitor visitTypeArgument(final JetSignatureVariance variance) { public JetSignatureVisitor visitTypeArgument(final JetSignatureVariance variance) {
return new JetTypeJetSignatureReader(javaSemanticServices, jetStandardLibrary, typeVariableResolver) { return new JetTypeJetSignatureReader(javaSemanticServices, jetStandardLibrary, typeVariableByNameResolver) {
@Override @Override
protected void done(@NotNull JetType jetType) { protected void done(@NotNull JetType jetType) {
@@ -133,7 +133,7 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd
@Override @Override
public JetSignatureVisitor visitArrayType(final boolean nullable) { public JetSignatureVisitor visitArrayType(final boolean nullable) {
return new JetTypeJetSignatureReader(javaSemanticServices, jetStandardLibrary, typeVariableResolver) { return new JetTypeJetSignatureReader(javaSemanticServices, jetStandardLibrary, typeVariableByNameResolver) {
@Override @Override
public void visitBaseType(char descriptor, boolean nullable) { public void visitBaseType(char descriptor, boolean nullable) {
JetType primitiveType = getPrimitiveType(descriptor, nullable); JetType primitiveType = getPrimitiveType(descriptor, nullable);
@@ -156,7 +156,7 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd
@Override @Override
public void visitTypeVariable(String name, boolean nullable) { public void visitTypeVariable(String name, boolean nullable) {
JetType r = TypeUtils.makeNullableAsSpecified(typeVariableResolver.getTypeVariable(name).getDefaultType(), nullable); JetType r = TypeUtils.makeNullableAsSpecified(typeVariableByNameResolver.getTypeVariable(name).getDefaultType(), nullable);
done(r); done(r);
} }
@@ -0,0 +1,14 @@
package org.jetbrains.jet.lang.resolve.java;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
/**
* @author Stepan Koltsov
*
* @see TypeVariableByPsiResolver
*/
public interface TypeVariableByNameResolver {
@NotNull
TypeParameterDescriptor getTypeVariable(@NotNull String name);
}
@@ -0,0 +1,15 @@
package org.jetbrains.jet.lang.resolve.java;
import com.intellij.psi.PsiTypeParameter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
/**
* @author Stepan Koltsov
*
* @see TypeVariableByNameResolver
*/
public interface TypeVariableByPsiResolver {
@NotNull
TypeParameterDescriptor getTypeVariable(@NotNull PsiTypeParameter psiTypeParameter);
}
@@ -0,0 +1,39 @@
package org.jetbrains.jet.lang.resolve.java;
import com.intellij.psi.PsiTypeParameter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import java.util.List;
/**
* @author Stepan Koltsov
*/
public class TypeVariableByPsiResolverImpl implements TypeVariableByPsiResolver {
@NotNull
private final List<JavaDescriptorResolver.TypeParameterDescriptorInitialization> typeParameters;
@Nullable
private final TypeVariableByPsiResolver parent;
public TypeVariableByPsiResolverImpl(@NotNull List<JavaDescriptorResolver.TypeParameterDescriptorInitialization> typeParameters, TypeVariableByPsiResolver parent) {
this.typeParameters = typeParameters;
this.parent = parent;
}
@NotNull
@Override
public TypeParameterDescriptor getTypeVariable(@NotNull PsiTypeParameter psiTypeParameter) {
for (JavaDescriptorResolver.TypeParameterDescriptorInitialization typeParameter : typeParameters) {
if (typeParameter.psiTypeParameter == psiTypeParameter) {
return typeParameter.descriptor;
}
}
if (parent != null) {
return parent.getTypeVariable(psiTypeParameter);
}
throw new RuntimeException("type parameter not found by PsiTypeParameter " + psiTypeParameter.getName()); // TODO report properly
}
}
@@ -1,12 +1,7 @@
package org.jetbrains.jet.lang.resolve.java; package org.jetbrains.jet.lang.resolve.java;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
/** /**
* @author Stepan Koltsov * @author Stepan Koltsov
*/ */
public interface TypeVariableResolver { public interface TypeVariableResolver extends TypeVariableByPsiResolver, TypeVariableByNameResolver {
@NotNull
TypeParameterDescriptor getTypeVariable(@NotNull String name);
} }
@@ -0,0 +1,38 @@
package org.jetbrains.jet.lang.resolve.java;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import java.util.List;
/**
* @author Stepan Koltsov
*/
public class TypeVariableResoverFromTypeDescriptorsInitialization extends TypeVariableByPsiResolverImpl implements TypeVariableResolver {
@NotNull
private final List<JavaDescriptorResolver.TypeParameterDescriptorInitialization> typeParameters;
@Nullable
private final TypeVariableResolver parent;
public TypeVariableResoverFromTypeDescriptorsInitialization(@NotNull List<JavaDescriptorResolver.TypeParameterDescriptorInitialization> typeParameters, @Nullable TypeVariableResolver parent) {
super(typeParameters, parent);
this.typeParameters = typeParameters;
this.parent = parent;
}
@NotNull
@Override
public TypeParameterDescriptor getTypeVariable(@NotNull String name) {
for (JavaDescriptorResolver.TypeParameterDescriptorInitialization typeParameter : typeParameters) {
if (typeParameter.descriptor.getName().equals(name)) {
return typeParameter.descriptor;
}
}
if (parent != null) {
return parent.getTypeVariable(name);
}
throw new RuntimeException("type parameter not found by name " + name); // TODO report properly
}
}
@@ -15,7 +15,7 @@ import java.util.Set;
/** /**
* @author abreslav * @author abreslav
*/ */
public interface ClassDescriptor extends ClassifierDescriptor, MemberDescriptor { public interface ClassDescriptor extends ClassifierDescriptor, MemberDescriptor, ClassOrNamespaceDescriptor {
@NotNull @NotNull
JetScope getMemberScope(List<TypeProjection> typeArguments); JetScope getMemberScope(List<TypeProjection> typeArguments);
@@ -0,0 +1,7 @@
package org.jetbrains.jet.lang.descriptors;
/**
* @author Stepan Koltsov
*/
public interface ClassOrNamespaceDescriptor extends DeclarationDescriptor {
}
@@ -8,7 +8,7 @@ import org.jetbrains.jet.lang.types.NamespaceType;
/** /**
* @author abreslav * @author abreslav
*/ */
public interface NamespaceDescriptor extends Annotated, Named, DeclarationDescriptor { public interface NamespaceDescriptor extends Annotated, Named, ClassOrNamespaceDescriptor {
@NotNull @NotNull
JetScope getMemberScope(); JetScope getMemberScope();
@@ -0,0 +1,4 @@
package test;
final class ClassWithTypeParameter<P> {
}
@@ -0,0 +1,4 @@
package test
class ClassWithTypeParameter<erased P>() {
}
@@ -0,0 +1,4 @@
package test;
abstract class ClassTypeTypePRefSuper<P> implements java.lang.Iterable<P> {
}
@@ -0,0 +1,4 @@
package test
abstract class ClassTypeTypePRefSuper<erased P>() : java.lang.Iterable<P> {
}
@@ -0,0 +1,4 @@
package test;
final class ClassWithTypeParameter<P, Q extends P> {
}
@@ -0,0 +1,4 @@
package test
class ClassWithTypeParameter<erased P, erased Q : P>() {
}
@@ -0,0 +1,4 @@
package test;
final class ClassWithTypePRefSelf<P extends Enum<P>> {
}
@@ -0,0 +1,4 @@
package test
class ClassWithTypePRefSelf<erased P : java.lang.Enum<P>?>() {
}
@@ -0,0 +1,5 @@
package test;
final class MethodWithTypeP {
public final <P> void f() {}
}
@@ -0,0 +1,5 @@
package test
class MethodWithTypeP() {
fun <erased P> f() = #()
}
@@ -0,0 +1,5 @@
package test;
final class MethodWithTypePP {
public final <P, Q extends P> void f() {}
}
@@ -0,0 +1,5 @@
package test
class MethodWithTypePP() {
fun <erased P, erased Q : P> f() = #()
}
@@ -0,0 +1,5 @@
package test;
class MethodWithTypePRefClassP<P> {
public final <Q extends P> void f() {}
}
@@ -0,0 +1,5 @@
package test
open class MethodWithTypePRefClassP<erased P>() {
fun <erased Q : P> f() = #()
}
@@ -0,0 +1,5 @@
package test;
final class MethosWithPRefTP {
public final <P> void f(P p) {}
}
@@ -0,0 +1,5 @@
package test
final class MethosWithPRefTP() {
fun <erased P> f(p0: P) = #()
}