Simplified BuiltinsReferenceResolver.

This commit is contained in:
Evgeny Gerashchenko
2013-10-30 14:32:24 +04:00
parent 75e550fe11
commit 303f2b8c4c
3 changed files with 59 additions and 117 deletions
@@ -17,16 +17,16 @@
package org.jetbrains.jet.lang.resolve;
import com.google.common.base.Predicates;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.di.InjectorForTopDownAnalyzerBasic;
import org.jetbrains.jet.lang.PlatformToKotlinClassMap;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.impl.*;
import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptorLite;
import org.jetbrains.jet.lang.descriptors.impl.NamespaceLikeBuilder;
import org.jetbrains.jet.lang.descriptors.impl.NamespaceLikeBuilderDummy;
import org.jetbrains.jet.lang.psi.JetClassOrObject;
import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
@@ -36,7 +36,10 @@ import org.jetbrains.jet.lang.types.expressions.ExpressionTypingContext;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import javax.inject.Inject;
import java.util.*;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public class TopDownAnalyzer {
@@ -147,36 +150,6 @@ public class TopDownAnalyzer {
}
}
public static void processStandardLibraryNamespace(
@NotNull Project project,
@NotNull BindingTrace trace,
@NotNull WritableScope outerScope,
@NotNull NamespaceDescriptorImpl standardLibraryNamespace,
@NotNull List<JetFile> files) {
TopDownAnalysisParameters topDownAnalysisParameters = new TopDownAnalysisParameters(
Predicates.<PsiFile>alwaysFalse(), true, false, Collections.<AnalyzerScriptParameter>emptyList());
InjectorForTopDownAnalyzerBasic injector = new InjectorForTopDownAnalyzerBasic(
project, topDownAnalysisParameters, new ObservableBindingTrace(trace),
KotlinBuiltIns.getInstance().getBuiltInsModule(), PlatformToKotlinClassMap.EMPTY);
injector.getTopDownAnalyzer().doProcessStandardLibraryNamespace(outerScope, standardLibraryNamespace, files);
}
private void doProcessStandardLibraryNamespace(
WritableScope outerScope, NamespaceDescriptorImpl standardLibraryNamespace, List<JetFile> files) {
ArrayList<JetDeclaration> toAnalyze = new ArrayList<JetDeclaration>();
for (JetFile file : files) {
// TODO 1 restore
//context.getPackageFragments().put(file, standardLibraryNamespace);
context.getNamespaceScopes().put(file, standardLibraryNamespace.getMemberScope());
toAnalyze.addAll(file.getDeclarations());
}
// context.getDeclaringScopes().put(file, outerScope);
doProcess(outerScope, standardLibraryNamespace.getBuilder(), toAnalyze);
}
public static void processClassOrObject(
@NotNull ExpressionTypingContext context,
@NotNull final DeclarationDescriptor containingDeclaration,
@@ -16,6 +16,7 @@
package org.jetbrains.jet.plugin.references;
import com.google.common.base.Predicates;
import com.google.common.collect.Sets;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.AbstractProjectComponent;
@@ -32,30 +33,25 @@ import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.asJava.LightClassUtil;
import org.jetbrains.jet.di.InjectorForTopDownAnalyzerBasic;
import org.jetbrains.jet.lang.PlatformToKotlinClassMap;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.NamespaceDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.impl.MutablePackageFragmentDescriptor;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.RedeclarationHandler;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.renderer.DescriptorRenderer;
import java.net.URL;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.*;
public class BuiltInsReferenceResolver extends AbstractProjectComponent {
private volatile BindingContext bindingContext = null;
private volatile Set<? extends PsiFile> builtInsSources = Sets.newHashSet();
private volatile BindingContext bindingContext;
private volatile Set<JetFile> builtInsSources;
private volatile MutablePackageFragmentDescriptor builtinsPackageFragment;
public BuiltInsReferenceResolver(Project project) {
super(project);
@@ -74,24 +70,24 @@ public class BuiltInsReferenceResolver extends AbstractProjectComponent {
private void initialize() {
assert bindingContext == null : "Attempt to initialize twice";
final List<JetFile> jetBuiltInsFiles = getJetBuiltInsFiles();
final Set<JetFile> jetBuiltInsFiles = getJetBuiltInsFiles();
final Runnable initializeRunnable = new Runnable() {
@Override
public void run() {
BindingTraceContext context = new BindingTraceContext();
FakeJetNamespaceDescriptor jetNamespace = new FakeJetNamespaceDescriptor();
context.record(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME, jetNamespace);
TopDownAnalysisParameters topDownAnalysisParameters = new TopDownAnalysisParameters(
Predicates.<PsiFile>alwaysFalse(), true, false, Collections.<AnalyzerScriptParameter>emptyList());
ModuleDescriptorImpl module = new ModuleDescriptorImpl(
Name.special("<fake_module>"), Collections.<ImportPath>emptyList(), PlatformToKotlinClassMap.EMPTY);
InjectorForTopDownAnalyzerBasic injector = new InjectorForTopDownAnalyzerBasic(
myProject, topDownAnalysisParameters, new BindingTraceContext(), module, PlatformToKotlinClassMap.EMPTY);
WritableScopeImpl scope = new WritableScopeImpl(JetScope.EMPTY, jetNamespace, RedeclarationHandler.THROW_EXCEPTION,
"Builtin classes scope");
scope.changeLockLevel(WritableScope.LockLevel.BOTH);
jetNamespace.setMemberScope(scope);
TopDownAnalyzer.processStandardLibraryNamespace(myProject, context, scope, jetNamespace, jetBuiltInsFiles);
TopDownAnalyzer analyzer = injector.getTopDownAnalyzer();
analyzer.analyzeFiles(jetBuiltInsFiles, Collections.<AnalyzerScriptParameter>emptyList());
builtinsPackageFragment = analyzer.getPackageFragmentProvider().getOrCreateFragment(KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME);
builtInsSources = Sets.newHashSet(jetBuiltInsFiles);
bindingContext = context.getBindingContext();
bindingContext = injector.getBindingTrace().getBindingContext();
}
};
@@ -106,9 +102,10 @@ public class BuiltInsReferenceResolver extends AbstractProjectComponent {
}
});
}
}
private List<JetFile> getJetBuiltInsFiles() {
private Set<JetFile> getJetBuiltInsFiles() {
URL url = LightClassUtil.getBuiltInsDirUrl();
VirtualFile vf = VfsUtil.findFileByURL(url);
assert vf != null : "Virtual file not found by URL: " + url;
@@ -123,12 +120,12 @@ public class BuiltInsReferenceResolver extends AbstractProjectComponent {
PsiDirectory psiDirectory = PsiManager.getInstance(myProject).findDirectory(vf);
assert psiDirectory != null : "No PsiDirectory for " + vf;
return ContainerUtil.mapNotNull(psiDirectory.getFiles(), new Function<PsiFile, JetFile>() {
return new HashSet<JetFile>(ContainerUtil.mapNotNull(psiDirectory.getFiles(), new Function<PsiFile, JetFile>() {
@Override
public JetFile fun(PsiFile file) {
return file instanceof JetFile ? (JetFile) file : null;
}
});
}));
}
@Nullable
@@ -170,9 +167,10 @@ public class BuiltInsReferenceResolver extends AbstractProjectComponent {
if (originalDescriptor instanceof ClassDescriptor) {
return findCurrentDescriptorForClass((ClassDescriptor) originalDescriptor);
}
else if (originalDescriptor instanceof NamespaceDescriptor) {
return bindingContext.get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR,
DescriptorUtils.getFQName(originalDescriptor).toSafe());
else if (originalDescriptor instanceof PackageFragmentDescriptor) {
return KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME.equals(((PackageFragmentDescriptor) originalDescriptor).getFqName())
? builtinsPackageFragment
: null;
}
else if (originalDescriptor instanceof MemberDescriptor) {
return findCurrentDescriptorForMember((MemberDescriptor) originalDescriptor);
@@ -221,32 +219,11 @@ public class BuiltInsReferenceResolver extends AbstractProjectComponent {
if (parent instanceof ClassDescriptor) {
return ((ClassDescriptor) parent).getDefaultType().getMemberScope();
}
else if (parent instanceof NamespaceDescriptor) {
return ((NamespaceDescriptor)parent).getMemberScope();
else if (parent instanceof PackageFragmentDescriptor) {
return ((PackageFragmentDescriptor) parent).getMemberScope();
}
else {
return null;
}
}
private static class FakeJetNamespaceDescriptor extends NamespaceDescriptorImpl {
private WritableScope memberScope;
private FakeJetNamespaceDescriptor() {
super(new NamespaceDescriptorImpl(
new ModuleDescriptorImpl(Name.special("<fake_module>"), Collections.<ImportPath>emptyList(), PlatformToKotlinClassMap.EMPTY),
Collections.<AnnotationDescriptor>emptyList(), Name.special("<root>")), Collections.<AnnotationDescriptor>emptyList(),
KotlinBuiltIns.BUILT_INS_PACKAGE_NAME);
}
void setMemberScope(WritableScope memberScope) {
this.memberScope = memberScope;
}
@NotNull
@Override
public WritableScope getMemberScope() {
return memberScope;
}
}
}
@@ -19,11 +19,8 @@ package org.jetbrains.jet.plugin.references;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.testFramework.ResolveTestCase;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.PackageViewDescriptor;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.impl.DeclarationDescriptorVisitorEmptyBodies;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.plugin.PluginTestCaseBase;
@@ -74,40 +71,35 @@ public class BuiltInsReferenceResolverTest extends ResolveTestCase {
public void testAllReferencesResolved() {
BuiltInsReferenceResolver referenceResolver = getProject().getComponent(BuiltInsReferenceResolver.class);
for (DeclarationDescriptor descriptor : getAllStandardDescriptors(KotlinBuiltIns.getInstance().getBuiltInsPackageFragment())) {
if (descriptor instanceof NamespaceDescriptor && "jet".equals(descriptor.getName().asString())) continue;
for (DeclarationDescriptor descriptor : getAllStandardDescriptors()) {
assertNotNull("Can't resolve " + descriptor, referenceResolver.resolveBuiltInSymbol(descriptor));
}
}
private static Collection<DeclarationDescriptor> getAllStandardDescriptors(DeclarationDescriptor baseDescriptor) {
final ArrayList<DeclarationDescriptor> descriptors = new ArrayList<DeclarationDescriptor>();
baseDescriptor.acceptVoid(new DeclarationDescriptorVisitorEmptyBodies<Void, Void>() {
private Void visitDescriptors(Collection<? extends DeclarationDescriptor> descriptors) {
for (DeclarationDescriptor descriptor : descriptors) {
descriptor.acceptVoid(this);
private static Collection<DeclarationDescriptor> getAllStandardDescriptors() {
final List<DeclarationDescriptor> descriptors = new ArrayList<DeclarationDescriptor>();
PackageFragmentDescriptor builtinsPackageFragment = KotlinBuiltIns.getInstance().getBuiltInsPackageFragment();
for (DeclarationDescriptor packageMember : builtinsPackageFragment.getMemberScope().getAllDescriptors()) {
packageMember.acceptVoid(new DeclarationDescriptorVisitorEmptyBodies<Void, Void>() {
@Override
public Void visitClassDescriptor(ClassDescriptor descriptor, Void data) {
descriptors.add(descriptor);
for (DeclarationDescriptor classMember : descriptor.getDefaultType().getMemberScope().getAllDescriptors()) {
classMember.acceptVoid(this);
}
return null;
}
return null;
}
@Override
public Void visitClassDescriptor(ClassDescriptor descriptor, Void data) {
descriptors.add(descriptor);
return visitDescriptors(descriptor.getDefaultType().getMemberScope().getAllDescriptors());
}
@Override
public Void visitDeclarationDescriptor(DeclarationDescriptor descriptor, Void data) {
descriptors.add(descriptor);
return null;
}
});
}
@Override
public Void visitPackageViewDescriptor(PackageViewDescriptor descriptor, Void data) {
descriptors.add(descriptor);
return visitDescriptors(descriptor.getMemberScope().getAllDescriptors());
}
@Override
public Void visitDeclarationDescriptor(DeclarationDescriptor descriptor, Void data) {
descriptors.add(descriptor);
return null;
}
});
return descriptors;
}