Minimal refactoring that eliminates importing Java's root namespace by default.

All tests pass. Some beautifying needed

#KT-1477 Fixed
This commit is contained in:
Andrey Breslav
2012-03-11 20:28:37 +04:00
parent 6bc3bbb53d
commit 3c71512850
10 changed files with 134 additions and 40 deletions
@@ -84,6 +84,9 @@ public abstract class CodegenContext {
while(true) { while(true) {
DeclarationDescriptor contextDescriptor = c.getContextDescriptor(); DeclarationDescriptor contextDescriptor = c.getContextDescriptor();
if(!(contextDescriptor instanceof ClassDescriptor) && !(contextDescriptor instanceof NamespaceDescriptor)) { if(!(contextDescriptor instanceof ClassDescriptor) && !(contextDescriptor instanceof NamespaceDescriptor)) {
if (c.getParentContext() == null) {
System.out.println();
}
c = c.getParentContext(); c = c.getParentContext();
} }
else { else {
@@ -52,7 +52,7 @@ public class NamespaceCodegen {
} }
public void generate(JetFile file) { 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 CodegenContext context = CodegenContext.STATIC.intoNamespace(descriptor);
final FunctionCodegen functionCodegen = new FunctionCodegen(context, v, state); final FunctionCodegen functionCodegen = new FunctionCodegen(context, v, state);
@@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.resolve.java;
import com.intellij.openapi.project.Project; import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.ModuleConfiguration; 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.NamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.psi.JetImportDirective; import org.jetbrains.jet.lang.psi.JetImportDirective;
@@ -53,7 +54,6 @@ public class JavaBridgeConfiguration implements ModuleConfiguration {
@Override @Override
public void addDefaultImports(@NotNull WritableScope rootScope, @NotNull Collection<JetImportDirective> directives) { public void addDefaultImports(@NotNull WritableScope rootScope, @NotNull Collection<JetImportDirective> directives) {
rootScope.importScope(new JavaPackageScope("", createNamespaceDescriptor(JavaDescriptorResolver.JAVA_ROOT, ""), javaSemanticServices));
for (String importFQN : DEFAULT_JAVA_IMPORTS) { for (String importFQN : DEFAULT_JAVA_IMPORTS) {
directives.add(JetPsiFactory.createImportDirective(project, importFQN)); directives.add(JetPsiFactory.createImportDirective(project, importFQN));
} }
@@ -69,4 +69,26 @@ public class JavaBridgeConfiguration implements ModuleConfiguration {
namespaceMemberScope.importScope(new JavaPackageScope(DescriptorUtils.getFQName(namespaceDescriptor), namespaceDescriptor, javaSemanticServices)); namespaceMemberScope.importScope(new JavaPackageScope(DescriptorUtils.getFQName(namespaceDescriptor), namespaceDescriptor, javaSemanticServices));
delegateConfiguration.extendNamespaceScope(trace, namespaceDescriptor, namespaceMemberScope); 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<? super NamespaceDescriptor> 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);
}
}
}
} }
@@ -53,4 +53,13 @@ public class DefaultModuleConfiguration implements ModuleConfiguration {
public void extendNamespaceScope(@NotNull BindingTrace trace, @NotNull NamespaceDescriptor namespaceDescriptor, @NotNull WritableScope namespaceMemberScope) { 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<? super NamespaceDescriptor> topLevelNamespaces) {
}
} }
@@ -17,6 +17,7 @@
package org.jetbrains.jet.lang; package org.jetbrains.jet.lang;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.psi.JetImportDirective; import org.jetbrains.jet.lang.psi.JetImportDirective;
import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.BindingTrace;
@@ -36,6 +37,15 @@ public interface ModuleConfiguration {
@Override @Override
public void extendNamespaceScope(@NotNull BindingTrace trace, @NotNull NamespaceDescriptor namespaceDescriptor, @NotNull WritableScope namespaceMemberScope) { 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<? super NamespaceDescriptor> topLevelNamespaces) {
}
}; };
void addDefaultImports(@NotNull WritableScope rootScope, @NotNull Collection<JetImportDirective> directives); void addDefaultImports(@NotNull WritableScope rootScope, @NotNull Collection<JetImportDirective> 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 * 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); 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<? super NamespaceDescriptor> topLevelNamespaces);
} }
@@ -17,6 +17,7 @@
package org.jetbrains.jet.lang.resolve; package org.jetbrains.jet.lang.resolve;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.intellij.openapi.project.Project; import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement; 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.diagnostics.DiagnosticUtils;
import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; 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.WritableScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
@@ -96,7 +98,7 @@ public class AnalyzingUtils {
public static BindingContext analyzeFilesWithGivenTrace( public static BindingContext analyzeFilesWithGivenTrace(
@NotNull Project project, @NotNull Project project,
@NotNull ModuleConfiguration configuration, @NotNull final ModuleConfiguration configuration,
@NotNull Collection<JetFile> files, @NotNull Collection<JetFile> files,
@NotNull Predicate<PsiFile> filesToAnalyzeCompletely, @NotNull Predicate<PsiFile> filesToAnalyzeCompletely,
@NotNull JetControlFlowDataTraceFactory flowDataTraceFactory, @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory,
@@ -112,46 +114,71 @@ public class AnalyzingUtils {
scope.importScope(libraryScope); scope.importScope(libraryScope);
scope.changeLockLevel(WritableScope.LockLevel.BOTH); scope.changeLockLevel(WritableScope.LockLevel.BOTH);
TopDownAnalyzer.process(project, bindingTraceContext, scope, new NamespaceLike.Adapter(owner) { final Map<String, NamespaceDescriptorImpl> declaredNamespaces = Maps.newHashMap();
private Map<String, NamespaceDescriptorImpl> 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 @NotNull
public NamespaceDescriptorImpl getNamespace(String name) { @Override
return declaredNamespaces.get(name); public Collection<DeclarationDescriptor> getAllDescriptors() {
} List<DeclarationDescriptor> allDescriptors = Lists.newArrayList(super.getAllDescriptors());
allDescriptors.addAll(declaredNamespaces.values());
configuration.addAllTopLevelNamespacesTo(allDescriptors);
return allDescriptors;
}
},
new NamespaceLike.Adapter(owner) {
@Override @Override
public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) { public NamespaceDescriptorImpl getNamespace(String name) {
scope.addNamespace(namespaceDescriptor); return declaredNamespaces.get(name);
declaredNamespaces.put(namespaceDescriptor.getName(), (NamespaceDescriptorImpl) namespaceDescriptor); }
}
@Override @Override
public void addClassifierDescriptor(@NotNull MutableClassDescriptorLite classDescriptor) { public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) {
throw new IllegalStateException("A class shouldn't sit right under a module: " + classDescriptor); scope.addNamespace(namespaceDescriptor);
} declaredNamespaces.put(namespaceDescriptor.getName(), (NamespaceDescriptorImpl) namespaceDescriptor);
}
@Override @Override
public void addObjectDescriptor(@NotNull MutableClassDescriptorLite objectDescriptor) { public void addClassifierDescriptor(@NotNull MutableClassDescriptorLite classDescriptor) {
throw new IllegalStateException("An object shouldn't sit right under a module: " + objectDescriptor); throw new IllegalStateException("A class shouldn't sit right under a module: " + classDescriptor);
} }
@Override @Override
public void addFunctionDescriptor(@NotNull SimpleFunctionDescriptor functionDescriptor) { public void addObjectDescriptor(@NotNull MutableClassDescriptorLite objectDescriptor) {
throw new IllegalStateException("A function shouldn't sit right under a module: " + functionDescriptor); throw new IllegalStateException("An object shouldn't sit right under a module: " + objectDescriptor);
} }
@Override @Override
public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) { public void addFunctionDescriptor(@NotNull SimpleFunctionDescriptor functionDescriptor) {
throw new IllegalStateException("A property shouldn't sit right under a module: " + propertyDescriptor); throw new IllegalStateException("A function shouldn't sit right under a module: " + functionDescriptor);
} }
@Override @Override
public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptorLite classObjectDescriptor) { public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) {
throw new IllegalStateException("Must be guaranteed not to happen by the parser"); throw new IllegalStateException("A property shouldn't sit right under a module: " + propertyDescriptor);
} }
}, files, filesToAnalyzeCompletely, flowDataTraceFactory, configuration);
@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(); return bindingTraceContext.getBindingContext();
} }
@@ -144,6 +144,8 @@ public interface BindingContext {
return declarationDescriptor.getOriginal(); return declarationDescriptor.getOriginal();
} }
}; };
WritableSlice<JetFile, NamespaceDescriptor> FILE_TO_NAMESPACE = Slices.createSimpleSlice();
ReadOnlySlice<DeclarationDescriptor, PsiElement> DESCRIPTOR_TO_DECLARATION = Slices.<DeclarationDescriptor, PsiElement>sliceBuilder().setKeyNormalizer(DECLARATION_DESCRIPTOR_NORMALIZER).build(); ReadOnlySlice<DeclarationDescriptor, PsiElement> DESCRIPTOR_TO_DECLARATION = Slices.<DeclarationDescriptor, PsiElement>sliceBuilder().setKeyNormalizer(DECLARATION_DESCRIPTOR_NORMALIZER).build();
WritableSlice<PsiElement, NamespaceDescriptor> NAMESPACE = Slices.<PsiElement, NamespaceDescriptor>sliceBuilder().setOpposite((WritableSlice) DESCRIPTOR_TO_DECLARATION).build(); WritableSlice<PsiElement, NamespaceDescriptor> NAMESPACE = Slices.<PsiElement, NamespaceDescriptor>sliceBuilder().setOpposite((WritableSlice) DESCRIPTOR_TO_DECLARATION).build();
@@ -167,7 +167,7 @@ public class TopDownAnalyzer {
public static void processObject( public static void processObject(
@NotNull Project project, @NotNull Project project,
@NotNull BindingTrace trace, @NotNull final BindingTrace trace,
@NotNull JetScope outerScope, @NotNull JetScope outerScope,
@NotNull DeclarationDescriptor containingDeclaration, @NotNull DeclarationDescriptor containingDeclaration,
@NotNull JetObjectDeclaration object) { @NotNull JetObjectDeclaration object) {
@@ -175,6 +175,9 @@ public class TopDownAnalyzer {
@Override @Override
public NamespaceDescriptorImpl getNamespace(String name) { public NamespaceDescriptorImpl getNamespace(String name) {
if (name == "") {
return (NamespaceDescriptorImpl) trace.get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, "");
}
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@@ -84,6 +84,9 @@ public class TypeHierarchyResolver {
public void process(@NotNull JetScope outerScope, @NotNull NamespaceLike owner, @NotNull Collection<? extends PsiElement> declarations) { public void process(@NotNull JetScope outerScope, @NotNull NamespaceLike owner, @NotNull Collection<? extends PsiElement> declarations) {
// Create the default package
createNamespaceDescriptorIfNeeded(null, owner, "");
collectNamespacesAndClassifiers(outerScope, outerScope, owner, declarations); // namespaceScopes, classes collectNamespacesAndClassifiers(outerScope, outerScope, owner, declarations); // namespaceScopes, classes
importsResolver.processTypeImports(); importsResolver.processTypeImports();
@@ -228,7 +231,6 @@ public class TypeHierarchyResolver {
} }
private NamespaceDescriptorImpl createNamespaceDescriptorPathIfNeeded(JetFile file, NamespaceLike owner, JetScope outerScope) { private NamespaceDescriptorImpl createNamespaceDescriptorPathIfNeeded(JetFile file, NamespaceLike owner, JetScope outerScope) {
NamespaceLike currentOwner = owner; NamespaceLike currentOwner = owner;
for (JetSimpleNameExpression nameExpression : file.getNamespaceHeader().getParentNamespaceNames()) { for (JetSimpleNameExpression nameExpression : file.getNamespaceHeader().getParentNamespaceNames()) {
@@ -248,13 +250,10 @@ public class TypeHierarchyResolver {
context.getTrace().record(RESOLUTION_SCOPE, file.getNamespaceHeader(), outerScope); context.getTrace().record(RESOLUTION_SCOPE, file.getNamespaceHeader(), outerScope);
return createNamespaceDescriptorIfNeeded(file, currentOwner, name); return createNamespaceDescriptorIfNeeded(file, currentOwner, name);
} }
@NotNull @NotNull
private NamespaceDescriptorImpl createNamespaceDescriptorIfNeeded(@Nullable JetFile file, @NotNull NamespaceLike owner, String name) { private NamespaceDescriptorImpl createNamespaceDescriptorIfNeeded(@Nullable JetFile file, @NotNull NamespaceLike owner, String name) {
NamespaceDescriptorImpl namespaceDescriptor = owner.getNamespace(name); NamespaceDescriptorImpl namespaceDescriptor = owner.getNamespace(name);
if (namespaceDescriptor == null) { if (namespaceDescriptor == null) {
namespaceDescriptor = new NamespaceDescriptorImpl( namespaceDescriptor = new NamespaceDescriptorImpl(
@@ -273,6 +272,10 @@ public class TypeHierarchyResolver {
} }
} }
if (file != null) {
context.getTrace().record(BindingContext.FILE_TO_NAMESPACE, file, namespaceDescriptor);
}
return namespaceDescriptor; return namespaceDescriptor;
} }
@@ -127,5 +127,14 @@ public final class AnalyzerFacadeForJS {
public void extendNamespaceScope(@NotNull BindingTrace trace, @NotNull NamespaceDescriptor namespaceDescriptor, public void extendNamespaceScope(@NotNull BindingTrace trace, @NotNull NamespaceDescriptor namespaceDescriptor,
@NotNull WritableScope namespaceMemberScope) { @NotNull WritableScope namespaceMemberScope) {
} }
@Override
public NamespaceDescriptor getTopLevelNamespace(@NotNull String shortName) {
return null;
}
@Override
public void addAllTopLevelNamespacesTo(@NotNull Collection<? super NamespaceDescriptor> topLevelNamespaces) {
}
} }
} }