diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java index 264564f8811..d1dc52b0190 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java @@ -6,6 +6,7 @@ import com.intellij.psi.PsiClass; import com.intellij.psi.PsiModifier; import org.jetbrains.annotations.NotNull; 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.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; @@ -14,6 +15,8 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import java.util.*; /** + * Class static of instance members. + * * @author abreslav */ public class JavaClassMembersScope extends JavaClassOrPackageScope { @@ -23,7 +26,7 @@ public class JavaClassMembersScope extends JavaClassOrPackageScope { private Collection allDescriptors; public JavaClassMembersScope( - @NotNull DeclarationDescriptor classOrNamespaceDescriptor, + @NotNull ClassOrNamespaceDescriptor classOrNamespaceDescriptor, @NotNull PsiClass psiClass, @NotNull JavaSemanticServices semanticServices, boolean staticMembers) { diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassOrPackageScope.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassOrPackageScope.java index f1ff0921913..0b83cfda171 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassOrPackageScope.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaClassOrPackageScope.java @@ -1,8 +1,8 @@ package org.jetbrains.jet.lang.resolve.java; -import com.intellij.psi.PsiClass; import org.jetbrains.annotations.NotNull; 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.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.VariableDescriptor; @@ -17,10 +17,10 @@ import java.util.Set; public abstract class JavaClassOrPackageScope extends JetScopeImpl { @NotNull - protected final DeclarationDescriptor descriptor; + protected final ClassOrNamespaceDescriptor descriptor; protected final JavaSemanticServices semanticServices; - protected JavaClassOrPackageScope(@NotNull DeclarationDescriptor descriptor, @NotNull JavaSemanticServices semanticServices) { + protected JavaClassOrPackageScope(@NotNull ClassOrNamespaceDescriptor descriptor, @NotNull JavaSemanticServices semanticServices) { this.descriptor = descriptor; this.semanticServices = semanticServices; } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java index cf6428169eb..1d03278c8fb 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -66,25 +66,30 @@ public class JavaDescriptorResolver { KOTLIN, } - private static class TypeParameterDescriptorInitialization { + public static class TypeParameterDescriptorInitialization { + @NotNull private final TypeParameterDescriptorOrigin origin; - private final TypeParameterDescriptor descriptor; + @NotNull + final TypeParameterDescriptor descriptor; + final PsiTypeParameter psiTypeParameter; @Nullable private final List upperBoundsForKotlin; @Nullable private final List lowerBoundsForKotlin; - private TypeParameterDescriptorInitialization(TypeParameterDescriptor descriptor) { + private TypeParameterDescriptorInitialization(@NotNull TypeParameterDescriptor descriptor, @NotNull PsiTypeParameter psiTypeParameter) { this.origin = TypeParameterDescriptorOrigin.JAVA; this.descriptor = descriptor; + this.psiTypeParameter = psiTypeParameter; this.upperBoundsForKotlin = null; this.lowerBoundsForKotlin = null; } - private TypeParameterDescriptorInitialization(TypeParameterDescriptor descriptor, + private TypeParameterDescriptorInitialization(@NotNull TypeParameterDescriptor descriptor, @NotNull PsiTypeParameter psiTypeParameter, List upperBoundsForKotlin, List lowerBoundsForKotlin) { this.origin = TypeParameterDescriptorOrigin.KOTLIN; this.descriptor = descriptor; + this.psiTypeParameter = psiTypeParameter; this.upperBoundsForKotlin = upperBoundsForKotlin; this.lowerBoundsForKotlin = lowerBoundsForKotlin; } @@ -97,10 +102,38 @@ public class JavaDescriptorResolver { private Map namedMembersMap; } + static abstract class ResolverClassData extends ResolverScopeData { + + @NotNull + public abstract ClassDescriptor getClassDescriptor(); + } + /** Class with instance members */ - private static class ResolverClassData extends ResolverScopeData { + static class ResolverBinaryClassData extends ResolverClassData { + + ResolverBinaryClassData() { + } + private MutableClassDescriptorLite classDescriptor; + List 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 public ClassDescriptor getClassDescriptor() { return classDescriptor; @@ -117,11 +150,10 @@ public class JavaDescriptorResolver { } } - protected final Map classDescriptorCache = Maps.newHashMap(); + protected final Map classDescriptorCache = Maps.newHashMap(); protected final Map namespaceDescriptorCacheByFqn = Maps.newHashMap(); protected final Map namespaceDescriptorCache = Maps.newHashMap(); - private final Map typeParameterDescriptorCache = Maps.newHashMap(); protected final Map methodDescriptorCache = Maps.newHashMap(); protected final JavaPsiFacade javaFacade; protected final GlobalSearchScope javaSearchScope; @@ -139,9 +171,9 @@ public class JavaDescriptorResolver { this.semanticServices = semanticServices; altClassFinder = new AltClassFinder(project); } - + @Nullable - public ClassDescriptor resolveClass(@NotNull PsiClass psiClass) { + ResolverClassData resolveClassData(@NotNull PsiClass psiClass) { String qualifiedName = psiClass.getQualifiedName(); 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: ClassDescriptor kotlinClassDescriptor = semanticServices.getKotlinClassDescriptor(qualifiedName); if (kotlinClassDescriptor != null) { - return kotlinClassDescriptor; + return new ResolverSrcClassData(kotlinClassDescriptor); } // Not let's take a descriptor of a Java class - ResolverClassData classData = classDescriptorCache.get(qualifiedName); + ResolverBinaryClassData classData = classDescriptorCache.get(qualifiedName); if (classData == null) { classData = createJavaClassDescriptor(psiClass); 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 @@ -179,7 +221,7 @@ public class JavaDescriptorResolver { } // Not let's take a descriptor of a Java class - ResolverClassData classData = classDescriptorCache.get(qualifiedName); + ResolverBinaryClassData classData = classDescriptorCache.get(qualifiedName); if (classData == null) { PsiClass psiClass = findClass(qualifiedName); if (psiClass == null) { @@ -190,19 +232,19 @@ public class JavaDescriptorResolver { return classData.getClassDescriptor(); } - private ResolverClassData createJavaClassDescriptor(@NotNull final PsiClass psiClass) { + private ResolverBinaryClassData createJavaClassDescriptor(@NotNull final PsiClass psiClass) { assert !classDescriptorCache.containsKey(psiClass.getQualifiedName()) : psiClass.getQualifiedName(); classDescriptorCache.put(psiClass.getQualifiedName(), null); // TODO 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; classData.classDescriptor = new MutableClassDescriptorLite( resolveParentDescriptor(psiClass), kind ); classData.classDescriptor.setName(name); - class OuterClassTypeVariableResolver implements TypeVariableResolver { + class OuterClassTypeVariableByNameResolver implements TypeVariableByNameResolver { @NotNull @Override @@ -213,7 +255,13 @@ public class JavaDescriptorResolver { List supertypes = new ArrayList(); - List typeParameters = resolveClassTypeParameters(psiClass, classData, new OuterClassTypeVariableResolver()); + classData.typeParameters = createUninitializedClassTypeParameters(psiClass, classData, new OuterClassTypeVariableByNameResolver()); + + List typeParameters = new ArrayList(); + for (TypeParameterDescriptorInitialization typeParameter : classData.typeParameters) { + typeParameters.add(typeParameter.descriptor); + } + classData.classDescriptor.setTypeParameterDescriptors(typeParameters); classData.classDescriptor.setSupertypes(supertypes); classData.classDescriptor.setVisibility(resolveVisibilityFromPsiModifiers(psiClass)); @@ -225,10 +273,12 @@ public class JavaDescriptorResolver { classDescriptorCache.put(psiClass.getQualifiedName(), classData); classData.classDescriptor.setScopeForMemberLookup(new JavaClassMembersScope(classData.classDescriptor, psiClass, semanticServices, false)); - initializeTypeParameters(psiClass); + initializeTypeParameters(classData.typeParameters, new TypeVariableResoverFromTypeDescriptorsInitialization(new ArrayList(), null)); + + TypeVariableResoverFromTypeDescriptorsInitialization resolverForTypeParameters = new TypeVariableResoverFromTypeDescriptorsInitialization(classData.typeParameters, null); // 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()) { //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; JetType superclassType = extendsListTypes.length == 0 ? JetStandardClasses.getAnyType() - : semanticServices.getTypeTransformer().transformToType(extendsListTypes[0]); + : semanticServices.getTypeTransformer().transformToType(extendsListTypes[0], resolverForTypeParameters); //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 JetType varargElementType = null; 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( @@ -289,7 +339,7 @@ public class JavaDescriptorResolver { Collections.emptyList(), method.getName(), false, - semanticServices.getTypeTransformer().transformToType(returnType), + semanticServices.getTypeTransformer().transformToType(returnType, resolverForTypeParameters), annotationMethod.getDefaultValue() != null, varargElementType)); } @@ -315,7 +365,7 @@ public class JavaDescriptorResolver { false); ValueParameterDescriptors valueParameterDescriptors = resolveParameterDescriptors(constructorDescriptor, constructor.getParameters(), - new TypeParameterListTypeVariableResolver(typeParameters) // TODO: outer too + new TypeVariableResoverFromTypeDescriptorsInitialization(classData.typeParameters, null) // TODO: outer too ); if (valueParameterDescriptors.receiverType != null) { throw new IllegalStateException(); @@ -333,13 +383,13 @@ public class JavaDescriptorResolver { return classData; } - private List resolveClassTypeParameters(PsiClass psiClass, ResolverClassData classData, TypeVariableResolver typeVariableResolver) { + private List createUninitializedClassTypeParameters(PsiClass psiClass, ResolverBinaryClassData classData, TypeVariableByNameResolver typeVariableByNameResolver) { JetClassAnnotation jetClassAnnotation = JetClassAnnotation.get(psiClass); classData.kotlin = jetClassAnnotation.isDefined(); if (jetClassAnnotation.signature().length() > 0) { return resolveClassTypeParametersFromJetSignature( - jetClassAnnotation.signature(), psiClass, classData.classDescriptor, typeVariableResolver); + jetClassAnnotation.signature(), psiClass, classData.classDescriptor, typeVariableByNameResolver); } return makeUninitializedTypeParameters(classData.classDescriptor, psiClass.getTypeParameters()); @@ -380,10 +430,10 @@ public class JavaDescriptorResolver { private final boolean reified; private final int index; private final TypeInfoVariance variance; - private final TypeVariableResolver typeVariableResolver; + private final TypeVariableByNameResolver typeVariableByNameResolver; 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()) { throw new IllegalStateException(); @@ -395,7 +445,7 @@ public class JavaDescriptorResolver { this.reified = reified; this.index = index; this.variance = variance; - this.typeVariableResolver = typeVariableResolver; + this.typeVariableByNameResolver = typeVariableByNameResolver; } List upperBounds = new ArrayList(); @@ -403,7 +453,7 @@ public class JavaDescriptorResolver { @Override public JetSignatureVisitor visitClassBound() { - return new JetTypeJetSignatureReader(semanticServices, semanticServices.getJetSemanticServices().getStandardLibrary(), typeVariableResolver) { + return new JetTypeJetSignatureReader(semanticServices, semanticServices.getJetSemanticServices().getStandardLibrary(), typeVariableByNameResolver) { @Override protected void done(@NotNull JetType jetType) { if (isJavaLangObject(jetType)) { @@ -416,7 +466,7 @@ public class JavaDescriptorResolver { @Override public JetSignatureVisitor visitInterfaceBound() { - return new JetTypeJetSignatureReader(semanticServices, semanticServices.getJetSemanticServices().getStandardLibrary(), typeVariableResolver) { + return new JetTypeJetSignatureReader(semanticServices, semanticServices.getJetSemanticServices().getStandardLibrary(), typeVariableByNameResolver) { @Override protected void done(@NotNull JetType jetType) { upperBounds.add(jetType); @@ -434,31 +484,31 @@ public class JavaDescriptorResolver { name, index); PsiTypeParameter psiTypeParameter = getPsiTypeParameterByName(psiOwner, name); - typeParameterDescriptorCache.put(psiTypeParameter, new TypeParameterDescriptorInitialization(typeParameter, upperBounds, lowerBounds)); - done(typeParameter); + TypeParameterDescriptorInitialization typeParameterDescriptorInitialization = new TypeParameterDescriptorInitialization(typeParameter, psiTypeParameter, upperBounds, lowerBounds); + done(typeParameterDescriptorInitialization); } - protected abstract void done(TypeParameterDescriptor typeParameterDescriptor); + protected abstract void done(@NotNull TypeParameterDescriptorInitialization typeParameterDescriptor); } /** * @see #resolveMethodTypeParametersFromJetSignature(String, FunctionDescriptor) */ - private List resolveClassTypeParametersFromJetSignature(String jetSignature, final PsiClass clazz, - final ClassDescriptor classDescriptor, final TypeVariableResolver outerClassTypeVariableResolver) { - final List r = new ArrayList(); + private List resolveClassTypeParametersFromJetSignature(String jetSignature, final PsiClass clazz, + final ClassDescriptor classDescriptor, final TypeVariableByNameResolver outerClassTypeVariableByNameResolver) { + final List r = new ArrayList(); - class MyTypeVariableResolver implements TypeVariableResolver { + class MyTypeVariableByNameResolver implements TypeVariableByNameResolver { @NotNull @Override public TypeParameterDescriptor getTypeVariable(@NotNull String name) { - for (TypeParameterDescriptor typeParameter : r) { - if (typeParameter.getName().equals(name)) { - return typeParameter; + for (TypeParameterDescriptorInitialization typeParameter : r) { + if (typeParameter.descriptor.getName().equals(name)) { + return typeParameter.descriptor; } } - return outerClassTypeVariableResolver.getTypeVariable(name); + return outerClassTypeVariableByNameResolver.getTypeVariable(name); } } @@ -467,9 +517,9 @@ public class JavaDescriptorResolver { @Override 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 - protected void done(TypeParameterDescriptor typeParameterDescriptor) { + protected void done(TypeParameterDescriptorInitialization typeParameterDescriptor) { r.add(typeParameterDescriptor); } }; @@ -501,18 +551,17 @@ public class JavaDescriptorResolver { return resolveNamespace(packageName); } - private List makeUninitializedTypeParameters(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameter[] typeParameters) { - List result = Lists.newArrayList(); + private List makeUninitializedTypeParameters(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameter[] typeParameters) { + List result = Lists.newArrayList(); for (PsiTypeParameter typeParameter : typeParameters) { - TypeParameterDescriptor typeParameterDescriptor = makeUninitializedTypeParameter(containingDeclaration, typeParameter); + TypeParameterDescriptorInitialization typeParameterDescriptor = makeUninitializedTypeParameter(containingDeclaration, typeParameter); result.add(typeParameterDescriptor); } return result; } @NotNull - private TypeParameterDescriptor makeUninitializedTypeParameter(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameter psiTypeParameter) { - assert typeParameterDescriptorCache.get(psiTypeParameter) == null : psiTypeParameter.getText(); + private TypeParameterDescriptorInitialization makeUninitializedTypeParameter(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameter psiTypeParameter) { TypeParameterDescriptor typeParameterDescriptor = TypeParameterDescriptor.createForFurtherModification( containingDeclaration, Collections.emptyList(), // TODO @@ -521,61 +570,52 @@ public class JavaDescriptorResolver { psiTypeParameter.getName(), psiTypeParameter.getIndex() ); - typeParameterDescriptorCache.put(psiTypeParameter, new TypeParameterDescriptorInitialization(typeParameterDescriptor)); - return typeParameterDescriptor; + return new TypeParameterDescriptorInitialization(typeParameterDescriptor, psiTypeParameter); } - private void initializeTypeParameter(PsiTypeParameter typeParameter, TypeParameterDescriptorInitialization typeParameterDescriptorInitialization) { - TypeParameterDescriptor typeParameterDescriptor = typeParameterDescriptorInitialization.descriptor; - if (typeParameterDescriptorInitialization.origin == TypeParameterDescriptorOrigin.KOTLIN) { - List upperBounds = typeParameterDescriptorInitialization.upperBoundsForKotlin; + private void initializeTypeParameter(TypeParameterDescriptorInitialization typeParameter, TypeVariableByPsiResolver typeVariableByPsiResolver) { + TypeParameterDescriptor typeParameterDescriptor = typeParameter.descriptor; + if (typeParameter.origin == TypeParameterDescriptorOrigin.KOTLIN) { + List upperBounds = typeParameter.upperBoundsForKotlin; if (upperBounds.size() == 0){ typeParameterDescriptor.addUpperBound(JetStandardClasses.getNullableAnyType()); } else { - for (JetType upperBound : typeParameterDescriptorInitialization.upperBoundsForKotlin) { + for (JetType upperBound : typeParameter.upperBoundsForKotlin) { typeParameterDescriptor.addUpperBound(upperBound); } } // TODO: lower bounds } else { - PsiClassType[] referencedTypes = typeParameter.getExtendsList().getReferencedTypes(); + PsiClassType[] referencedTypes = typeParameter.psiTypeParameter.getExtendsList().getReferencedTypes(); if (referencedTypes.length == 0){ typeParameterDescriptor.addUpperBound(JetStandardClasses.getNullableAnyType()); } else if (referencedTypes.length == 1) { - typeParameterDescriptor.addUpperBound(semanticServices.getTypeTransformer().transformToType(referencedTypes[0])); + typeParameterDescriptor.addUpperBound(semanticServices.getTypeTransformer().transformToType(referencedTypes[0], typeVariableByPsiResolver)); } else { for (PsiClassType referencedType : referencedTypes) { - typeParameterDescriptor.addUpperBound(semanticServices.getTypeTransformer().transformToType(referencedType)); + typeParameterDescriptor.addUpperBound(semanticServices.getTypeTransformer().transformToType(referencedType, typeVariableByPsiResolver)); } } } typeParameterDescriptor.setInitialized(); } - private void initializeTypeParameters(PsiTypeParameterListOwner typeParameterListOwner) { - for (PsiTypeParameter psiTypeParameter : typeParameterListOwner.getTypeParameters()) { - initializeTypeParameter(psiTypeParameter, resolveTypeParameterInitialization(psiTypeParameter)); + private void initializeTypeParameters(List typeParametersInitialization, TypeVariableResolver typeVariableByPsiResolver) { + List prevTypeParameters = new ArrayList(); + for (TypeParameterDescriptorInitialization psiTypeParameter : typeParametersInitialization) { + prevTypeParameters.add(psiTypeParameter); + initializeTypeParameter(psiTypeParameter, new TypeVariableResoverFromTypeDescriptorsInitialization(prevTypeParameters, typeVariableByPsiResolver)); } } - @NotNull - 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 getSupertypes(PsiClassWrapper psiClass, List typeParameters) { + private Collection getSupertypes(PsiClassWrapper psiClass, List typeParameters) { final List result = new ArrayList(); 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() { @Override @@ -609,8 +649,8 @@ public class JavaDescriptorResolver { } }); } else { - transformSupertypeList(result, psiClass.getPsiClass().getExtendsListTypes()); - transformSupertypeList(result, psiClass.getPsiClass().getImplementsListTypes()); + transformSupertypeList(result, psiClass.getPsiClass().getExtendsListTypes(), new TypeVariableResoverFromTypeDescriptorsInitialization(typeParameters, null)); + transformSupertypeList(result, psiClass.getPsiClass().getImplementsListTypes(), new TypeVariableResoverFromTypeDescriptorsInitialization(typeParameters, null)); } if (result.isEmpty()) { result.add(JetStandardClasses.getAnyType()); @@ -618,14 +658,14 @@ public class JavaDescriptorResolver { return result; } - private void transformSupertypeList(List result, PsiClassType[] extendsListTypes) { + private void transformSupertypeList(List result, PsiClassType[] extendsListTypes, TypeVariableResolver typeVariableResolver) { for (PsiClassType type : extendsListTypes) { PsiClass resolved = type.resolve(); if (resolved != null && resolved.getQualifiedName().equals(JvmStdlibNames.JET_OBJECT.getFqName())) { continue; } - JetType transform = semanticServices.getTypeTransformer().transformToType(type); + JetType transform = semanticServices.getTypeTransformer().transformToType(type, typeVariableResolver); result.add(TypeUtils.makeNotNullable(transform)); } @@ -817,7 +857,7 @@ public class JavaDescriptorResolver { if (typeFromAnnotation.length() > 0) { outType = semanticServices.getTypeTransformer().transformToType(typeFromAnnotation, typeVariableResolver); } else { - outType = semanticServices.getTypeTransformer().transformToType(psiType); + outType = semanticServices.getTypeTransformer().transformToType(psiType, typeVariableResolver); } JetType varargElementType; @@ -843,7 +883,7 @@ public class JavaDescriptorResolver { } } - public Set resolveFieldGroupByName(@NotNull DeclarationDescriptor owner, PsiClass psiClass, String fieldName, boolean staticMembers) { + public Set resolveFieldGroupByName(@NotNull ClassOrNamespaceDescriptor owner, PsiClass psiClass, String fieldName, boolean staticMembers) { ResolverScopeData scopeData = getResolverScopeData(owner, new PsiClassWrapper(psiClass)); NamedMembers namedMembers = scopeData.namedMembersMap.get(fieldName); @@ -851,13 +891,13 @@ public class JavaDescriptorResolver { return Collections.emptySet(); } - resolveNamedGroupProperties(owner, staticMembers, namedMembers, fieldName); + resolveNamedGroupProperties(owner, scopeData, staticMembers, namedMembers, fieldName); return namedMembers.propertyDescriptors; } @NotNull - public Set resolveFieldGroup(@NotNull DeclarationDescriptor owner, PsiClass psiClass, boolean staticMembers) { + public Set resolveFieldGroup(@NotNull ClassOrNamespaceDescriptor owner, PsiClass psiClass, boolean staticMembers) { ResolverScopeData scopeData = getResolverScopeData(owner, new PsiClassWrapper(psiClass)); @@ -871,7 +911,7 @@ public class JavaDescriptorResolver { String propertyName = entry.getKey(); - resolveNamedGroupProperties(owner, staticMembers, namedMembers, propertyName); + resolveNamedGroupProperties(owner, scopeData, staticMembers, namedMembers, propertyName); descriptors.addAll(namedMembers.propertyDescriptors); } return descriptors; @@ -905,7 +945,10 @@ public class JavaDescriptorResolver { 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) { return; } @@ -914,16 +957,16 @@ public class JavaDescriptorResolver { namedMembers.propertyDescriptors = Collections.emptySet(); return; } - - final List classTypeParameters; - if (!staticMembers) { - classTypeParameters = ((ClassDescriptor) owner).getTypeConstructor().getParameters(); + + final List classTypeParameterDescriptorInitialization; + if (scopeData instanceof ResolverBinaryClassData) { + classTypeParameterDescriptorInitialization = ((ResolverBinaryClassData) scopeData).typeParameters; } else { - classTypeParameters = new ArrayList(0); + classTypeParameterDescriptorInitialization = new ArrayList(0); } - TypeParameterListTypeVariableResolver typeVariableResolver = new TypeParameterListTypeVariableResolver(classTypeParameters); - + TypeVariableResolver typeVariableResolver = new TypeVariableResoverFromTypeDescriptorsInitialization(classTypeParameterDescriptorInitialization, null); + class GroupingValue { PropertyAccessorData getter; PropertyAccessorData setter; @@ -1015,33 +1058,38 @@ public class JavaDescriptorResolver { propertyDescriptor.initialize(getterDescriptor, setterDescriptor); - List typeParameters = new ArrayList(0); + List typeParametersInitialization = new ArrayList(0); if (members.setter != null) { PsiMethodWrapper method = (PsiMethodWrapper) members.setter.getMember(); if (anyMember == members.setter) { - typeParameters = resolveMethodTypeParameters(method, setterDescriptor, typeVariableResolver); + typeParametersInitialization = resolveMethodTypeParameters(method, setterDescriptor, typeVariableResolver); } } if (members.getter != null) { PsiMethodWrapper method = (PsiMethodWrapper) members.getter.getMember(); if (anyMember == members.getter) { - typeParameters = resolveMethodTypeParameters(method, getterDescriptor, typeVariableResolver); + typeParametersInitialization = resolveMethodTypeParameters(method, getterDescriptor, typeVariableResolver); } } - List typeParametersForReceiver = new ArrayList(); - typeParametersForReceiver.addAll(classTypeParameters); - typeParametersForReceiver.addAll(typeParameters); - TypeVariableResolver typeVariableResolverForPropertyInternals = new TypeParameterListTypeVariableResolver(typeParametersForReceiver); - + List typeParameters = new ArrayList(); + for (TypeParameterDescriptorInitialization typeParameter : typeParametersInitialization) { + typeParameters.add(typeParameter.descriptor); + } + + List typeParametersForReceiver = new ArrayList(); + typeParametersForReceiver.addAll(classTypeParameterDescriptorInitialization); + typeParametersForReceiver.addAll(typeParametersInitialization); + TypeVariableResolver typeVariableResolverForPropertyInternals = new TypeVariableResoverFromTypeDescriptorsInitialization(typeParametersForReceiver, null); + JetType propertyType; if (anyMember.getType().getTypeString().length() > 0) { propertyType = semanticServices.getTypeTransformer().transformToType(anyMember.getType().getTypeString(), typeVariableResolverForPropertyInternals); } else { - propertyType = semanticServices.getTypeTransformer().transformToType(anyMember.getType().getPsiType()); + propertyType = semanticServices.getTypeTransformer().transformToType(anyMember.getType().getPsiType(), typeVariableResolverForPropertyInternals); } JetType receiverType; @@ -1050,7 +1098,7 @@ public class JavaDescriptorResolver { } else if (anyMember.getReceiverType().getTypeString().length() > 0) { receiverType = semanticServices.getTypeTransformer().transformToType(anyMember.getReceiverType().getTypeString(), typeVariableResolverForPropertyInternals); } else { - receiverType = semanticServices.getTypeTransformer().transformToType(anyMember.getReceiverType().getPsiType()); + receiverType = semanticServices.getTypeTransformer().transformToType(anyMember.getReceiverType().getPsiType(), typeVariableResolverForPropertyInternals); } propertyDescriptor.setType( @@ -1074,7 +1122,7 @@ public class JavaDescriptorResolver { 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) { return; } @@ -1094,7 +1142,7 @@ public class JavaDescriptorResolver { namedMembers.functionDescriptors = functionDescriptors; } - private ResolverScopeData getResolverScopeData(DeclarationDescriptor owner, PsiClassWrapper psiClass) { + private ResolverScopeData getResolverScopeData(ClassOrNamespaceDescriptor owner, PsiClassWrapper psiClass) { ResolverScopeData scopeData; boolean staticMembers; if (owner instanceof JavaNamespaceDescriptor) { @@ -1118,8 +1166,7 @@ public class JavaDescriptorResolver { } @NotNull - public Set resolveFunctionGroup(@NotNull DeclarationDescriptor descriptor, @NotNull PsiClass psiClass, - @NotNull String methodName, boolean staticMembers) { + public Set resolveFunctionGroup(@NotNull ClassOrNamespaceDescriptor descriptor, @NotNull PsiClass psiClass, @NotNull String methodName, boolean staticMembers) { ResolverScopeData resolverScopeData = getResolverScopeData(descriptor, new PsiClassWrapper(psiClass)); @@ -1152,28 +1199,30 @@ public class JavaDescriptorResolver { 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 dest) { + ResolverClassData classData = resolveClassData(psiClass); - private final List typeParameters; - - private TypeParameterListTypeVariableResolver(List typeParameters) { - this.typeParameters = typeParameters; + if (classData instanceof ResolverSrcClassData) { + // TODO hack + return; } - @NotNull - @Override - public TypeParameterDescriptor getTypeVariable(@NotNull String name) { - for (TypeParameterDescriptor typeParameter : typeParameters) { - if (typeParameter.getName().equals(name)) { - return typeParameter; - } - } - throw new IllegalStateException("unresolver variable: " + name); // TODO: report properly + ResolverBinaryClassData binaryClassData = (ResolverBinaryClassData) classData; + if (binaryClassData == null) { + return; + } + if (binaryClassData.typeParameters == null) { + throw new RuntimeException(); + } + dest.addAll(binaryClassData.typeParameters); + for (PsiClass supr : psiClass.getSupers()) { + getAllTypeParameterDescriptorInitialization(supr, dest); } } @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(); if (returnType == null) { @@ -1187,6 +1236,8 @@ public class JavaDescriptorResolver { return functionDescriptor; } + ResolverScopeData scopeData = getResolverScopeData(owner, new PsiClassWrapper(psiClass)); + boolean kotlin; if (owner instanceof JavaNamespaceDescriptor) { JavaNamespaceDescriptor javaNamespaceDescriptor = (JavaNamespaceDescriptor) owner; @@ -1196,7 +1247,7 @@ public class JavaDescriptorResolver { } kotlin = namespaceData.kotlin; } else { - ResolverClassData classData = classDescriptorCache.get(psiClass.getQualifiedName()); + ResolverBinaryClassData classData = classDescriptorCache.get(psiClass.getQualifiedName()); if (classData == null) { throw new IllegalStateException("classData not found by name " + psiClass.getQualifiedName()); } @@ -1231,14 +1282,19 @@ public class JavaDescriptorResolver { DeclarationDescriptor classDescriptor; final List classTypeParameters; - if (method.isStatic()) { - classDescriptor = resolveNamespace(method.getPsiMethod().getContainingClass()); - classTypeParameters = Collections.emptyList(); - } - else { + final List classTypeParameterDescriptorsInitialization; + if (scopeData instanceof ResolverBinaryClassData) { ClassDescriptor classClassDescriptor = resolveClass(method.getPsiMethod().getContainingClass()); classDescriptor = classClassDescriptor; classTypeParameters = classClassDescriptor.getTypeConstructor().getParameters(); + classTypeParameterDescriptorsInitialization = new ArrayList(); + getAllTypeParameterDescriptorInitialization(psiClass, classTypeParameterDescriptorsInitialization); + //classTypeParameterDescriptorsInitialization = ((ResolverClassData) scopeData).typeParameters; + } + else { + classDescriptor = resolveNamespace(method.getPsiMethod().getContainingClass()); + classTypeParameters = new ArrayList(0); + classTypeParameterDescriptorsInitialization = new ArrayList(0); } if (classDescriptor == null) { return null; @@ -1251,18 +1307,37 @@ public class JavaDescriptorResolver { methodDescriptorCache.put(method.getPsiMethod(), functionDescriptorImpl); // TODO: add outer classes - TypeParameterListTypeVariableResolver typeVariableResolverForParameters = new TypeParameterListTypeVariableResolver(classTypeParameters); + TypeVariableResolver typeVariableResolverForParameters = new TypeVariableResoverFromTypeDescriptorsInitialization(classTypeParameterDescriptorsInitialization, null); - final List methodTypeParameters = resolveMethodTypeParameters(method, functionDescriptorImpl, typeVariableResolverForParameters); + final List methodTypeParametersInitialization = resolveMethodTypeParameters(method, functionDescriptorImpl, typeVariableResolverForParameters); + List methodTypeParameters = new ArrayList(); + for (TypeParameterDescriptorInitialization typeParameterDescriptorInitialization : methodTypeParametersInitialization) { + methodTypeParameters.add(typeParameterDescriptorInitialization.descriptor); + } 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 @Override public TypeParameterDescriptor getTypeVariable(@NotNull String name) { - for (TypeParameterDescriptor typeParameter : methodTypeParameters) { - if (typeParameter.getName().equals(name)) { - return typeParameter; + for (TypeParameterDescriptorInitialization typeParameter : methodTypeParametersInitialization) { + if (typeParameter.descriptor.getName().equals(name)) { + return typeParameter.descriptor; } } for (TypeParameterDescriptor typeParameter : classTypeParameters) { @@ -1272,6 +1347,7 @@ public class JavaDescriptorResolver { } throw new IllegalStateException("unresolver variable: " + name); // TODO: report properly } + } @@ -1293,12 +1369,12 @@ public class JavaDescriptorResolver { return substitutedFunctionDescriptor; } - public List resolveMethods(PsiClass psiClass, DeclarationDescriptor containingDeclaration) { + public List resolveMethods(PsiClass psiClass, ClassOrNamespaceDescriptor containingDeclaration) { ResolverScopeData scopeData = getResolverScopeData(containingDeclaration, new PsiClassWrapper(psiClass)); TypeSubstitutor substitutorForGenericSupertypes; - if (scopeData instanceof ResolverClassData) { - substitutorForGenericSupertypes = createSubstitutorForGenericSupertypes(((ResolverClassData) scopeData).classDescriptor); + if (scopeData instanceof ResolverBinaryClassData) { + substitutorForGenericSupertypes = createSubstitutorForGenericSupertypes(((ResolverBinaryClassData) scopeData).classDescriptor); } else { substitutorForGenericSupertypes = TypeSubstitutor.EMPTY; } @@ -1313,41 +1389,42 @@ public class JavaDescriptorResolver { return functions; } - private List resolveMethodTypeParameters( + private List resolveMethodTypeParameters( @NotNull PsiMethodWrapper method, @NotNull DeclarationDescriptor functionDescriptor, - @NotNull TypeVariableResolver classTypeVariableResolver) { + @NotNull TypeVariableResolver classTypeVariableResolver + ) { + List typeParameters; if (method.getJetMethod().typeParameters().length() > 0) { - List r = resolveMethodTypeParametersFromJetSignature( + typeParameters = resolveMethodTypeParametersFromJetSignature( method.getJetMethod().typeParameters(), method.getPsiMethod(), functionDescriptor, classTypeVariableResolver); - initializeTypeParameters(method.getPsiMethod()); - return r; + } else { + typeParameters = makeUninitializedTypeParameters(functionDescriptor, method.getPsiMethod().getTypeParameters()); } - List typeParameters = makeUninitializedTypeParameters(functionDescriptor, method.getPsiMethod().getTypeParameters()); - initializeTypeParameters(method.getPsiMethod()); + initializeTypeParameters(typeParameters, classTypeVariableResolver); return typeParameters; } /** * @see #resolveClassTypeParametersFromJetSignature(String, com.intellij.psi.PsiClass, MutableClassDescriptorLite) */ - private List resolveMethodTypeParametersFromJetSignature(String jetSignature, final PsiMethod method, - final DeclarationDescriptor functionDescriptor, final TypeVariableResolver classTypeVariableResolver) + private List resolveMethodTypeParametersFromJetSignature(String jetSignature, final PsiMethod method, + final DeclarationDescriptor functionDescriptor, final TypeVariableByNameResolver classTypeVariableByNameResolver) { - final List r = new ArrayList(); + final List r = new ArrayList(); - class MyTypeVariableResolver implements TypeVariableResolver { + class MyTypeVariableByNameResolver implements TypeVariableByNameResolver { @NotNull @Override public TypeParameterDescriptor getTypeVariable(@NotNull String name) { - for (TypeParameterDescriptor typeParameter : r) { - if (typeParameter.getName().equals(name)) { - return typeParameter; + for (TypeParameterDescriptorInitialization typeParameter : r) { + if (typeParameter.descriptor.getName().equals(name)) { + return typeParameter.descriptor; } } - return classTypeVariableResolver.getTypeVariable(name); + return classTypeVariableByNameResolver.getTypeVariable(name); } } @@ -1357,9 +1434,9 @@ public class JavaDescriptorResolver { @Override 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 - protected void done(TypeParameterDescriptor typeParameterDescriptor) { + protected void done(TypeParameterDescriptorInitialization typeParameterDescriptor) { r.add(typeParameterDescriptor); } }; @@ -1369,7 +1446,8 @@ public class JavaDescriptorResolver { 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(); @@ -1377,7 +1455,7 @@ public class JavaDescriptorResolver { if (returnTypeFromAnnotation.length() > 0) { transformedType = semanticServices.getTypeTransformer().transformToType(returnTypeFromAnnotation, typeVariableResolver); } else { - transformedType = semanticServices.getTypeTransformer().transformToType(returnType); + transformedType = semanticServices.getTypeTransformer().transformToType(returnType, typeVariableResolver); } if (method.getJetMethod().returnTypeNullable()) { return TypeUtils.makeNullableAsSpecified(transformedType, true); @@ -1393,41 +1471,14 @@ public class JavaDescriptorResolver { (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 resolveInnerClasses(DeclarationDescriptor owner, PsiClass psiClass, boolean staticMembers) { PsiClass[] innerPsiClasses = psiClass.getInnerClasses(); List r = new ArrayList(innerPsiClasses.length); for (PsiClass innerPsiClass : innerPsiClasses) { + if (innerPsiClass.hasModifierProperty(PsiModifier.PRIVATE)) { + // TODO: hack against inner classes + continue; + } r.add(resolveClass(innerPsiClass)); } return r; diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPackageScope.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPackageScope.java index ebb7af8502e..3fbdd8fcc50 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPackageScope.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaPackageScope.java @@ -22,7 +22,7 @@ public class JavaPackageScope extends JavaClassOrPackageScope { public JavaPackageScope( @NotNull String packageFQN, - @NotNull DeclarationDescriptor containingDescriptor, + @NotNull NamespaceDescriptor containingDescriptor, @NotNull JavaSemanticServices semanticServices) { super(containingDescriptor, semanticServices); this.packageFQN = packageFQN; diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java index 9291f30c7bf..0e8899008a8 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java @@ -33,7 +33,9 @@ public class JavaTypeTransformer { } @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() { @Override @@ -50,21 +52,21 @@ public class JavaTypeTransformer { PsiType bound = wildcardType.getBound(); assert bound != null; - return new TypeProjection(variance, transformToType(bound)); + return new TypeProjection(variance, transformToType(bound, typeVariableByPsiResolver)); } @Override public TypeProjection visitType(PsiType type) { - return new TypeProjection(transformToType(type)); + return new TypeProjection(transformToType(type, typeVariableByPsiResolver)); } }); return result; } @NotNull - public JetType transformToType(@NotNull String kotlinSignature, TypeVariableResolver typeVariableResolver) { + public JetType transformToType(@NotNull String kotlinSignature, TypeVariableByNameResolver typeVariableByNameResolver) { final JetType[] r = new JetType[1]; - JetTypeJetSignatureReader reader = new JetTypeJetSignatureReader(javaSemanticServices, standardLibrary, typeVariableResolver) { + JetTypeJetSignatureReader reader = new JetTypeJetSignatureReader(javaSemanticServices, standardLibrary, typeVariableByNameResolver) { @Override protected void done(@NotNull JetType jetType) { r[0] = jetType; @@ -75,7 +77,8 @@ public class JavaTypeTransformer { } @NotNull - public JetType transformToType(@NotNull PsiType javaType) { + public JetType transformToType(@NotNull PsiType javaType, + @NotNull final TypeVariableByPsiResolver typeVariableByPsiResolver) { return javaType.accept(new PsiTypeVisitor() { @Override public JetType visitClassType(PsiClassType classType) { @@ -87,7 +90,7 @@ public class JavaTypeTransformer { if (psiClass instanceof PsiTypeParameter) { PsiTypeParameter typeParameter = (PsiTypeParameter) psiClass; - TypeParameterDescriptor typeParameterDescriptor = resolver.resolveTypeParameter(typeParameter); + TypeParameterDescriptor typeParameterDescriptor = typeVariableByPsiResolver.getTypeVariable(typeParameter); // return TypeUtils.makeNullable(typeParameterDescriptor.getDefaultType()); return typeParameterDescriptor.getDefaultType(); } @@ -97,34 +100,65 @@ public class JavaTypeTransformer { return jetAnalog; } - ClassDescriptor descriptor = resolver.resolveClass(psiClass); - if (descriptor == null) { + final JavaDescriptorResolver.ResolverClassData classData = resolver.resolveClassData(psiClass); + if (classData == null) { return ErrorUtils.createErrorType("Unresolve java class: " + classType.getPresentableText()); } List arguments = Lists.newArrayList(); if (classType.isRaw()) { - List parameters = descriptor.getTypeConstructor().getParameters(); + List parameters = classData.getClassDescriptor().getTypeConstructor().getParameters(); for (TypeParameterDescriptor parameter : parameters) { arguments.add(TypeUtils.makeStarProjection(parameter)); } } else { - List parameters = descriptor.getTypeConstructor().getParameters(); + List parameters = classData.getClassDescriptor().getTypeConstructor().getParameters(); PsiType[] psiArguments = classType.getParameters(); + + if (parameters.size() != psiArguments.length) { + throw new IllegalStateException(); + } + for (int i = 0; i < parameters.size(); i++) { PsiType psiArgument = psiArguments[i]; TypeParameterDescriptor typeParameterDescriptor = parameters.get(i); + + TypeVariableResolver typeVariableByPsiResolver2 = new TypeVariableResolver() { + @NotNull + @Override + public TypeParameterDescriptor getTypeVariable(@NotNull String name) { + throw new RuntimeException(); // TODO + } - arguments.add(transformToTypeProjection(psiArgument, typeParameterDescriptor)); + @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( Collections.emptyList(), - descriptor.getTypeConstructor(), + classData.getClassDescriptor().getTypeConstructor(), true, arguments, - descriptor.getMemberScope(arguments)); + classData.getClassDescriptor().getMemberScope(arguments)); } } @@ -145,7 +179,7 @@ public class JavaTypeTransformer { return TypeUtils.makeNullable(jetType); } - JetType type = transformToType(componentType); + JetType type = transformToType(componentType, typeVariableByPsiResolver); return TypeUtils.makeNullable(standardLibrary.getArrayType(type)); } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java index 261bc41c70c..4b28da0f5cb 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java @@ -28,13 +28,13 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd private final JavaSemanticServices javaSemanticServices; private final JavaDescriptorResolver javaDescriptorResolver; 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.javaDescriptorResolver = javaSemanticServices.getDescriptorResolver(); this.jetStandardLibrary = jetStandardLibrary; - this.typeVariableResolver = typeVariableResolver; + this.typeVariableByNameResolver = typeVariableByNameResolver; } @@ -122,7 +122,7 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd @Override public JetSignatureVisitor visitTypeArgument(final JetSignatureVariance variance) { - return new JetTypeJetSignatureReader(javaSemanticServices, jetStandardLibrary, typeVariableResolver) { + return new JetTypeJetSignatureReader(javaSemanticServices, jetStandardLibrary, typeVariableByNameResolver) { @Override protected void done(@NotNull JetType jetType) { @@ -133,7 +133,7 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd @Override public JetSignatureVisitor visitArrayType(final boolean nullable) { - return new JetTypeJetSignatureReader(javaSemanticServices, jetStandardLibrary, typeVariableResolver) { + return new JetTypeJetSignatureReader(javaSemanticServices, jetStandardLibrary, typeVariableByNameResolver) { @Override public void visitBaseType(char descriptor, boolean nullable) { JetType primitiveType = getPrimitiveType(descriptor, nullable); @@ -156,7 +156,7 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd @Override 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); } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/TypeVariableByNameResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/TypeVariableByNameResolver.java new file mode 100644 index 00000000000..68720749751 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/TypeVariableByNameResolver.java @@ -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); +} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/TypeVariableByPsiResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/TypeVariableByPsiResolver.java new file mode 100644 index 00000000000..4615f626fed --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/TypeVariableByPsiResolver.java @@ -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); +} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/TypeVariableByPsiResolverImpl.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/TypeVariableByPsiResolverImpl.java new file mode 100644 index 00000000000..983055bd315 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/TypeVariableByPsiResolverImpl.java @@ -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 typeParameters; + @Nullable + private final TypeVariableByPsiResolver parent; + + public TypeVariableByPsiResolverImpl(@NotNull List 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 + } + +} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/TypeVariableResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/TypeVariableResolver.java index 9f391218d72..6e944e0559f 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/TypeVariableResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/TypeVariableResolver.java @@ -1,12 +1,7 @@ package org.jetbrains.jet.lang.resolve.java; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; - /** * @author Stepan Koltsov */ -public interface TypeVariableResolver { - @NotNull - TypeParameterDescriptor getTypeVariable(@NotNull String name); +public interface TypeVariableResolver extends TypeVariableByPsiResolver, TypeVariableByNameResolver { } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/TypeVariableResoverFromTypeDescriptorsInitialization.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/TypeVariableResoverFromTypeDescriptorsInitialization.java new file mode 100644 index 00000000000..b184016b1a4 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/TypeVariableResoverFromTypeDescriptorsInitialization.java @@ -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 typeParameters; + @Nullable + private final TypeVariableResolver parent; + + public TypeVariableResoverFromTypeDescriptorsInitialization(@NotNull List 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 + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptor.java index 230e58fdf12..096385ca524 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassDescriptor.java @@ -15,7 +15,7 @@ import java.util.Set; /** * @author abreslav */ -public interface ClassDescriptor extends ClassifierDescriptor, MemberDescriptor { +public interface ClassDescriptor extends ClassifierDescriptor, MemberDescriptor, ClassOrNamespaceDescriptor { @NotNull JetScope getMemberScope(List typeArguments); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassOrNamespaceDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassOrNamespaceDescriptor.java new file mode 100644 index 00000000000..6d8f02af9f8 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassOrNamespaceDescriptor.java @@ -0,0 +1,7 @@ +package org.jetbrains.jet.lang.descriptors; + +/** + * @author Stepan Koltsov + */ +public interface ClassOrNamespaceDescriptor extends DeclarationDescriptor { +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/NamespaceDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/NamespaceDescriptor.java index e28ddec1d21..0a86d3da2d3 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/NamespaceDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/NamespaceDescriptor.java @@ -8,7 +8,7 @@ import org.jetbrains.jet.lang.types.NamespaceType; /** * @author abreslav */ -public interface NamespaceDescriptor extends Annotated, Named, DeclarationDescriptor { +public interface NamespaceDescriptor extends Annotated, Named, ClassOrNamespaceDescriptor { @NotNull JetScope getMemberScope(); diff --git a/compiler/testData/readJavaBinaryClass/ClassWithTypeP.java b/compiler/testData/readJavaBinaryClass/ClassWithTypeP.java new file mode 100644 index 00000000000..034f19c4e15 --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/ClassWithTypeP.java @@ -0,0 +1,4 @@ +package test; + +final class ClassWithTypeParameter

{ +} diff --git a/compiler/testData/readJavaBinaryClass/ClassWithTypeP.kt b/compiler/testData/readJavaBinaryClass/ClassWithTypeP.kt new file mode 100644 index 00000000000..8dcfa0c26af --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/ClassWithTypeP.kt @@ -0,0 +1,4 @@ +package test + +class ClassWithTypeParameter() { +} diff --git a/compiler/testData/readJavaBinaryClass/ClassWithTypePExtendsIterableP.java b/compiler/testData/readJavaBinaryClass/ClassWithTypePExtendsIterableP.java new file mode 100644 index 00000000000..ddbeb9b8713 --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/ClassWithTypePExtendsIterableP.java @@ -0,0 +1,4 @@ +package test; + +abstract class ClassTypeTypePRefSuper

implements java.lang.Iterable

{ +} diff --git a/compiler/testData/readJavaBinaryClass/ClassWithTypePExtendsIterableP.kt b/compiler/testData/readJavaBinaryClass/ClassWithTypePExtendsIterableP.kt new file mode 100644 index 00000000000..be4d105bc30 --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/ClassWithTypePExtendsIterableP.kt @@ -0,0 +1,4 @@ +package test + +abstract class ClassTypeTypePRefSuper() : java.lang.Iterable

{ +} diff --git a/compiler/testData/readJavaBinaryClass/ClassWithTypePP.java b/compiler/testData/readJavaBinaryClass/ClassWithTypePP.java new file mode 100644 index 00000000000..20423487a5b --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/ClassWithTypePP.java @@ -0,0 +1,4 @@ +package test; + +final class ClassWithTypeParameter { +} diff --git a/compiler/testData/readJavaBinaryClass/ClassWithTypePP.kt b/compiler/testData/readJavaBinaryClass/ClassWithTypePP.kt new file mode 100644 index 00000000000..c310804bec9 --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/ClassWithTypePP.kt @@ -0,0 +1,4 @@ +package test + +class ClassWithTypeParameter() { +} diff --git a/compiler/testData/readJavaBinaryClass/ClassWithTypePRefSelf.java b/compiler/testData/readJavaBinaryClass/ClassWithTypePRefSelf.java new file mode 100644 index 00000000000..e28acbc31e1 --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/ClassWithTypePRefSelf.java @@ -0,0 +1,4 @@ +package test; + +final class ClassWithTypePRefSelf

> { +} diff --git a/compiler/testData/readJavaBinaryClass/ClassWithTypePRefSelf.kt b/compiler/testData/readJavaBinaryClass/ClassWithTypePRefSelf.kt new file mode 100644 index 00000000000..7235e9985fd --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/ClassWithTypePRefSelf.kt @@ -0,0 +1,4 @@ +package test + +class ClassWithTypePRefSelf?>() { +} diff --git a/compiler/testData/readJavaBinaryClass/MethodWithTypeP.java b/compiler/testData/readJavaBinaryClass/MethodWithTypeP.java new file mode 100644 index 00000000000..061dfc68e4c --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/MethodWithTypeP.java @@ -0,0 +1,5 @@ +package test; + +final class MethodWithTypeP { + public final

void f() {} +} diff --git a/compiler/testData/readJavaBinaryClass/MethodWithTypeP.kt b/compiler/testData/readJavaBinaryClass/MethodWithTypeP.kt new file mode 100644 index 00000000000..2c74ae0376f --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/MethodWithTypeP.kt @@ -0,0 +1,5 @@ +package test + +class MethodWithTypeP() { + fun f() = #() +} diff --git a/compiler/testData/readJavaBinaryClass/MethodWithTypePP.java b/compiler/testData/readJavaBinaryClass/MethodWithTypePP.java new file mode 100644 index 00000000000..e593cf9ec52 --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/MethodWithTypePP.java @@ -0,0 +1,5 @@ +package test; + +final class MethodWithTypePP { + public final void f() {} +} diff --git a/compiler/testData/readJavaBinaryClass/MethodWithTypePP.kt b/compiler/testData/readJavaBinaryClass/MethodWithTypePP.kt new file mode 100644 index 00000000000..c0220ae2434 --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/MethodWithTypePP.kt @@ -0,0 +1,5 @@ +package test + +class MethodWithTypePP() { + fun f() = #() +} diff --git a/compiler/testData/readJavaBinaryClass/MethodWithTypePRefClassP.java b/compiler/testData/readJavaBinaryClass/MethodWithTypePRefClassP.java new file mode 100644 index 00000000000..22ba9198274 --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/MethodWithTypePRefClassP.java @@ -0,0 +1,5 @@ +package test; + +class MethodWithTypePRefClassP

{ + public final void f() {} +} diff --git a/compiler/testData/readJavaBinaryClass/MethodWithTypePRefClassP.kt b/compiler/testData/readJavaBinaryClass/MethodWithTypePRefClassP.kt new file mode 100644 index 00000000000..c54adee8f48 --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/MethodWithTypePRefClassP.kt @@ -0,0 +1,5 @@ +package test + +open class MethodWithTypePRefClassP() { + fun f() = #() +} diff --git a/compiler/testData/readJavaBinaryClass/MethosWithPRefTP.java b/compiler/testData/readJavaBinaryClass/MethosWithPRefTP.java new file mode 100644 index 00000000000..e32fbd4b741 --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/MethosWithPRefTP.java @@ -0,0 +1,5 @@ +package test; + +final class MethosWithPRefTP { + public final

void f(P p) {} +} diff --git a/compiler/testData/readJavaBinaryClass/MethosWithPRefTP.kt b/compiler/testData/readJavaBinaryClass/MethosWithPRefTP.kt new file mode 100644 index 00000000000..34aafd20ac9 --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/MethosWithPRefTP.kt @@ -0,0 +1,5 @@ +package test + +final class MethosWithPRefTP() { + fun f(p0: P) = #() +}