diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java index 5224d6aac84..d4961e199ca 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java @@ -84,6 +84,9 @@ public abstract class CodegenContext { while(true) { DeclarationDescriptor contextDescriptor = c.getContextDescriptor(); if(!(contextDescriptor instanceof ClassDescriptor) && !(contextDescriptor instanceof NamespaceDescriptor)) { + if (c.getParentContext() == null) { + System.out.println(); + } c = c.getParentContext(); } else { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java index 6f1c1c255c1..0f54af71660 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java @@ -52,7 +52,7 @@ public class NamespaceCodegen { } public void generate(JetFile file) { - NamespaceDescriptor descriptor = state.getBindingContext().get(BindingContext.NAMESPACE, file); + NamespaceDescriptor descriptor = state.getBindingContext().get(BindingContext.FILE_TO_NAMESPACE, file); final CodegenContext context = CodegenContext.STATIC.intoNamespace(descriptor); final FunctionCodegen functionCodegen = new FunctionCodegen(context, v, state); 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 39bb83ab777..ce0033c0ba5 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 @@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.resolve.java; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.ModuleConfiguration; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.psi.JetImportDirective; @@ -53,7 +54,6 @@ public class JavaBridgeConfiguration implements ModuleConfiguration { @Override public void addDefaultImports(@NotNull WritableScope rootScope, @NotNull Collection directives) { - rootScope.importScope(new JavaPackageScope("", createNamespaceDescriptor(JavaDescriptorResolver.JAVA_ROOT, ""), javaSemanticServices)); for (String importFQN : DEFAULT_JAVA_IMPORTS) { directives.add(JetPsiFactory.createImportDirective(project, importFQN)); } @@ -69,4 +69,26 @@ public class JavaBridgeConfiguration implements ModuleConfiguration { namespaceMemberScope.importScope(new JavaPackageScope(DescriptorUtils.getFQName(namespaceDescriptor), namespaceDescriptor, javaSemanticServices)); delegateConfiguration.extendNamespaceScope(trace, namespaceDescriptor, namespaceMemberScope); } + + + @Override + public NamespaceDescriptor getTopLevelNamespace(@NotNull String shortName) { + NamespaceDescriptor namespaceDescriptor = javaSemanticServices.getDescriptorResolver().resolveNamespace(shortName); + if (namespaceDescriptor != null) { + return namespaceDescriptor; + } + return delegateConfiguration.getTopLevelNamespace(shortName); + } + + @Override + public void addAllTopLevelNamespacesTo(@NotNull Collection topLevelNamespaces) { + NamespaceDescriptor defaultPackage = javaSemanticServices.getDescriptorResolver().resolveNamespace(""); + assert defaultPackage != null : "Cannot resolve Java's default package"; + for (DeclarationDescriptor declarationDescriptor : defaultPackage.getMemberScope().getAllDescriptors()) { + if (declarationDescriptor instanceof NamespaceDescriptor) { + NamespaceDescriptor namespaceDescriptor = (NamespaceDescriptor) declarationDescriptor; + topLevelNamespaces.add(namespaceDescriptor); + } + } + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/DefaultModuleConfiguration.java b/compiler/frontend/src/org/jetbrains/jet/lang/DefaultModuleConfiguration.java index 82bf46581b5..790b1b184ee 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/DefaultModuleConfiguration.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/DefaultModuleConfiguration.java @@ -53,4 +53,13 @@ public class DefaultModuleConfiguration implements ModuleConfiguration { public void extendNamespaceScope(@NotNull BindingTrace trace, @NotNull NamespaceDescriptor namespaceDescriptor, @NotNull WritableScope namespaceMemberScope) { } + @Override + public NamespaceDescriptor getTopLevelNamespace(@NotNull String shortName) { + return null; + } + + @Override + public void addAllTopLevelNamespacesTo(@NotNull Collection topLevelNamespaces) { + } + } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/ModuleConfiguration.java b/compiler/frontend/src/org/jetbrains/jet/lang/ModuleConfiguration.java index 25597aaba1e..078a74cbcf9 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/ModuleConfiguration.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/ModuleConfiguration.java @@ -17,6 +17,7 @@ package org.jetbrains.jet.lang; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.psi.JetImportDirective; import org.jetbrains.jet.lang.resolve.BindingTrace; @@ -36,6 +37,15 @@ public interface ModuleConfiguration { @Override public void extendNamespaceScope(@NotNull BindingTrace trace, @NotNull NamespaceDescriptor namespaceDescriptor, @NotNull WritableScope namespaceMemberScope) { } + + @Override + public NamespaceDescriptor getTopLevelNamespace(@NotNull String shortName) { + return null; + } + + @Override + public void addAllTopLevelNamespacesTo(@NotNull Collection topLevelNamespaces) { + } }; void addDefaultImports(@NotNull WritableScope rootScope, @NotNull Collection directives); @@ -45,4 +55,10 @@ public interface ModuleConfiguration { * This method is called every time a namespace descriptor is created. Use it to add extra descriptors to the namespace, e.g. merge a Java package with a Kotlin one */ void extendNamespaceScope(@NotNull BindingTrace trace, @NotNull NamespaceDescriptor namespaceDescriptor, @NotNull WritableScope namespaceMemberScope); + + /** This method is called only if no namespace with the same short name is declared in the module itself, or to merge namespaces */ + @Nullable + NamespaceDescriptor getTopLevelNamespace(@NotNull String shortName); + + void addAllTopLevelNamespacesTo(@NotNull Collection topLevelNamespaces); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java index 54d5f5c25a2..315918b8e29 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java @@ -17,6 +17,7 @@ package org.jetbrains.jet.lang.resolve; import com.google.common.base.Predicate; +import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; @@ -32,6 +33,7 @@ import org.jetbrains.jet.lang.diagnostics.DiagnosticHolder; import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.scopes.JetScope; +import org.jetbrains.jet.lang.resolve.scopes.JetScopeAdapter; import org.jetbrains.jet.lang.resolve.scopes.WritableScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; @@ -96,7 +98,7 @@ public class AnalyzingUtils { public static BindingContext analyzeFilesWithGivenTrace( @NotNull Project project, - @NotNull ModuleConfiguration configuration, + @NotNull final ModuleConfiguration configuration, @NotNull Collection files, @NotNull Predicate filesToAnalyzeCompletely, @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory, @@ -112,46 +114,71 @@ public class AnalyzingUtils { scope.importScope(libraryScope); scope.changeLockLevel(WritableScope.LockLevel.BOTH); - TopDownAnalyzer.process(project, bindingTraceContext, scope, new NamespaceLike.Adapter(owner) { + final Map declaredNamespaces = Maps.newHashMap(); - private Map declaredNamespaces = Maps.newHashMap(); + TopDownAnalyzer.process(project, bindingTraceContext, + new JetScopeAdapter(scope) { + @Override + public NamespaceDescriptor getNamespace(@NotNull String name) { + NamespaceDescriptor topLevelNamespace = declaredNamespaces.get(name); + if (topLevelNamespace != null) { + return topLevelNamespace; + } + NamespaceDescriptor topLevelNamespaceFromConfiguration = configuration.getTopLevelNamespace(name); + if (topLevelNamespaceFromConfiguration != null) { + return topLevelNamespaceFromConfiguration; + } + return super.getNamespace(name); + } - @Override - public NamespaceDescriptorImpl getNamespace(String name) { - return declaredNamespaces.get(name); - } + @NotNull + @Override + public Collection getAllDescriptors() { + List allDescriptors = Lists.newArrayList(super.getAllDescriptors()); + allDescriptors.addAll(declaredNamespaces.values()); + configuration.addAllTopLevelNamespacesTo(allDescriptors); + return allDescriptors; + } + }, + new NamespaceLike.Adapter(owner) { - @Override - public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) { - scope.addNamespace(namespaceDescriptor); - declaredNamespaces.put(namespaceDescriptor.getName(), (NamespaceDescriptorImpl) namespaceDescriptor); - } + @Override + public NamespaceDescriptorImpl getNamespace(String name) { + return declaredNamespaces.get(name); + } - @Override - public void addClassifierDescriptor(@NotNull MutableClassDescriptorLite classDescriptor) { - throw new IllegalStateException("A class shouldn't sit right under a module: " + classDescriptor); - } + @Override + public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) { + scope.addNamespace(namespaceDescriptor); + declaredNamespaces.put(namespaceDescriptor.getName(), (NamespaceDescriptorImpl) namespaceDescriptor); + } - @Override - public void addObjectDescriptor(@NotNull MutableClassDescriptorLite objectDescriptor) { - throw new IllegalStateException("An object shouldn't sit right under a module: " + objectDescriptor); - } + @Override + public void addClassifierDescriptor(@NotNull MutableClassDescriptorLite classDescriptor) { + throw new IllegalStateException("A class shouldn't sit right under a module: " + classDescriptor); + } - @Override - public void addFunctionDescriptor(@NotNull SimpleFunctionDescriptor functionDescriptor) { - throw new IllegalStateException("A function shouldn't sit right under a module: " + functionDescriptor); - } + @Override + public void addObjectDescriptor(@NotNull MutableClassDescriptorLite objectDescriptor) { + throw new IllegalStateException("An object shouldn't sit right under a module: " + objectDescriptor); + } - @Override - public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) { - throw new IllegalStateException("A property shouldn't sit right under a module: " + propertyDescriptor); - } + @Override + public void addFunctionDescriptor(@NotNull SimpleFunctionDescriptor functionDescriptor) { + throw new IllegalStateException("A function shouldn't sit right under a module: " + functionDescriptor); + } - @Override - public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptorLite classObjectDescriptor) { - throw new IllegalStateException("Must be guaranteed not to happen by the parser"); - } - }, files, filesToAnalyzeCompletely, flowDataTraceFactory, configuration); + @Override + public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) { + throw new IllegalStateException("A property shouldn't sit right under a module: " + propertyDescriptor); + } + + @Override + public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptorLite classObjectDescriptor) { + throw new IllegalStateException("Must be guaranteed not to happen by the parser"); + } + }, + files, filesToAnalyzeCompletely, flowDataTraceFactory, configuration); return bindingTraceContext.getBindingContext(); } 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 ef916264cc2..b2545dd1581 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java @@ -144,6 +144,8 @@ public interface BindingContext { return declarationDescriptor.getOriginal(); } }; + WritableSlice FILE_TO_NAMESPACE = Slices.createSimpleSlice(); + ReadOnlySlice DESCRIPTOR_TO_DECLARATION = Slices.sliceBuilder().setKeyNormalizer(DECLARATION_DESCRIPTOR_NORMALIZER).build(); WritableSlice NAMESPACE = Slices.sliceBuilder().setOpposite((WritableSlice) DESCRIPTOR_TO_DECLARATION).build(); 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 f49f70e896d..2cd559cca46 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java @@ -167,7 +167,7 @@ public class TopDownAnalyzer { public static void processObject( @NotNull Project project, - @NotNull BindingTrace trace, + @NotNull final BindingTrace trace, @NotNull JetScope outerScope, @NotNull DeclarationDescriptor containingDeclaration, @NotNull JetObjectDeclaration object) { @@ -175,6 +175,9 @@ public class TopDownAnalyzer { @Override public NamespaceDescriptorImpl getNamespace(String name) { + if (name == "") { + return (NamespaceDescriptorImpl) trace.get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, ""); + } throw new UnsupportedOperationException(); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java index 2a19bf5da04..f38b6e2ca3a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java @@ -84,6 +84,9 @@ public class TypeHierarchyResolver { public void process(@NotNull JetScope outerScope, @NotNull NamespaceLike owner, @NotNull Collection declarations) { + // Create the default package + createNamespaceDescriptorIfNeeded(null, owner, ""); + collectNamespacesAndClassifiers(outerScope, outerScope, owner, declarations); // namespaceScopes, classes importsResolver.processTypeImports(); @@ -228,7 +231,6 @@ public class TypeHierarchyResolver { } private NamespaceDescriptorImpl createNamespaceDescriptorPathIfNeeded(JetFile file, NamespaceLike owner, JetScope outerScope) { - NamespaceLike currentOwner = owner; for (JetSimpleNameExpression nameExpression : file.getNamespaceHeader().getParentNamespaceNames()) { @@ -248,13 +250,10 @@ public class TypeHierarchyResolver { context.getTrace().record(RESOLUTION_SCOPE, file.getNamespaceHeader(), outerScope); return createNamespaceDescriptorIfNeeded(file, currentOwner, name); - - } @NotNull private NamespaceDescriptorImpl createNamespaceDescriptorIfNeeded(@Nullable JetFile file, @NotNull NamespaceLike owner, String name) { - NamespaceDescriptorImpl namespaceDescriptor = owner.getNamespace(name); if (namespaceDescriptor == null) { namespaceDescriptor = new NamespaceDescriptorImpl( @@ -273,6 +272,10 @@ public class TypeHierarchyResolver { } } + if (file != null) { + context.getTrace().record(BindingContext.FILE_TO_NAMESPACE, file, namespaceDescriptor); + } + return namespaceDescriptor; } diff --git a/js/js.translator/src/org/jetbrains/k2js/analyze/AnalyzerFacadeForJS.java b/js/js.translator/src/org/jetbrains/k2js/analyze/AnalyzerFacadeForJS.java index d3d8cab4152..fead7220bbb 100644 --- a/js/js.translator/src/org/jetbrains/k2js/analyze/AnalyzerFacadeForJS.java +++ b/js/js.translator/src/org/jetbrains/k2js/analyze/AnalyzerFacadeForJS.java @@ -127,5 +127,14 @@ public final class AnalyzerFacadeForJS { public void extendNamespaceScope(@NotNull BindingTrace trace, @NotNull NamespaceDescriptor namespaceDescriptor, @NotNull WritableScope namespaceMemberScope) { } + + @Override + public NamespaceDescriptor getTopLevelNamespace(@NotNull String shortName) { + return null; + } + + @Override + public void addAllTopLevelNamespacesTo(@NotNull Collection topLevelNamespaces) { + } } }