From 5af4661c187a117c03aab9fc950fd2d0765c62e2 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Wed, 14 Mar 2012 19:43:22 +0400 Subject: [PATCH] better root ns * ModuleDescrpiptor now lives in context * ns parent is module descriptor iff ns is root ns * minor test enhancements --- .../jetbrains/jet/codegen/JetTypeMapper.java | 5 +- .../resolve/java/JavaDescriptorResolver.java | 9 ++- .../resolve/java/JavaNamespaceDescriptor.java | 3 +- .../jet/di/InjectorForTopDownAnalyzer.java | 4 ++ .../jet/lang/ModuleConfiguration.java | 1 + .../AbstractNamespaceDescriptorImpl.java | 15 ++++- .../lang/descriptors/ModuleDescriptor.java | 60 ++++++++++++++++++- .../lang/descriptors/NamespaceDescriptor.java | 5 +- .../descriptors/NamespaceDescriptorImpl.java | 2 +- .../NamespaceDescriptorParent.java | 23 +++++++ .../jetbrains/jet/lang/psi/JetPsiFactory.java | 3 + .../jet/lang/resolve/AnalyzingUtils.java | 2 +- .../jet/lang/resolve/DescriptorUtils.java | 2 +- .../jetbrains/jet/lang/resolve/FqName.java | 9 ++- .../lang/resolve/TopDownAnalysisContext.java | 3 +- .../jet/lang/resolve/TopDownAnalyzer.java | 17 ++++-- .../lang/resolve/TypeHierarchyResolver.java | 46 +++++++++++--- .../lang/types/lang/JetStandardClasses.java | 10 +++- .../jet/compiler/NamespaceComparator.java | 16 +---- .../jet/types/JetTypeCheckerTest.java | 4 +- .../jetbrains/jet/plugin/JetPluginUtil.java | 17 ++---- .../plugin/quickfix/ImportClassHelper.java | 2 +- .../quickfix/JetPsiCheckerMultifileTest.java | 4 +- .../jet/di/AllInjectorsGenerator.java | 2 + 24 files changed, 204 insertions(+), 60 deletions(-) create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/descriptors/NamespaceDescriptorParent.java diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index ffed04f9d63..a07c12f61db 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -212,9 +212,12 @@ public class JetTypeMapper { if(name.contains("/")) return name; if (container != null) { - if (container instanceof ModuleDescriptor) { + if (container.getContainingDeclaration() instanceof ModuleDescriptor) { return name; } + if (container instanceof ModuleDescriptor) { + throw new IllegalStateException("missed something"); + } if(container instanceof JavaNamespaceDescriptor && JavaDescriptorResolver.JAVA_ROOT.equals(container.getName())) { return name; } 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 14f77fddeb2..854989af1dc 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 @@ -57,6 +57,8 @@ public class JavaDescriptorResolver { public static final String JAVA_ROOT = ""; + public static final ModuleDescriptor FAKE_ROOT_MODULE = new ModuleDescriptor(JAVA_ROOT); + /*package*/ static final DeclarationDescriptor JAVA_METHOD_TYPE_PARAMETER_PARENT = new DeclarationDescriptorImpl(null, Collections.emptyList(), "") { @Override @@ -851,7 +853,7 @@ public class JavaDescriptorResolver { ResolverNamespaceData namespaceData = new ResolverNamespaceData(); String name = psiPackage.getName(); namespaceData.namespaceDescriptor = new JavaNamespaceDescriptor( - resolveParentDescriptor(psiPackage), + (NamespaceDescriptorParent) resolveParentDescriptor(psiPackage), Collections.emptyList(), // TODO name == null ? JAVA_ROOT : name, name == null ? FqName.ROOT : new FqName(psiPackage.getQualifiedName()), @@ -865,10 +867,11 @@ public class JavaDescriptorResolver { return namespaceData; } + @NotNull private DeclarationDescriptor resolveParentDescriptor(@NotNull PsiPackage psiPackage) { PsiPackage parentPackage = psiPackage.getParentPackage(); if (parentPackage == null) { - return null; + return FAKE_ROOT_MODULE; } return resolveNamespace(parentPackage); } @@ -883,7 +886,7 @@ public class JavaDescriptorResolver { ResolverNamespaceData namespaceData = new ResolverNamespaceData(); namespaceData.namespaceDescriptor = new JavaNamespaceDescriptor( - resolveParentDescriptor(psiClass), + (NamespaceDescriptorParent) resolveParentDescriptor(psiClass), Collections.emptyList(), // TODO psiClass.getName(), new FqName(psiClass.getQualifiedName()), 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 index a885e3866cb..19db2430f59 100644 --- 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 @@ -19,6 +19,7 @@ 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; @@ -34,7 +35,7 @@ public class JavaNamespaceDescriptor extends AbstractNamespaceDescriptorImpl { /** Namespace of class with static methods */ private final boolean namespace; - public JavaNamespaceDescriptor(DeclarationDescriptor containingDeclaration, List annotations, + public JavaNamespaceDescriptor(NamespaceDescriptorParent containingDeclaration, List annotations, @NotNull String name, @NotNull FqName qualifiedName, boolean namespace) { super(containingDeclaration, annotations, name); this.qualifiedName = qualifiedName; diff --git a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzer.java b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzer.java index 47c3f27c8c1..5cd7c670af7 100644 --- a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzer.java +++ b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzer.java @@ -25,6 +25,7 @@ import org.jetbrains.jet.lang.resolve.DescriptorResolver; import com.intellij.openapi.project.Project; import org.jetbrains.jet.lang.resolve.TopDownAnalysisContext; import org.jetbrains.jet.lang.ModuleConfiguration; +import org.jetbrains.jet.lang.descriptors.ModuleDescriptor; import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory; import org.jetbrains.jet.lang.resolve.DeclarationResolver; import org.jetbrains.jet.lang.resolve.AnnotationResolver; @@ -40,6 +41,7 @@ import org.jetbrains.jet.lang.resolve.TypeHierarchyResolver; import com.intellij.openapi.project.Project; import org.jetbrains.jet.lang.resolve.TopDownAnalysisContext; import org.jetbrains.jet.lang.ModuleConfiguration; +import org.jetbrains.jet.lang.descriptors.ModuleDescriptor; import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory; /* This file is generated by org.jetbrains.jet.di.AllInjectorsGenerator. DO NOT EDIT! */ @@ -56,6 +58,7 @@ public class InjectorForTopDownAnalyzer { Project project, TopDownAnalysisContext topDownAnalysisContext, ModuleConfiguration moduleConfiguration, + ModuleDescriptor moduleDescriptor, JetControlFlowDataTraceFactory jetControlFlowDataTraceFactory ) { this.topDownAnalyzer = new TopDownAnalyzer(); @@ -130,6 +133,7 @@ public class InjectorForTopDownAnalyzer { typeHierarchyResolver.setContext(topDownAnalysisContext); typeHierarchyResolver.setDescriptorResolver(descriptorResolver); typeHierarchyResolver.setImportsResolver(importsResolver); + typeHierarchyResolver.setModuleDescriptor(moduleDescriptor); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/ModuleConfiguration.java b/compiler/frontend/src/org/jetbrains/jet/lang/ModuleConfiguration.java index 8709130e857..0ed59fcb038 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/ModuleConfiguration.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/ModuleConfiguration.java @@ -18,6 +18,7 @@ package org.jetbrains.jet.lang; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.descriptors.ModuleDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.psi.JetImportDirective; import org.jetbrains.jet.lang.resolve.BindingTrace; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/AbstractNamespaceDescriptorImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/AbstractNamespaceDescriptorImpl.java index e8c05b8ab37..a677b637658 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/AbstractNamespaceDescriptorImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/AbstractNamespaceDescriptorImpl.java @@ -25,12 +25,23 @@ import java.util.List; /** * @author abreslav - */ + */ J public abstract class AbstractNamespaceDescriptorImpl extends DeclarationDescriptorImpl implements NamespaceDescriptor { private NamespaceType namespaceType; - public AbstractNamespaceDescriptorImpl(DeclarationDescriptor containingDeclaration, List annotations, String name) { + public AbstractNamespaceDescriptorImpl(@NotNull NamespaceDescriptorParent containingDeclaration, List annotations, String name) { super(containingDeclaration, annotations, name); + + boolean rootAccordingToContainer = containingDeclaration instanceof ModuleDescriptor; + boolean rootAccordingToName = name.startsWith("<"); + if (rootAccordingToContainer != rootAccordingToName) { + throw new IllegalStateException("something is wrong, name: " + name + ", container: " + containingDeclaration); + } + } + + @Override + public NamespaceDescriptorParent getContainingDeclaration() { + return (NamespaceDescriptorParent) super.getContainingDeclaration(); } @Override diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ModuleDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ModuleDescriptor.java index 772367c602e..784c4c4f516 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ModuleDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ModuleDescriptor.java @@ -25,11 +25,24 @@ import java.util.Collections; /** * @author abreslav */ -public class ModuleDescriptor extends DeclarationDescriptorImpl implements ClassOrNamespaceDescriptor { +public class ModuleDescriptor extends DeclarationDescriptorImpl implements ClassOrNamespaceDescriptor, NamespaceDescriptorParent, NamespaceLikeBuilder { + private NamespaceDescriptor rootNs; + public ModuleDescriptor(String name) { super(null, Collections.emptyList(), name); } + public void setRootNs(@NotNull NamespaceDescriptor rootNs) { + if (this.rootNs != null) { + throw new IllegalStateException(); + } + this.rootNs = rootNs; + } + + public NamespaceDescriptorImpl getRootNs() { + return (NamespaceDescriptorImpl) rootNs; + } + @NotNull @Override public ModuleDescriptor substitute(TypeSubstitutor substitutor) { @@ -40,4 +53,49 @@ public class ModuleDescriptor extends DeclarationDescriptorImpl implements Class public R accept(DeclarationDescriptorVisitor visitor, D data) { return visitor.visitModuleDeclaration(this, data); } + + + @NotNull + @Override + public DeclarationDescriptor getOwnerForChildren() { + return this; + } + + @Override + public NamespaceDescriptorImpl getNamespace(String name) { + throw new IllegalStateException(); + } + + @Override + public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) { + if (namespaceDescriptor.getContainingDeclaration() != this) { + throw new IllegalStateException(); + } + setRootNs(namespaceDescriptor); + } + + @Override + public void addClassifierDescriptor(@NotNull MutableClassDescriptorLite classDescriptor) { + throw new IllegalStateException(); + } + + @Override + public void addObjectDescriptor(@NotNull MutableClassDescriptorLite objectDescriptor) { + throw new IllegalStateException(); + } + + @Override + public void addFunctionDescriptor(@NotNull SimpleFunctionDescriptor functionDescriptor) { + throw new IllegalStateException(); + } + + @Override + public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) { + throw new IllegalStateException(); + } + + @Override + public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptorLite classObjectDescriptor) { + throw new IllegalStateException(); + } } 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 1d938adcd09..5aafdb2db18 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/NamespaceDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/NamespaceDescriptor.java @@ -24,10 +24,13 @@ import org.jetbrains.jet.lang.types.NamespaceType; /** * @author abreslav */ -public interface NamespaceDescriptor extends Annotated, Named, ClassOrNamespaceDescriptor { +public interface NamespaceDescriptor extends Annotated, Named, ClassOrNamespaceDescriptor, NamespaceDescriptorParent { @NotNull JetScope getMemberScope(); @NotNull NamespaceType getNamespaceType(); + + @Override + NamespaceDescriptorParent getContainingDeclaration(); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/NamespaceDescriptorImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/NamespaceDescriptorImpl.java index 2edb2365c19..223367e0e5b 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/NamespaceDescriptorImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/NamespaceDescriptorImpl.java @@ -30,7 +30,7 @@ public class NamespaceDescriptorImpl extends AbstractNamespaceDescriptorImpl imp private WritableScope memberScope; - public NamespaceDescriptorImpl(@Nullable DeclarationDescriptor containingDeclaration, @NotNull List annotations, @NotNull String name) { + public NamespaceDescriptorImpl(@NotNull NamespaceDescriptorParent containingDeclaration, @NotNull List annotations, @NotNull String name) { super(containingDeclaration, annotations, name); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/NamespaceDescriptorParent.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/NamespaceDescriptorParent.java new file mode 100644 index 00000000000..0f135e97e24 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/NamespaceDescriptorParent.java @@ -0,0 +1,23 @@ +/* + * 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.descriptors; + +/** + * @author Stepan Koltsov + */ +public interface NamespaceDescriptorParent extends DeclarationDescriptor { +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java index e50f9c30a17..2b3b3eb4df5 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java @@ -146,6 +146,9 @@ public class JetPsiFactory { // } public static JetImportDirective createImportDirective(Project project, @NotNull String classPath) { + if (classPath.isEmpty()) { + throw new IllegalArgumentException("import path must not be empty"); + } JetFile namespace = createFile(project, "import " + classPath); return namespace.getImportDirectives().iterator().next(); } 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 6a3e3f04aaa..8c428b6a5e8 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnalyzingUtils.java @@ -178,7 +178,7 @@ public class AnalyzingUtils { public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptorLite classObjectDescriptor) { throw new IllegalStateException("Must be guaranteed not to happen by the parser"); } - }, + }, owner, files, filesToAnalyzeCompletely, flowDataTraceFactory, configuration); return bindingTraceContext.getBindingContext(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java index 473780af56f..e18213de8d1 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java @@ -179,7 +179,7 @@ public class DescriptorUtils { } public static FqName getFQName(@NotNull DeclarationDescriptor descriptor) { - if (descriptor instanceof ModuleDescriptor) { + if (descriptor instanceof ModuleDescriptor || descriptor.getContainingDeclaration() instanceof ModuleDescriptor) { return FqName.ROOT; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/FqName.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/FqName.java index f54bc56e8a3..4068f0fccf3 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/FqName.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/FqName.java @@ -16,8 +16,12 @@ package org.jetbrains.jet.lang.resolve; +import com.google.common.collect.Lists; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; +import java.util.List; + /** * @author Stepan Koltsov */ @@ -53,9 +57,8 @@ public class FqName { return; } - // '<' are allowed, but shouldn't be - - if (fqName.indexOf('/') >= 0) { + // TODO: prohibit < everywhere + if (fqName.indexOf('/') >= 0 || fqName.charAt(0) == '<') { throw new IllegalArgumentException("incorrect fq name: " + fqName); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalysisContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalysisContext.java index 6280c49681e..a8d5ba80b44 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalysisContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalysisContext.java @@ -67,6 +67,7 @@ public class TopDownAnalysisContext { final BindingTrace trace, Predicate analyzeCompletely, @NotNull final ModuleConfiguration configuration, + @NotNull final ModuleDescriptor moduleDescriptor, boolean declaredLocally, boolean analyzingBootstrapLibrary, @Nullable final JetControlFlowDataTraceFactory jetControlFlowDataTraceFactory) { @@ -76,7 +77,7 @@ public class TopDownAnalysisContext { "jetControlFlowDataTraceFactory must not be passed when analyzingBootstrapLibrary and vice versa"); } - this.injector = new InjectorForTopDownAnalyzer(project, this, configuration, jetControlFlowDataTraceFactory); + this.injector = new InjectorForTopDownAnalyzer(project, this, configuration, moduleDescriptor, jetControlFlowDataTraceFactory); this.trace = new ObservableBindingTrace(trace); this.analyzeCompletely = analyzeCompletely; 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 ffc4ec19417..8dafa7af641 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java @@ -30,6 +30,7 @@ import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetObjectDeclaration; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScope; +import org.jetbrains.jet.lang.types.lang.JetStandardClasses; import javax.inject.Inject; import java.util.ArrayList; @@ -82,28 +83,31 @@ public class TopDownAnalyzer { public static void process( - Project project, @NotNull BindingTrace trace, + @NotNull Project project, + @NotNull BindingTrace trace, @NotNull JetScope outerScope, @NotNull NamespaceLikeBuilder owner, + @NotNull ModuleDescriptor moduleDescriptor, @NotNull Collection files, @NotNull Predicate analyzeCompletely, @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory, @NotNull ModuleConfiguration configuration ) { - process(project, trace, outerScope, owner, files, analyzeCompletely, flowDataTraceFactory, configuration, false); + process(project, trace, outerScope, moduleDescriptor, owner, files, analyzeCompletely, flowDataTraceFactory, configuration, false); } private static void process( @NotNull Project project, @NotNull BindingTrace trace, @NotNull JetScope outerScope, + @NotNull ModuleDescriptor moduleDescriptor, @NotNull NamespaceLikeBuilder owner, @NotNull Collection declarations, @NotNull Predicate analyzeCompletely, @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory, @NotNull ModuleConfiguration configuration, boolean declaredLocally) { - TopDownAnalysisContext context = new TopDownAnalysisContext(project, trace, analyzeCompletely, configuration, declaredLocally, false, flowDataTraceFactory); + TopDownAnalysisContext context = new TopDownAnalysisContext(project, trace, analyzeCompletely, configuration, moduleDescriptor, declaredLocally, false, flowDataTraceFactory); context.getInjector().getTopDownAnalyzer().doProcess(context, outerScope, owner, declarations); } @@ -153,7 +157,7 @@ public class TopDownAnalyzer { @NotNull WritableScope outerScope, @NotNull NamespaceDescriptorImpl standardLibraryNamespace, @NotNull List files) { - TopDownAnalysisContext context = new TopDownAnalysisContext(project, trace, Predicates.alwaysFalse(), ModuleConfiguration.EMPTY, false, true, null); + TopDownAnalysisContext context = new TopDownAnalysisContext(project, trace, Predicates.alwaysFalse(), ModuleConfiguration.EMPTY, JetStandardClasses.FAKE_STANDARD_CLASSES_MODULE, false, true, null); ArrayList toAnalyze = new ArrayList(); for(JetFile file : files) { context.getNamespaceDescriptors().put(file, standardLibraryNamespace); @@ -171,7 +175,10 @@ public class TopDownAnalyzer { @NotNull JetScope outerScope, @NotNull final DeclarationDescriptor containingDeclaration, @NotNull JetObjectDeclaration object) { - process(project, trace, outerScope, new NamespaceLikeBuilder() { + + ModuleDescriptor moduleDescriptor = new ModuleDescriptor(""); + + process(project, trace, outerScope, moduleDescriptor, new NamespaceLikeBuilder() { @NotNull @Override 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 dbb85cdc381..598c7b502b5 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java @@ -56,6 +56,8 @@ public class TypeHierarchyResolver { private DescriptorResolver descriptorResolver; @NotNull private ModuleConfiguration configuration; + @NotNull + private ModuleDescriptor moduleDescriptor; // state private LinkedList topologicalOrder; @@ -80,6 +82,10 @@ public class TypeHierarchyResolver { this.configuration = configuration; } + @Inject + public void setModuleDescriptor(@NotNull ModuleDescriptor moduleDescriptor) { + this.moduleDescriptor = moduleDescriptor; + } public void process(@NotNull JetScope outerScope, @NotNull NamespaceLikeBuilder owner, @NotNull Collection declarations) { collectNamespacesAndClassifiers(outerScope, outerScope, owner, declarations); // namespaceScopes, classes @@ -111,7 +117,7 @@ public class TypeHierarchyResolver { declaration.accept(new JetVisitorVoid() { @Override public void visitJetFile(JetFile file) { - NamespaceDescriptorImpl namespaceDescriptor = createNamespaceDescriptorPathIfNeeded(file, owner, outerScope); + NamespaceDescriptorImpl namespaceDescriptor = createNamespaceDescriptorPathIfNeeded(file, outerScope); context.getNamespaceDescriptors().put(file, namespaceDescriptor); WriteThroughScope namespaceScope = new WriteThroughScope(outerScope, namespaceDescriptor.getMemberScope(), new TraceBasedRedeclarationHandler(context.getTrace())); @@ -225,15 +231,22 @@ public class TypeHierarchyResolver { } } - private NamespaceDescriptorImpl createNamespaceDescriptorPathIfNeeded(JetFile file, NamespaceLikeBuilder owner, JetScope outerScope) { + private NamespaceDescriptorImpl createNamespaceDescriptorPathIfNeeded(JetFile file, JetScope outerScope) { JetNamespaceHeader namespaceHeader = file.getNamespaceHeader(); - NamespaceLikeBuilder currentOwner = owner; + if (moduleDescriptor.getRootNs() == null) { + createNamespaceDescriptorIfNeeded(null, moduleDescriptor, "", true); + } + + NamespaceLikeBuilder currentOwner = moduleDescriptor.getRootNs(); + if (currentOwner == null) { + throw new IllegalStateException("must be initialized 5 lines above"); + } for (JetSimpleNameExpression nameExpression : namespaceHeader.getParentNamespaceNames()) { String namespaceName = JetPsiUtil.safeName(nameExpression.getReferencedName()); - NamespaceDescriptorImpl namespaceDescriptor = createNamespaceDescriptorIfNeeded(null, currentOwner, namespaceName); + NamespaceDescriptorImpl namespaceDescriptor = createNamespaceDescriptorIfNeeded(null, currentOwner, namespaceName, false); currentOwner = namespaceDescriptor; @@ -246,19 +259,34 @@ public class TypeHierarchyResolver { String name = JetPsiUtil.safeName(namespaceHeader.getName()); context.getTrace().record(RESOLUTION_SCOPE, namespaceHeader, outerScope); - return createNamespaceDescriptorIfNeeded(file, currentOwner, name); + return createNamespaceDescriptorIfNeeded(file, currentOwner, name, false); } @NotNull - private NamespaceDescriptorImpl createNamespaceDescriptorIfNeeded(@Nullable JetFile file, @NotNull NamespaceLikeBuilder owner, String name) { - NamespaceDescriptorImpl namespaceDescriptor = owner.getNamespace(name); + private NamespaceDescriptorImpl createNamespaceDescriptorIfNeeded(@Nullable JetFile file, @NotNull NamespaceLikeBuilder owner, @NotNull String name, boolean root) { + FqName ownerFqName = DescriptorUtils.getFQName(owner.getOwnerForChildren()); + + FqName fqName; + NamespaceDescriptorImpl namespaceDescriptor; + if (root) { + if (!ownerFqName.equals(FqName.ROOT) || !(owner instanceof ModuleDescriptor)) { + throw new IllegalStateException(); + } + fqName = FqName.ROOT; + namespaceDescriptor = ((ModuleDescriptor) owner).getRootNs(); + } + else { + fqName = ownerFqName.child(name); + namespaceDescriptor = owner.getNamespace(name); + } + if (namespaceDescriptor == null) { namespaceDescriptor = new NamespaceDescriptorImpl( - owner.getOwnerForChildren(), + (NamespaceDescriptorParent) owner.getOwnerForChildren(), Collections.emptyList(), // TODO: annotations name ); - context.getTrace().record(FQNAME_TO_NAMESPACE_DESCRIPTOR, DescriptorUtils.getFQName(namespaceDescriptor), namespaceDescriptor); + context.getTrace().record(FQNAME_TO_NAMESPACE_DESCRIPTOR, fqName, namespaceDescriptor); WritableScopeImpl scope = new WritableScopeImpl(JetScope.EMPTY, namespaceDescriptor, new TraceBasedRedeclarationHandler(context.getTrace())).setDebugName("Namespace member scope"); scope.changeLockLevel(WritableScope.LockLevel.BOTH); namespaceDescriptor.initialize(scope); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/lang/JetStandardClasses.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/lang/JetStandardClasses.java index 5c4ce16819a..cfd73a8a631 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/lang/JetStandardClasses.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/lang/JetStandardClasses.java @@ -46,7 +46,15 @@ public class JetStandardClasses { //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /*package*/ static NamespaceDescriptorImpl STANDARD_CLASSES_NAMESPACE = new NamespaceDescriptorImpl(null, Collections.emptyList(), "jet"); + public static final ModuleDescriptor FAKE_STANDARD_CLASSES_MODULE = new ModuleDescriptor(""); + + private static final NamespaceDescriptorImpl STANDARD_CLASSES_FAKE_ROOT_NS = new NamespaceDescriptorImpl(FAKE_STANDARD_CLASSES_MODULE, Collections.emptyList(), ""); + + static { + FAKE_STANDARD_CLASSES_MODULE.setRootNs(STANDARD_CLASSES_FAKE_ROOT_NS); + } + + /*package*/ static NamespaceDescriptorImpl STANDARD_CLASSES_NAMESPACE = new NamespaceDescriptorImpl(STANDARD_CLASSES_FAKE_ROOT_NS, Collections.emptyList(), "jet"); private static final ClassDescriptor NOTHING_CLASS = new ClassDescriptorImpl( STANDARD_CLASSES_NAMESPACE, diff --git a/compiler/tests/org/jetbrains/jet/compiler/NamespaceComparator.java b/compiler/tests/org/jetbrains/jet/compiler/NamespaceComparator.java index 110951d6d1b..f4cb3cc1536 100644 --- a/compiler/tests/org/jetbrains/jet/compiler/NamespaceComparator.java +++ b/compiler/tests/org/jetbrains/jet/compiler/NamespaceComparator.java @@ -33,6 +33,7 @@ import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.descriptors.VariableDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; +import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver; import org.jetbrains.jet.lang.resolve.java.JavaNamespaceDescriptor; import org.jetbrains.jet.lang.resolve.scopes.JetScope; @@ -413,23 +414,12 @@ class NamespaceComparator { sb.append(s); } - public void serialize(ModuleDescriptor module) { - // nop - } - public void serialize(ClassDescriptor clazz) { - new NamespacePrefixSerializer(sb).serialize(clazz.getContainingDeclaration()); - sb.append(clazz.getName()); + sb.append(DescriptorUtils.getFQName(clazz)); } public void serialize(NamespaceDescriptor ns) { - if (isRootNs(ns)) { - return; - } - if (ns.getContainingDeclaration() != null) { - new NamespacePrefixSerializer(sb).serialize(ns.getContainingDeclaration()); - } - sb.append(ns.getName()); + sb.append(DescriptorUtils.getFQName(ns)); } public void serialize(TypeParameterDescriptor param) { diff --git a/compiler/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java b/compiler/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java index 6cc7b185019..b1e8975ade9 100644 --- a/compiler/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java +++ b/compiler/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java @@ -588,8 +588,8 @@ public class JetTypeCheckerTest extends JetLiteFixture { WritableScopeImpl writableScope = new WritableScopeImpl(scope, scope.getContainingDeclaration(), RedeclarationHandler.DO_NOTHING); writableScope.importScope(library.getLibraryScope()); JavaSemanticServices javaSemanticServices = new JavaSemanticServices(getProject(), JetTestUtils.DUMMY_TRACE); - writableScope.importScope(new JavaPackageScope(FqName.ROOT, JavaBridgeConfiguration.createNamespaceDescriptor(JavaDescriptorResolver.JAVA_ROOT, FqName.ROOT), javaSemanticServices)); - writableScope.importScope(new JavaPackageScope(new FqName("java.lang"), JavaBridgeConfiguration.createNamespaceDescriptor("lang", new FqName("java.lang")), javaSemanticServices)); + writableScope.importScope(javaSemanticServices.getDescriptorResolver().resolveNamespace(FqName.ROOT).getMemberScope()); + writableScope.importScope(javaSemanticServices.getDescriptorResolver().resolveNamespace(new FqName("java.lang")).getMemberScope()); writableScope.changeLockLevel(WritableScope.LockLevel.BOTH); return writableScope; } diff --git a/idea/src/org/jetbrains/jet/plugin/JetPluginUtil.java b/idea/src/org/jetbrains/jet/plugin/JetPluginUtil.java index 15e78571d0f..27bb98a892f 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetPluginUtil.java +++ b/idea/src/org/jetbrains/jet/plugin/JetPluginUtil.java @@ -19,9 +19,12 @@ package org.jetbrains.jet.plugin; import com.google.common.collect.Lists; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.ModuleDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; +import org.jetbrains.jet.lang.resolve.DescriptorUtils; +import org.jetbrains.jet.lang.resolve.FqName; import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.types.*; @@ -35,17 +38,9 @@ import java.util.LinkedList; */ public class JetPluginUtil { @NotNull - public static String computeTypeFullName(JetType type) { - LinkedList fullName = computeTypeFullNameList(type); - String last = fullName.getLast(); - StringBuilder sb = new StringBuilder(); - for (String s : fullName) { - sb.append(s); - if (s != last) { - sb.append('.'); - } - } - return sb.toString(); + public static FqName computeTypeFullName(@NotNull JetType type) { + ClassDescriptor clazz = (ClassDescriptor) type.getConstructor().getDeclarationDescriptor(); + return DescriptorUtils.getFQName(clazz); } @NotNull diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ImportClassHelper.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ImportClassHelper.java index e13f75a8352..b944596cacd 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ImportClassHelper.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ImportClassHelper.java @@ -51,7 +51,7 @@ public class ImportClassHelper { if (element != null && element.getContainingFile() == file) { //declaration is in the same file, so no import is needed return; } - addImportDirective(JetPluginUtil.computeTypeFullName(type), file); + addImportDirective(JetPluginUtil.computeTypeFullName(type).getFqName(), file); } /** diff --git a/idea/tests/org/jetbrains/jet/plugin/quickfix/JetPsiCheckerMultifileTest.java b/idea/tests/org/jetbrains/jet/plugin/quickfix/JetPsiCheckerMultifileTest.java index 14e7769dd32..0760c1bf8d5 100644 --- a/idea/tests/org/jetbrains/jet/plugin/quickfix/JetPsiCheckerMultifileTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/quickfix/JetPsiCheckerMultifileTest.java @@ -85,8 +85,8 @@ public class JetPsiCheckerMultifileTest extends JetQuickFixMultiFileTest { } }); - assertTrue("No main file for test", mainFiles.size() > 0); - assertTrue("Too many main files for the test", mainFiles.size() <= 1); + assertTrue("No main file for test in " + dir, mainFiles.size() > 0); + assertTrue("Too many main files for the test in " + dir, mainFiles.size() <= 1); final Collection dataFiles = Collections2.filter(allTestFiles, new Predicate() { @Override diff --git a/injector-generator/src/org/jetbrains/jet/di/AllInjectorsGenerator.java b/injector-generator/src/org/jetbrains/jet/di/AllInjectorsGenerator.java index d9591d0cd7d..e8f526e7073 100644 --- a/injector-generator/src/org/jetbrains/jet/di/AllInjectorsGenerator.java +++ b/injector-generator/src/org/jetbrains/jet/di/AllInjectorsGenerator.java @@ -19,6 +19,7 @@ package org.jetbrains.jet.di; import com.intellij.openapi.project.Project; import org.jetbrains.jet.lang.ModuleConfiguration; import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory; +import org.jetbrains.jet.lang.descriptors.ModuleDescriptor; import org.jetbrains.jet.lang.resolve.*; import org.jetbrains.jet.lang.resolve.calls.CallResolver; import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; @@ -53,6 +54,7 @@ public class AllInjectorsGenerator { generator.addPublicParameter(Project.class); generator.addParameter(TopDownAnalysisContext.class); generator.addParameter(ModuleConfiguration.class); + generator.addParameter(ModuleDescriptor.class); generator.addParameter(JetControlFlowDataTraceFactory.class); generator.generate("compiler/frontend/src", "org.jetbrains.jet.di", "InjectorForTopDownAnalyzer");