From 6424e0fe222689349af35790389b758f12a5f94a Mon Sep 17 00:00:00 2001 From: "Pavel V. Talanov" Date: Sat, 6 Oct 2012 19:13:43 +0400 Subject: [PATCH] Extract NamespaceResolver class from JavaDescriptorResolver --- .../java/JavaDescriptorResolveData.java | 8 +- .../resolve/java/JavaDescriptorResolver.java | 121 ++----------- .../java/resolver/NamespaceResolver.java | 170 ++++++++++++++++++ 3 files changed, 185 insertions(+), 114 deletions(-) create mode 100644 compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/NamespaceResolver.java diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolveData.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolveData.java index ef88c7277c2..0c2739dcfab 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolveData.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolveData.java @@ -190,14 +190,14 @@ public class JavaDescriptorResolveData { /** * Either package or class with static members */ - static class ResolverNamespaceData extends ResolverScopeData { - static final ResolverNamespaceData NEGATIVE = new ResolverNamespaceData(true); + public static class ResolverNamespaceData extends ResolverScopeData { + public static final ResolverNamespaceData NEGATIVE = new ResolverNamespaceData(true); private final NamespaceDescriptor namespaceDescriptor; private JavaPackageScope memberScope; - ResolverNamespaceData( + public ResolverNamespaceData( @Nullable PsiClass psiClass, @Nullable PsiPackage psiPackage, @NotNull FqName fqName, @@ -212,7 +212,7 @@ public class JavaDescriptorResolveData { this.namespaceDescriptor = null; } - JavaPackageScope getMemberScope() { + public JavaPackageScope getMemberScope() { return memberScope; } 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 8a565f00bf0..6a25c5e46f1 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 @@ -37,7 +37,6 @@ import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolveData.ResolverNam import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolveData.ResolverScopeData; import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolveData.ResolverSyntheticClassObjectClassData; import org.jetbrains.jet.lang.resolve.java.descriptor.ClassDescriptorFromJvmBytecode; -import org.jetbrains.jet.lang.resolve.java.descriptor.JavaNamespaceDescriptor; import org.jetbrains.jet.lang.resolve.java.kt.PsiAnnotationWithFlags; import org.jetbrains.jet.lang.resolve.java.resolver.*; import org.jetbrains.jet.lang.resolve.java.scope.JavaClassMembersScope; @@ -123,12 +122,13 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes private BindingTrace trace; private PsiClassFinder psiClassFinder; private JavaDescriptorSignatureResolver javaDescriptorSignatureResolver; - private PropertiesResolver propertiesResolver = new PropertiesResolver(this); + private final PropertiesResolver propertiesResolver = new PropertiesResolver(this); private final ClassResolver classResolver = new ClassResolver(this); private final ConstructorResolver constructorResolver = new ConstructorResolver(this); private final CompileTimeConstResolver compileTimeConstResolver = new CompileTimeConstResolver(this); private final AnnotationResolver annotationResolver = new AnnotationResolver(this); private final FunctionResolver functionResolver = new FunctionResolver(this); + private final NamespaceResolver namespaceResolver = new NamespaceResolver(this); @Inject public void setProject(Project project) { @@ -216,6 +216,10 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes return annotationResolver; } + public Map getNamespaceDescriptorCacheByFqn() { + return namespaceDescriptorCacheByFqn; + } + public static void checkPsiClassIsNotJet(PsiClass psiClass) { if (psiClass instanceof JetJavaMirrorMarker) { throw new IllegalStateException("trying to resolve fake jet PsiClass as regular PsiClass: " + psiClass.getQualifiedName()); @@ -361,7 +365,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes return clazz; } - NamespaceDescriptor ns = resolveNamespace(fqName.parent(), DescriptorSearchRule.INCLUDE_KOTLIN); + NamespaceDescriptor ns = namespaceResolver.resolveNamespace(fqName.parent(), DescriptorSearchRule.INCLUDE_KOTLIN); if (ns == null) { throw new IllegalStateException("cannot resolve namespace " + fqName.parent() + ", required to be container for " + fqName); } @@ -462,125 +466,22 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes @Nullable public NamespaceDescriptor resolveNamespace(@NotNull FqName qualifiedName, @NotNull DescriptorSearchRule searchRule) { // First, let's check that there is no Kotlin package: - NamespaceDescriptor kotlinNamespaceDescriptor = semanticServices.getKotlinNamespaceDescriptor(qualifiedName); - if (kotlinNamespaceDescriptor != null) { - if (searchRule == DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN) { - throw new IllegalStateException("class must not be found in kotlin: " + qualifiedName); - } - else if (searchRule == DescriptorSearchRule.IGNORE_IF_FOUND_IN_KOTLIN) { - return null; - } - else if (searchRule == DescriptorSearchRule.INCLUDE_KOTLIN) { - // TODO: probably this is evil - return kotlinNamespaceDescriptor; - } - else { - throw new IllegalStateException("unknown searchRule: " + searchRule); - } - } - ResolverNamespaceData namespaceData = namespaceDescriptorCacheByFqn.get(qualifiedName); - if (namespaceData != null) { - return namespaceData.getNamespaceDescriptor(); - } - - NamespaceDescriptorParent parentNs = resolveParentNamespace(qualifiedName); - if (parentNs == null) { - return null; - } - - JavaNamespaceDescriptor ns = new JavaNamespaceDescriptor( - parentNs, - Collections.emptyList(), // TODO - qualifiedName - ); - - ResolverNamespaceData scopeData = createNamespaceResolverScopeData(qualifiedName, ns); - if (scopeData == null) { - return null; - } - - trace.record(BindingContext.NAMESPACE, scopeData.getPsiPackageOrPsiClass(), ns); - - ns.setMemberScope(scopeData.getMemberScope()); - - return scopeData.getNamespaceDescriptor(); + return namespaceResolver.resolveNamespace(qualifiedName, searchRule); } @Override public NamespaceDescriptor resolveNamespace(@NotNull FqName qualifiedName) { - return resolveNamespace(qualifiedName, DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN); - } - - private NamespaceDescriptorParent resolveParentNamespace(FqName fqName) { - if (fqName.isRoot()) { - return FAKE_ROOT_MODULE; - } - else { - return resolveNamespace(fqName.parent(), DescriptorSearchRule.INCLUDE_KOTLIN); - } - } - - @Nullable - private ResolverNamespaceData createNamespaceResolverScopeData(@NotNull FqName fqName, @NotNull NamespaceDescriptor ns) { - PsiPackage psiPackage; - PsiClass psiClass; - - lookingForPsi: - { - psiClass = getPsiClassForJavaPackageScope(fqName); - psiPackage = semanticServices.getPsiClassFinder().findPsiPackage(fqName); - if (psiClass != null || psiPackage != null) { - trace.record(JavaBindingContext.JAVA_NAMESPACE_KIND, ns, JavaNamespaceKind.PROPER); - break lookingForPsi; - } - - psiClass = psiClassFinder.findPsiClass(fqName, PsiClassFinder.RuntimeClassesHandleMode.IGNORE); - if (psiClass != null && !psiClass.isEnum()) { - trace.record(JavaBindingContext.JAVA_NAMESPACE_KIND, ns, JavaNamespaceKind.CLASS_STATICS); - break lookingForPsi; - } - - ResolverNamespaceData oldValue = namespaceDescriptorCacheByFqn.put(fqName, ResolverNamespaceData.NEGATIVE); - if (oldValue != null) { - throw new IllegalStateException("rewrite at " + fqName); - } - return null; - } - - ResolverNamespaceData namespaceData = new ResolverNamespaceData(psiClass, psiPackage, fqName, ns); - - namespaceData.setMemberScope(new JavaPackageScope(fqName, semanticServices, namespaceData)); - - ResolverNamespaceData oldValue = namespaceDescriptorCacheByFqn.put(fqName, namespaceData); - if (oldValue != null) { - throw new IllegalStateException("rewrite at " + fqName); - } - - return namespaceData; + return namespaceResolver.resolveNamespace(qualifiedName); } @Nullable public JavaPackageScope getJavaPackageScope(@NotNull FqName fqName, @NotNull NamespaceDescriptor ns) { - ResolverNamespaceData resolverNamespaceData = namespaceDescriptorCacheByFqn.get(fqName); - if (resolverNamespaceData == null) { - resolverNamespaceData = createNamespaceResolverScopeData(fqName, ns); - } - if (resolverNamespaceData == null) { - return null; - } - if (resolverNamespaceData == ResolverNamespaceData.NEGATIVE) { - throw new IllegalStateException("This means that we are trying to create a Java package, but have a package with the same FQN defined in Kotlin: " + fqName); - } - JavaPackageScope scope = resolverNamespaceData.getMemberScope(); - if (scope == null) { - throw new IllegalStateException("fqn: " + fqName); - } - return scope; + return namespaceResolver.getJavaPackageScope(fqName, ns); } @Nullable - private PsiClass getPsiClassForJavaPackageScope(@NotNull FqName packageFQN) { + public PsiClass getPsiClassForJavaPackageScope(@NotNull FqName packageFQN) { return psiClassFinder.findPsiClass(packageFQN.child(Name.identifier(JvmAbi.PACKAGE_CLASS)), PsiClassFinder.RuntimeClassesHandleMode.IGNORE); } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/NamespaceResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/NamespaceResolver.java new file mode 100644 index 00000000000..6aff69ec243 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/NamespaceResolver.java @@ -0,0 +1,170 @@ +/* + * 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.resolver; + +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiPackage; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; +import org.jetbrains.jet.lang.descriptors.NamespaceDescriptorParent; +import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.java.*; +import org.jetbrains.jet.lang.resolve.java.descriptor.JavaNamespaceDescriptor; +import org.jetbrains.jet.lang.resolve.java.scope.JavaPackageScope; +import org.jetbrains.jet.lang.resolve.name.FqName; + +import java.util.Collections; + +public class NamespaceResolver { + private final JavaDescriptorResolver javaDescriptorResolver; + + public NamespaceResolver(JavaDescriptorResolver javaDescriptorResolver) { + this.javaDescriptorResolver = javaDescriptorResolver; + } + + @Nullable + public NamespaceDescriptor resolveNamespace(@NotNull FqName qualifiedName, @NotNull DescriptorSearchRule searchRule) { + // First, let's check that there is no Kotlin package: + NamespaceDescriptor kotlinNamespaceDescriptor = + javaDescriptorResolver.getSemanticServices().getKotlinNamespaceDescriptor(qualifiedName); + if (kotlinNamespaceDescriptor != null) { + if (searchRule == DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN) { + throw new IllegalStateException("class must not be found in kotlin: " + qualifiedName); + } + else if (searchRule == DescriptorSearchRule.IGNORE_IF_FOUND_IN_KOTLIN) { + return null; + } + else if (searchRule == DescriptorSearchRule.INCLUDE_KOTLIN) { + // TODO: probably this is evil + return kotlinNamespaceDescriptor; + } + else { + throw new IllegalStateException("unknown searchRule: " + searchRule); + } + } + + JavaDescriptorResolveData.ResolverNamespaceData namespaceData = + javaDescriptorResolver.getNamespaceDescriptorCacheByFqn().get(qualifiedName); + if (namespaceData != null) { + return namespaceData.getNamespaceDescriptor(); + } + + NamespaceDescriptorParent parentNs = resolveParentNamespace(qualifiedName); + if (parentNs == null) { + return null; + } + + JavaNamespaceDescriptor ns = new JavaNamespaceDescriptor( + parentNs, + Collections.emptyList(), // TODO + qualifiedName + ); + + JavaDescriptorResolveData.ResolverNamespaceData scopeData = createNamespaceResolverScopeData(qualifiedName, ns); + if (scopeData == null) { + return null; + } + + javaDescriptorResolver.getTrace().record(BindingContext.NAMESPACE, scopeData.getPsiPackageOrPsiClass(), ns); + + ns.setMemberScope(scopeData.getMemberScope()); + + return scopeData.getNamespaceDescriptor(); + } + + public NamespaceDescriptor resolveNamespace(@NotNull FqName qualifiedName) { + return resolveNamespace(qualifiedName, DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN); + } + + public NamespaceDescriptorParent resolveParentNamespace(FqName fqName) { + if (fqName.isRoot()) { + return JavaDescriptorResolver.FAKE_ROOT_MODULE; + } + else { + return resolveNamespace(fqName.parent(), DescriptorSearchRule.INCLUDE_KOTLIN); + } + } + + @Nullable + public JavaDescriptorResolveData.ResolverNamespaceData createNamespaceResolverScopeData( + @NotNull FqName fqName, + @NotNull NamespaceDescriptor ns + ) { + PsiPackage psiPackage; + PsiClass psiClass; + + lookingForPsi: + { + psiClass = javaDescriptorResolver.getPsiClassForJavaPackageScope(fqName); + psiPackage = javaDescriptorResolver.getSemanticServices().getPsiClassFinder().findPsiPackage(fqName); + if (psiClass != null || psiPackage != null) { + javaDescriptorResolver.getTrace().record(JavaBindingContext.JAVA_NAMESPACE_KIND, ns, JavaNamespaceKind.PROPER); + break lookingForPsi; + } + + psiClass = javaDescriptorResolver.getPsiClassFinder().findPsiClass(fqName, PsiClassFinder.RuntimeClassesHandleMode.IGNORE); + if (psiClass != null && !psiClass.isEnum()) { + javaDescriptorResolver.getTrace().record(JavaBindingContext.JAVA_NAMESPACE_KIND, ns, JavaNamespaceKind.CLASS_STATICS); + break lookingForPsi; + } + + JavaDescriptorResolveData.ResolverNamespaceData oldValue = + javaDescriptorResolver.getNamespaceDescriptorCacheByFqn().put(fqName, JavaDescriptorResolveData.ResolverNamespaceData.NEGATIVE); + if (oldValue != null) { + throw new IllegalStateException("rewrite at " + fqName); + } + return null; + } + + JavaDescriptorResolveData.ResolverNamespaceData namespaceData = + new JavaDescriptorResolveData.ResolverNamespaceData(psiClass, psiPackage, fqName, ns); + + namespaceData.setMemberScope(new JavaPackageScope(fqName, javaDescriptorResolver.getSemanticServices(), namespaceData)); + + JavaDescriptorResolveData.ResolverNamespaceData oldValue = + javaDescriptorResolver.getNamespaceDescriptorCacheByFqn().put(fqName, namespaceData); + if (oldValue != null) { + throw new IllegalStateException("rewrite at " + fqName); + } + + return namespaceData; + } + + @Nullable + public JavaPackageScope getJavaPackageScope(@NotNull FqName fqName, @NotNull NamespaceDescriptor ns) { + JavaDescriptorResolveData.ResolverNamespaceData resolverNamespaceData = + javaDescriptorResolver.getNamespaceDescriptorCacheByFqn().get(fqName); + if (resolverNamespaceData == null) { + resolverNamespaceData = createNamespaceResolverScopeData(fqName, ns); + } + if (resolverNamespaceData == null) { + return null; + } + if (resolverNamespaceData == JavaDescriptorResolveData.ResolverNamespaceData.NEGATIVE) { + throw new IllegalStateException( + "This means that we are trying to create a Java package, but have a package with the same FQN defined in Kotlin: " + + fqName); + } + JavaPackageScope scope = resolverNamespaceData.getMemberScope(); + if (scope == null) { + throw new IllegalStateException("fqn: " + fqName); + } + return scope; + } +} \ No newline at end of file