From 7836e44e70ab82ed59d62d50cf8c714020cf1252 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Sat, 24 Mar 2012 02:17:47 +0400 Subject: [PATCH] Temporarily revert "kill JavaNamespaceDescriptor" This reverts commit 3c45a1d60e8eb5c53b816a62eb28cb487ed908da. This commit breaks compilation of jdk-headers. Explanation: 1. TopDownAnalyzer creates namespace java.util from sources 2. TopDownAnalyzer creates class Map in java.util 3. TopDownAnalyzer processes import java.util.Map.Entry 4. JavaDescriptorResolver resolves namespace java.util.Map 5. java.util.Map namespace is added to java.util namespace 6. redeclaration handler of namespace java.util crashes on Map --- .../jetbrains/jet/codegen/JetTypeMapper.java | 11 +- .../resolve/java/JavaBridgeConfiguration.java | 10 +- .../resolve/java/JavaClassMembersScope.java | 9 +- .../resolve/java/JavaClassOrPackageScope.java | 21 +- .../resolve/java/JavaDescriptorResolver.java | 262 ++++++++---------- .../resolve/java/JavaNamespaceDescriptor.java | 62 +++++ .../lang/resolve/java/JavaPackageScope.java | 19 +- .../jet/lang/psi/JetNamespaceHeader.java | 4 - .../jet/lang/resolve/BindingContext.java | 2 +- .../jet/lang/resolve/NamespaceFactory.java | 5 +- .../lang/resolve/NamespaceFactoryImpl.java | 24 +- .../jet/lang/resolve/TopDownAnalyzer.java | 4 +- idea/testData/completion/basic/InPackage.kt | 3 +- 13 files changed, 225 insertions(+), 211 deletions(-) create mode 100644 compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaNamespaceDescriptor.java diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index a0e8a96c844..9b3355ccd2e 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -218,11 +218,7 @@ public class JetTypeMapper { * * @see DescriptorUtils#getFQName(DeclarationDescriptor) */ - public String getFQName(@NotNull DeclarationDescriptor descriptor) { - if (descriptor instanceof ModuleDescriptor) { - throw new IllegalStateException("missed something"); - } - + public String getFQName(DeclarationDescriptor descriptor) { descriptor = descriptor.getOriginal(); if(descriptor instanceof FunctionDescriptor) { @@ -237,8 +233,11 @@ public class JetTypeMapper { if(name.contains("/")) return name; if (container != null) { + if (container.getContainingDeclaration() instanceof ModuleDescriptor) { + return name; + } if (container instanceof ModuleDescriptor) { - return ""; + throw new IllegalStateException("missed something"); } String baseName = getFQName(container); if (!baseName.isEmpty()) { diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaBridgeConfiguration.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaBridgeConfiguration.java index 7e139c7af91..68a3566205e 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaBridgeConfiguration.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaBridgeConfiguration.java @@ -21,16 +21,18 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.DefaultModuleConfiguration; import org.jetbrains.jet.lang.ModuleConfiguration; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; +import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.psi.JetImportDirective; import org.jetbrains.jet.lang.psi.JetPsiFactory; import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.DescriptorUtils; +import org.jetbrains.jet.lang.resolve.FqName; import org.jetbrains.jet.lang.resolve.ImportPath; -import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScope; import javax.inject.Inject; import java.util.Collection; +import java.util.Collections; /** * @author abreslav @@ -70,11 +72,7 @@ public class JavaBridgeConfiguration implements ModuleConfiguration { @Override public void extendNamespaceScope(@NotNull BindingTrace trace, @NotNull NamespaceDescriptor namespaceDescriptor, @NotNull WritableScope namespaceMemberScope) { - JetScope scope = javaSemanticServices.getDescriptorResolver().resolveJavaPackageScope( - DescriptorUtils.getFQName(namespaceDescriptor).toSafe(), namespaceDescriptor); - if (scope != null) { - namespaceMemberScope.importScope(scope); - } + namespaceMemberScope.importScope(javaSemanticServices.getDescriptorResolver().createJavaPackageScope(DescriptorUtils.getFQName(namespaceDescriptor).toSafe(), namespaceDescriptor)); delegateConfiguration.extendNamespaceScope(trace, namespaceDescriptor, namespaceMemberScope); } 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 e36875d0449..40338891a1e 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 @@ -42,9 +42,8 @@ public class JavaClassMembersScope extends JavaClassOrPackageScope { @NotNull ClassOrNamespaceDescriptor classOrNamespaceDescriptor, @NotNull PsiClass psiClass, @NotNull JavaSemanticServices semanticServices, - boolean staticMembers, - @NotNull JavaDescriptorResolver.ResolverScopeData resolverScopeData) { - super(classOrNamespaceDescriptor, semanticServices, psiClass, resolverScopeData); + boolean staticMembers) { + super(classOrNamespaceDescriptor, semanticServices, psiClass); this.psiClass = psiClass; this.staticMembers = staticMembers; } @@ -90,9 +89,9 @@ public class JavaClassMembersScope extends JavaClassOrPackageScope { if (allDescriptors == null) { allDescriptors = Sets.newHashSet(); - allDescriptors.addAll(semanticServices.getDescriptorResolver().resolveMethods(psiClass, descriptor, getResolverScopeData())); + allDescriptors.addAll(semanticServices.getDescriptorResolver().resolveMethods(psiClass, descriptor)); - allDescriptors.addAll(semanticServices.getDescriptorResolver().resolveFieldGroup(descriptor, psiClass, staticMembers, getResolverScopeData())); + allDescriptors.addAll(semanticServices.getDescriptorResolver().resolveFieldGroup(descriptor, psiClass, staticMembers)); allDescriptors.addAll(semanticServices.getDescriptorResolver().resolveInnerClasses(descriptor, psiClass, 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 4c90c89ddf4..e9c93d3b6fd 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 @@ -39,18 +39,12 @@ public abstract class JavaClassOrPackageScope extends JetScopeImpl { protected final JavaSemanticServices semanticServices; @Nullable protected final PsiClass psiClass; - @NotNull - private final JavaDescriptorResolver.ResolverScopeData resolverScopeData; - protected JavaClassOrPackageScope( - @NotNull ClassOrNamespaceDescriptor descriptor, - @NotNull JavaSemanticServices semanticServices, - @Nullable PsiClass psiClass, - @NotNull JavaDescriptorResolver.ResolverScopeData resolverScopeData) { + protected JavaClassOrPackageScope(@NotNull ClassOrNamespaceDescriptor descriptor, @NotNull JavaSemanticServices semanticServices, + @Nullable PsiClass psiClass) { this.descriptor = descriptor; this.semanticServices = semanticServices; this.psiClass = psiClass; - this.resolverScopeData = resolverScopeData; JavaDescriptorResolver.checkPsiClassIsNotJet(psiClass); } @@ -72,7 +66,7 @@ public abstract class JavaClassOrPackageScope extends JetScopeImpl { // TODO: cache return semanticServices.getDescriptorResolver().resolveFieldGroupByName( - descriptor, psiClass, name, staticMembers(), getResolverScopeData()); + descriptor, psiClass, name, staticMembers()); } @NotNull @@ -83,14 +77,7 @@ public abstract class JavaClassOrPackageScope extends JetScopeImpl { return Collections.emptySet(); } - return semanticServices.getDescriptorResolver().resolveFunctionGroup( - descriptor, psiClass, name, staticMembers(), getResolverScopeData()); - } - - @NotNull - protected JavaDescriptorResolver.ResolverScopeData getResolverScopeData() { - semanticServices.getDescriptorResolver().initializeResolverScopeData(resolverScopeData, psiClass, staticMembers()); - return resolverScopeData; + return semanticServices.getDescriptorResolver().resolveFunctionGroup(descriptor, psiClass, name, staticMembers()); } } 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 c688092c3b6..03ebd7ec9ec 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 @@ -34,7 +34,6 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.psi.JetPsiUtil; import org.jetbrains.jet.lang.resolve.*; import org.jetbrains.jet.lang.resolve.constants.*; -import org.jetbrains.jet.lang.resolve.constants.StringValue; import org.jetbrains.jet.lang.resolve.java.alt.AltClassFinder; import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation; import org.jetbrains.jet.lang.types.*; @@ -119,7 +118,7 @@ public class JavaDescriptorResolver { } - static abstract class ResolverScopeData { + private static abstract class ResolverScopeData { protected boolean kotlin; private Map namedMembersMap; @@ -174,8 +173,7 @@ public class JavaDescriptorResolver { /** Either package or class with static members */ private static class ResolverNamespaceData extends ResolverScopeData { - private NamespaceDescriptor namespaceDescriptor; - private JavaClassOrPackageScope scope; + private JavaNamespaceDescriptor namespaceDescriptor; @NotNull public NamespaceDescriptor getNamespaceDescriptor() { @@ -367,7 +365,7 @@ public class JavaDescriptorResolver { } classData.classDescriptor.setModality(modality); classData.classDescriptor.createTypeConstructor(); - classData.classDescriptor.setScopeForMemberLookup(new JavaClassMembersScope(classData.classDescriptor, psiClass, semanticServices, false, classData)); + classData.classDescriptor.setScopeForMemberLookup(new JavaClassMembersScope(classData.classDescriptor, psiClass, semanticServices, false)); initializeTypeParameters(classData.typeParameters, classData.classDescriptor, "class " + psiClass.getQualifiedName()); @@ -515,7 +513,7 @@ public class JavaDescriptorResolver { classData.classDescriptor.setModality(Modality.FINAL); classData.classDescriptor.setTypeParameterDescriptors(new ArrayList(0)); classData.classDescriptor.createTypeConstructor(); - classData.classDescriptor.setScopeForMemberLookup(new JavaClassMembersScope(classData.classDescriptor, classObjectPsiClass, semanticServices, false, classData)); + classData.classDescriptor.setScopeForMemberLookup(new JavaClassMembersScope(classData.classDescriptor, classObjectPsiClass, semanticServices, false)); // TODO: wrong: class objects do not need visible constructors ConstructorDescriptorImpl constructor = new ConstructorDescriptorImpl(classData.classDescriptor, new ArrayList(0), true); @@ -841,12 +839,13 @@ public class JavaDescriptorResolver { } } - PsiClassOrPsiPackage psiElement = findPsiElementForNamespace(qualifiedName); - if (psiElement == null) { - return null; + PsiPackage psiPackage = findPackage(qualifiedName); + if (psiPackage == null) { + PsiClass psiClass = findClass(qualifiedName); + if (psiClass == null) return null; + return resolveNamespace(psiClass); } - - return resolveNamespace(psiElement); + return resolveNamespace(psiPackage); } @Nullable @@ -876,102 +875,81 @@ public class JavaDescriptorResolver { return javaFacade.findPackage(qualifiedName.getFqName()); } - @Nullable - private PsiClassOrPsiPackage findPsiElementForNamespace(@NotNull FqName fqName) { - PsiPackage psiPackage = findPackage(fqName); - if (psiPackage != null) { - return new PsiClassOrPsiPackage(psiPackage); + private NamespaceDescriptor resolveNamespace(@NotNull PsiPackage psiPackage) { + ResolverNamespaceData namespaceData = namespaceDescriptorCache.get(psiPackage); + if (namespaceData == null) { + namespaceData = createJavaNamespaceDescriptor(psiPackage); + namespaceDescriptorCache.put(psiPackage, namespaceData); + namespaceDescriptorCacheByFqn.put(new FqName(psiPackage.getQualifiedName()), namespaceData); } - PsiClass psiClass = findClass(fqName); - if (psiClass != null) { - return new PsiClassOrPsiPackage(psiClass); + return namespaceData.namespaceDescriptor; + } + + private NamespaceDescriptor resolveNamespace(@NotNull PsiClass psiClass) { + ResolverNamespaceData namespaceData = namespaceDescriptorCache.get(psiClass); + if (namespaceData == null) { + namespaceData = createJavaNamespaceDescriptor(psiClass); + namespaceDescriptorCache.put(psiClass, namespaceData); + namespaceDescriptorCacheByFqn.put(new FqName(psiClass.getQualifiedName()), namespaceData); } - return null; + return namespaceData.namespaceDescriptor; + } + + private ResolverNamespaceData createJavaNamespaceDescriptor(@NotNull PsiPackage psiPackage) { + ResolverNamespaceData namespaceData = new ResolverNamespaceData(); + String name = psiPackage.getName(); + namespaceData.namespaceDescriptor = new JavaNamespaceDescriptor( + (NamespaceDescriptorParent) resolveParentDescriptor(psiPackage), + Collections.emptyList(), // TODO + name == null ? JAVA_ROOT : name, + name == null ? FqName.ROOT : new FqName(psiPackage.getQualifiedName()), + true + ); + trace.record(JavaBindingContext.NAMESPACE_IS_CLASS_STATICS, namespaceData.namespaceDescriptor, false); + + namespaceData.namespaceDescriptor.setMemberScope(createJavaPackageScope(new FqName(psiPackage.getQualifiedName()), namespaceData.namespaceDescriptor)); + trace.record(BindingContext.NAMESPACE, psiPackage, namespaceData.namespaceDescriptor); + // TODO: hack + namespaceData.kotlin = true; + return namespaceData; + } + + public JavaPackageScope createJavaPackageScope(@NotNull FqName fqName, @NotNull NamespaceDescriptor ns) { + return new JavaPackageScope(fqName, ns, semanticServices); } @NotNull - private NamespaceDescriptor resolveNamespace(@NotNull PsiClassOrPsiPackage psi) { - return namespaceFactory.createNamespaceDescriptorPathIfNeeded(psi.getFqName(), psi.getPsiElement()); + private DeclarationDescriptor resolveParentDescriptor(@NotNull PsiPackage psiPackage) { + PsiPackage parentPackage = psiPackage.getParentPackage(); + if (parentPackage == null) { + return FAKE_ROOT_MODULE; + } + return resolveNamespace(parentPackage); } - private static class PsiClassOrPsiPackage { - @NotNull - private final PsiElement psiElement; - @NotNull - private final FqName fqName; + /** + * TODO + * @see #createClassObjectDescriptor(org.jetbrains.jet.lang.descriptors.ClassDescriptor, com.intellij.psi.PsiClass) + */ + private ResolverNamespaceData createJavaNamespaceDescriptor(@NotNull final PsiClass psiClass) { - private PsiClassOrPsiPackage(@NotNull PsiClass psiElement) { - this.psiElement = psiElement; - this.fqName = new FqName(psiElement.getQualifiedName()); - } + checkPsiClassIsNotJet(psiClass); - private PsiClassOrPsiPackage(@NotNull PsiPackage psiElement) { - this.psiElement = psiElement; - this.fqName = new FqName(psiElement.getQualifiedName()); - } + ResolverNamespaceData namespaceData = new ResolverNamespaceData(); + namespaceData.namespaceDescriptor = new JavaNamespaceDescriptor( + (NamespaceDescriptorParent) resolveParentDescriptor(psiClass), + Collections.emptyList(), // TODO + psiClass.getName(), + new FqName(psiClass.getQualifiedName()), + false + ); + trace.record(JavaBindingContext.NAMESPACE_IS_CLASS_STATICS, namespaceData.namespaceDescriptor, true); - public boolean isClass() { - return psiElement instanceof PsiClass; - } - - public boolean isPackage() { - return psiElement instanceof PsiPackage; - } - - @NotNull - public PsiClass getPsiClass() { - return (PsiClass)psiElement; - } - - @NotNull - public PsiPackage getPsiPackage() { - return (PsiPackage)psiElement; - } - - @NotNull - public PsiElement getPsiElement() { - return psiElement; - } - - @NotNull - public FqName getFqName() { - return fqName; - } + namespaceData.namespaceDescriptor.setMemberScope(new JavaClassMembersScope(namespaceData.namespaceDescriptor, psiClass, semanticServices, true)); + trace.record(BindingContext.NAMESPACE, psiClass, namespaceData.namespaceDescriptor); + return namespaceData; } - - @Nullable - public JavaClassOrPackageScope resolveJavaPackageScope(@NotNull FqName fqName, @NotNull NamespaceDescriptor namespace) { - PsiClassOrPsiPackage psi = findPsiElementForNamespace(fqName); - if (psi == null) { - return null; - } - - ResolverNamespaceData namespaceData = namespaceDescriptorCacheByFqn.get(fqName); - if (namespaceData != null) { - throw new IllegalStateException("cache must be empty for ns " + fqName); - } - - namespaceData = new ResolverNamespaceData(); - namespaceDescriptorCache.put(psi.getPsiElement(), namespaceData); - namespaceDescriptorCacheByFqn.put(fqName, namespaceData); - - if (psi.isClass()) { - checkPsiClassIsNotJet(psi.getPsiClass()); - } - - namespaceData.namespaceDescriptor = namespace; - namespaceData.kotlin = psi.isPackage(); - trace.record(JavaBindingContext.NAMESPACE_IS_CLASS_STATICS, namespaceData.namespaceDescriptor, psi.isClass()); - - if (psi.isClass()) { - namespaceData.scope = new JavaClassMembersScope(namespace, psi.getPsiClass(), semanticServices, true, namespaceData); - } else { - namespaceData.scope = new JavaPackageScope(fqName, namespace, semanticServices, namespaceData); - } - - return namespaceData.scope; - } - + private static class ValueParameterDescriptors { private final JetType receiverType; private final List descriptors; @@ -1074,12 +1052,8 @@ public class JavaDescriptorResolver { } } - public Set resolveFieldGroupByName( - @NotNull ClassOrNamespaceDescriptor owner, - @NotNull PsiClass psiClass, - String fieldName, - boolean staticMembers, - @NotNull ResolverScopeData scopeData) { + public Set resolveFieldGroupByName(@NotNull ClassOrNamespaceDescriptor owner, @NotNull PsiClass psiClass, String fieldName, boolean staticMembers) { + ResolverScopeData scopeData = getResolverScopeData(owner, new PsiClassWrapper(psiClass)); NamedMembers namedMembers = scopeData.namedMembersMap.get(fieldName); if (namedMembers == null) { @@ -1099,12 +1073,10 @@ public class JavaDescriptorResolver { } @NotNull - public Set resolveFieldGroup( - @NotNull ClassOrNamespaceDescriptor owner, - @NotNull PsiClass psiClass, - boolean staticMembers, - @NotNull ResolverScopeData scopeData) { + public Set resolveFieldGroup(@NotNull ClassOrNamespaceDescriptor owner, @NotNull PsiClass psiClass, boolean staticMembers) { + ResolverScopeData scopeData = getResolverScopeData(owner, new PsiClassWrapper(psiClass)); + Set descriptors = Sets.newHashSet(); Map membersForProperties = scopeData.namedMembersMap; for (Map.Entry entry : membersForProperties.entrySet()) { @@ -1358,7 +1330,7 @@ public class JavaDescriptorResolver { namedMembers.propertyDescriptors = r; } - private void resolveNamedGroupFunctions(ClassOrNamespaceDescriptor owner, PsiClass psiClass, NamedMembers namedMembers, String methodName, ResolverScopeData scopeData) { + private void resolveNamedGroupFunctions(ClassOrNamespaceDescriptor owner, PsiClass psiClass, TypeSubstitutor typeSubstitutorForGenericSuperclasses, NamedMembers namedMembers, String methodName, ResolverScopeData scopeData) { if (namedMembers.functionDescriptors != null) { return; } @@ -1367,7 +1339,8 @@ public class JavaDescriptorResolver { Set functionsFromCurrent = Sets.newHashSet(); for (PsiMethodWrapper method : namedMembers.methods) { - FunctionDescriptorImpl function = resolveMethodToFunctionDescriptor(owner, psiClass, method, scopeData); + FunctionDescriptorImpl function = resolveMethodToFunctionDescriptor(owner, psiClass, + method); if (function != null) { functionsFromCurrent.add((SimpleFunctionDescriptor) function); } @@ -1407,30 +1380,42 @@ public class JavaDescriptorResolver { return r; } - void initializeResolverScopeData(@NotNull ResolverScopeData scopeData, @Nullable PsiClass psiClass, boolean staticMembers) { - if (scopeData.namedMembersMap == null) { - if (psiClass != null) { - scopeData.namedMembersMap = JavaDescriptorResolverHelper.getNamedMembers( - new PsiClassWrapper(psiClass), staticMembers, scopeData.kotlin); - } else { - scopeData.namedMembersMap = Maps.newHashMap(); - } + private ResolverScopeData getResolverScopeData(@NotNull ClassOrNamespaceDescriptor owner, PsiClassWrapper psiClass) { + // TODO: store scopeData in Java*Scope + ResolverScopeData scopeData; + boolean staticMembers; + if (owner instanceof JavaNamespaceDescriptor) { + scopeData = namespaceDescriptorCacheByFqn.get(((JavaNamespaceDescriptor) owner).getQualifiedName()); + staticMembers = true; + } else if (owner instanceof ClassDescriptor) { + scopeData = classDescriptorCache.get(new FqName(psiClass.getQualifiedName())); + staticMembers = false; + } else { + throw new IllegalStateException("unknown owner: " + owner.getClass().getName()); } + if (scopeData == null) { + throw new IllegalStateException(); + } + + if (scopeData.namedMembersMap == null) { + scopeData.namedMembersMap = JavaDescriptorResolverHelper.getNamedMembers(psiClass, staticMembers, scopeData.kotlin); + } + + return scopeData; } @NotNull - public Set resolveFunctionGroup( - @NotNull ClassOrNamespaceDescriptor descriptor, - @NotNull PsiClass psiClass, - @NotNull String methodName, - boolean staticMembers, - @NotNull ResolverScopeData scopeData) { + public Set resolveFunctionGroup(@NotNull ClassOrNamespaceDescriptor descriptor, @NotNull PsiClass psiClass, @NotNull String methodName, boolean staticMembers) { - Map namedMembersMap = scopeData.namedMembersMap; + ResolverScopeData resolverScopeData = getResolverScopeData(descriptor, new PsiClassWrapper(psiClass)); + + Map namedMembersMap = resolverScopeData.namedMembersMap; NamedMembers namedMembers = namedMembersMap.get(methodName); if (namedMembers != null && namedMembers.methods != null) { - resolveNamedGroupFunctions(descriptor, psiClass, namedMembers, methodName, scopeData); + TypeSubstitutor typeSubstitutor = typeSubstitutorForGenericSupertypes(resolverScopeData); + + resolveNamedGroupFunctions(descriptor, psiClass, typeSubstitutor, namedMembers, methodName, resolverScopeData); return namedMembers.functionDescriptors; } else { @@ -1474,24 +1459,20 @@ public class JavaDescriptorResolver { } @Nullable - private FunctionDescriptorImpl resolveMethodToFunctionDescriptor( - ClassOrNamespaceDescriptor owner, - final PsiClass psiClass, - final PsiMethodWrapper method, - @NotNull ResolverScopeData scopeData) { + private FunctionDescriptorImpl resolveMethodToFunctionDescriptor(ClassOrNamespaceDescriptor owner, final PsiClass psiClass, final PsiMethodWrapper method) { PsiType returnType = method.getReturnType(); if (returnType == null) { return null; } + ResolverScopeData scopeData = getResolverScopeData(owner, new PsiClassWrapper(psiClass)); boolean kotlin; - if (owner instanceof NamespaceDescriptor) { - NamespaceDescriptor javaNamespaceDescriptor = (NamespaceDescriptor) owner; - FqName fqName = DescriptorUtils.getFQName(javaNamespaceDescriptor).toSafe(); - ResolverNamespaceData namespaceData = namespaceDescriptorCacheByFqn.get(fqName); + if (owner instanceof JavaNamespaceDescriptor) { + JavaNamespaceDescriptor javaNamespaceDescriptor = (JavaNamespaceDescriptor) owner; + ResolverNamespaceData namespaceData = namespaceDescriptorCacheByFqn.get(javaNamespaceDescriptor.getQualifiedName()); if (namespaceData == null) { - throw new IllegalStateException("namespaceData not found by name " + fqName); + throw new IllegalStateException("namespaceData not found by name " + javaNamespaceDescriptor.getQualifiedName()); } kotlin = namespaceData.kotlin; } else { @@ -1521,7 +1502,7 @@ public class JavaDescriptorResolver { classDescriptor = classClassDescriptor; } else { - classDescriptor = resolveNamespace(new PsiClassOrPsiPackage(method.getPsiMethod().getContainingClass())); + classDescriptor = resolveNamespace(method.getPsiMethod().getContainingClass()); } if (classDescriptor == null) { return null; @@ -1620,10 +1601,9 @@ public class JavaDescriptorResolver { return annotation; } - public List resolveMethods( - @NotNull PsiClass psiClass, - @NotNull ClassOrNamespaceDescriptor containingDeclaration, - @NotNull ResolverScopeData scopeData) { + public List resolveMethods(@NotNull PsiClass psiClass, @NotNull ClassOrNamespaceDescriptor containingDeclaration) { + ResolverScopeData scopeData = getResolverScopeData(containingDeclaration, new PsiClassWrapper(psiClass)); + TypeSubstitutor substitutorForGenericSupertypes = typeSubstitutorForGenericSupertypes(scopeData); List functions = new ArrayList(); @@ -1631,7 +1611,7 @@ public class JavaDescriptorResolver { for (Map.Entry entry : scopeData.namedMembersMap.entrySet()) { String methodName = entry.getKey(); NamedMembers namedMembers = entry.getValue(); - resolveNamedGroupFunctions(containingDeclaration, psiClass, namedMembers, methodName, scopeData); + resolveNamedGroupFunctions(containingDeclaration, psiClass, substitutorForGenericSupertypes, namedMembers, methodName, scopeData); functions.addAll(namedMembers.functionDescriptors); } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaNamespaceDescriptor.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaNamespaceDescriptor.java new file mode 100644 index 00000000000..19db2430f59 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaNamespaceDescriptor.java @@ -0,0 +1,62 @@ +/* + * Copyright 2010-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.lang.resolve.java; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.AbstractNamespaceDescriptorImpl; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.descriptors.NamespaceDescriptorParent; +import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; +import org.jetbrains.jet.lang.resolve.FqName; +import org.jetbrains.jet.lang.resolve.scopes.JetScope; + +import java.util.List; + +/** + * @author abreslav + */ +public class JavaNamespaceDescriptor extends AbstractNamespaceDescriptorImpl { + private JetScope memberScope; + private final FqName qualifiedName; + /** Namespace of class with static methods */ + private final boolean namespace; + + public JavaNamespaceDescriptor(NamespaceDescriptorParent containingDeclaration, List annotations, + @NotNull String name, @NotNull FqName qualifiedName, boolean namespace) { + super(containingDeclaration, annotations, name); + this.qualifiedName = qualifiedName; + this.namespace = namespace; + } + + public void setMemberScope(@NotNull JetScope memberScope) { + this.memberScope = memberScope; + } + + @NotNull + @Override + public JetScope getMemberScope() { + return memberScope; + } + + public FqName getQualifiedName() { + return qualifiedName; + } + + public boolean isNamespace() { + return namespace; + } +} 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 a7a5132afaf..84bfb74654e 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 @@ -46,18 +46,21 @@ public class JavaPackageScope extends JavaClassOrPackageScope { public JavaPackageScope( @NotNull FqName packageFQN, @NotNull NamespaceDescriptor containingDescriptor, - @NotNull JavaSemanticServices semanticServices, - @NotNull JavaDescriptorResolver.ResolverScopeData resolverScopeData) { - super(containingDescriptor, semanticServices, getPiClass(packageFQN, semanticServices), resolverScopeData); + @NotNull JavaSemanticServices semanticServices) { + super(containingDescriptor, semanticServices, getPiClass(packageFQN, semanticServices)); this.packageFQN = packageFQN; } private static PsiClass getPiClass(FqName packageFQN, JavaSemanticServices semanticServices) { - PsiClass psiClass = semanticServices.getDescriptorResolver().findClass(getQualifiedName(packageFQN, JvmAbi.PACKAGE_CLASS)); - if (psiClass instanceof JetJavaMirrorMarker) { + // TODO: move this check outside + // If this package is actually a Kotlin namespace, then we access it through a namespace descriptor, and + // Kotlin functions are already there + NamespaceDescriptor kotlinNamespaceDescriptor = semanticServices.getKotlinNamespaceDescriptor(packageFQN); + if (kotlinNamespaceDescriptor != null) { return null; } else { - return psiClass; + // TODO: what is GlobalSearchScope + return semanticServices.getDescriptorResolver().javaFacade.findClass(getQualifiedName(packageFQN, JvmAbi.PACKAGE_CLASS).getFqName()); } } @@ -99,9 +102,9 @@ public class JavaPackageScope extends JavaClassOrPackageScope { allDescriptors = Sets.newHashSet(); if (psiClass != null) { - allDescriptors.addAll(semanticServices.getDescriptorResolver().resolveMethods(psiClass, descriptor, getResolverScopeData())); + allDescriptors.addAll(semanticServices.getDescriptorResolver().resolveMethods(psiClass, descriptor)); - allDescriptors.addAll(semanticServices.getDescriptorResolver().resolveFieldGroup(descriptor, psiClass, staticMembers(), getResolverScopeData())); + allDescriptors.addAll(semanticServices.getDescriptorResolver().resolveFieldGroup(descriptor, psiClass, staticMembers())); } final PsiPackage javaPackage = semanticServices.getDescriptorResolver().findPackage(packageFQN); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetNamespaceHeader.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetNamespaceHeader.java index 2cc13c6f2fc..97dc2a7e749 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetNamespaceHeader.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetNamespaceHeader.java @@ -59,10 +59,6 @@ public class JetNamespaceHeader extends JetReferenceExpression { return findChildByType(JetTokens.IDENTIFIER); } - public boolean isRoot() { - return getNameIdentifier() == null; - } - @Override public String getName() { PsiElement nameIdentifier = getNameIdentifier(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java index 7037ec1290c..cf6ba13c1e1 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java @@ -172,7 +172,7 @@ public interface BindingContext { WritableSlice VALUE_PARAMETER_AS_PROPERTY = Slices.sliceBuilder().build(); WritableSlice FQNAME_TO_CLASS_DESCRIPTOR = new BasicWritableSlice(DO_NOTHING, true); - WritableSlice FQNAME_TO_NAMESPACE_DESCRIPTOR = new BasicWritableSlice(Slices.ONLY_REWRITE_TO_EQUAL); + WritableSlice FQNAME_TO_NAMESPACE_DESCRIPTOR = new BasicWritableSlice(DO_NOTHING); /** * Each namespace found in src must be registered here. diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/NamespaceFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/NamespaceFactory.java index 69b6d122884..53ae6be294f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/NamespaceFactory.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/NamespaceFactory.java @@ -16,9 +16,7 @@ package org.jetbrains.jet.lang.resolve; -import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptorImpl; /** @@ -26,6 +24,5 @@ import org.jetbrains.jet.lang.descriptors.NamespaceDescriptorImpl; */ public interface NamespaceFactory { @NotNull - NamespaceDescriptorImpl createNamespaceDescriptorPathIfNeeded( - @NotNull FqName fqName, @Nullable PsiElement declaration); + NamespaceDescriptorImpl createNamespaceDescriptorPathIfNeeded(@NotNull FqName fqName); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/NamespaceFactoryImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/NamespaceFactoryImpl.java index 6bedf2192bd..2abde869b54 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/NamespaceFactoryImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/NamespaceFactoryImpl.java @@ -16,7 +16,6 @@ package org.jetbrains.jet.lang.resolve; -import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.ModuleConfiguration; @@ -69,7 +68,7 @@ public class NamespaceFactoryImpl implements NamespaceFactory { JetNamespaceHeader namespaceHeader = file.getNamespaceHeader(); if (moduleDescriptor.getRootNs() == null) { - createNamespaceDescriptorIfNeeded(null, null, moduleDescriptor, "", true); + createNamespaceDescriptorIfNeeded(null, moduleDescriptor, "", true); } NamespaceDescriptorParent currentOwner = moduleDescriptor.getRootNs(); @@ -80,7 +79,7 @@ public class NamespaceFactoryImpl implements NamespaceFactory { for (JetSimpleNameExpression nameExpression : namespaceHeader.getParentNamespaceNames()) { String namespaceName = JetPsiUtil.safeName(nameExpression.getReferencedName()); - NamespaceDescriptorImpl namespaceDescriptor = createNamespaceDescriptorIfNeeded(null, null, currentOwner, namespaceName, false); + NamespaceDescriptorImpl namespaceDescriptor = createNamespaceDescriptorIfNeeded(null, currentOwner, namespaceName, false); trace.record(BindingContext.NAMESPACE_IS_SRC, namespaceDescriptor, true); currentOwner = namespaceDescriptor; @@ -94,8 +93,7 @@ public class NamespaceFactoryImpl implements NamespaceFactory { String name = JetPsiUtil.safeName(namespaceHeader.getName()); trace.record(RESOLUTION_SCOPE, namespaceHeader, outerScope); - NamespaceDescriptorImpl namespaceDescriptor = - createNamespaceDescriptorIfNeeded(file, file, namespaceHeader.isRoot() ? moduleDescriptor : currentOwner, name, namespaceHeader.isRoot()); + NamespaceDescriptorImpl namespaceDescriptor = createNamespaceDescriptorIfNeeded(file, currentOwner, name, false); trace.record(BindingContext.NAMESPACE_IS_SRC, namespaceDescriptor, true); return namespaceDescriptor; @@ -103,21 +101,17 @@ public class NamespaceFactoryImpl implements NamespaceFactory { @Override @NotNull - public NamespaceDescriptorImpl createNamespaceDescriptorPathIfNeeded( - @NotNull FqName fqName, @Nullable PsiElement declaration) { + public NamespaceDescriptorImpl createNamespaceDescriptorPathIfNeeded(@NotNull FqName fqName) { NamespaceDescriptorParent owner = moduleDescriptor; for (FqName pathElement : fqName.path()) { - boolean needDeclaration = pathElement.equals(fqName); - owner = createNamespaceDescriptorIfNeeded(null, needDeclaration ? declaration : null, + owner = createNamespaceDescriptorIfNeeded(null, owner, pathElement.isRoot() ? "" : pathElement.shortName(), pathElement.isRoot()); } return (NamespaceDescriptorImpl) owner; } @NotNull - public NamespaceDescriptorImpl createNamespaceDescriptorIfNeeded( - @Nullable JetFile file, @Nullable PsiElement declaration, - @NotNull NamespaceDescriptorParent owner, @NotNull String name, boolean root) { + public NamespaceDescriptorImpl createNamespaceDescriptorIfNeeded(@Nullable JetFile file, @NotNull NamespaceDescriptorParent owner, @NotNull String name, boolean root) { FqName fqName; NamespaceDescriptorImpl namespaceDescriptor; @@ -126,7 +120,7 @@ public class NamespaceFactoryImpl implements NamespaceFactory { throw new IllegalStateException(); } fqName = FqName.ROOT; - namespaceDescriptor = (NamespaceDescriptorImpl) trace.get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, FqName.ROOT); + namespaceDescriptor = ((ModuleDescriptor) owner).getRootNs(); } else { FqName ownerFqName = DescriptorUtils.getFQName(owner).toSafe(); @@ -146,8 +140,8 @@ public class NamespaceFactoryImpl implements NamespaceFactory { namespaceDescriptor.initialize(scope); configuration.extendNamespaceScope(trace, namespaceDescriptor, scope); owner.addNamespace(namespaceDescriptor); - if (declaration != null) { - trace.record(BindingContext.NAMESPACE, declaration, namespaceDescriptor); + if (file != null) { + trace.record(BindingContext.NAMESPACE, file, namespaceDescriptor); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java index 639304373f4..fb7fc0dd049 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java @@ -297,11 +297,11 @@ public class TopDownAnalyzer { new TraceBasedRedeclarationHandler(trace)).setDebugName("Root scope in analyzeNamespace"); scope.changeLockLevel(WritableScope.LockLevel.BOTH); - NamespaceDescriptorImpl rootNs = namespaceFactory.createNamespaceDescriptorPathIfNeeded(FqName.ROOT, null); + NamespaceDescriptorImpl rootNs = namespaceFactory.createNamespaceDescriptorPathIfNeeded(FqName.ROOT); // map "jet" namespace into JetStandardLibrary/Classes // @see DefaultModuleConfiguraiton#extendNamespaceScope - namespaceFactory.createNamespaceDescriptorPathIfNeeded(JetStandardClasses.STANDARD_CLASSES_FQNAME, null); + namespaceFactory.createNamespaceDescriptorPathIfNeeded(JetStandardClasses.STANDARD_CLASSES_FQNAME); // Import a scope that contains all top-level namespaces that come from dependencies // This makes the namespaces visible at all, does not import themselves diff --git a/idea/testData/completion/basic/InPackage.kt b/idea/testData/completion/basic/InPackage.kt index 08f0ec0700b..ce800ff38d9 100644 --- a/idea/testData/completion/basic/InPackage.kt +++ b/idea/testData/completion/basic/InPackage.kt @@ -7,5 +7,4 @@ class Test { } // EXIST: concurrent -// ABSENT: TodoAbstractList, Date, Random, import -// TODO: add AbstractList back to ABSENT +// ABSENT: AbstractList, Date, Random, import