Supporting (predefined) classifier aliases in Lazy Resolve

This commit is contained in:
Andrey Breslav
2012-06-26 23:23:06 +02:00
parent ceafb5ddaf
commit 0c910dba8b
4 changed files with 1522 additions and 1 deletions
@@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.resolve.lazy;
import com.google.common.collect.Maps;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
@@ -64,6 +65,13 @@ public class LazyPackageMemberScope extends AbstractLazyMemberScope<NamespaceDes
return namespaceDescriptor;
}
@Override
public ClassifierDescriptor getClassifier(@NotNull Name name) {
// TODO: creating an FqName every time may be a performance problem
Name actualName = resolveSession.resolveClassifierAlias(DescriptorUtils.getFQName(thisDescriptor).toSafe(), name);
return super.getClassifier(actualName);
}
@NotNull
@Override
protected JetScope getScopeForMemberDeclarationResolution(JetDeclaration declaration) {
@@ -22,6 +22,7 @@ import com.google.common.collect.Maps;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.Function;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.di.InjectorForLazyResolve;
@@ -45,6 +46,14 @@ import java.util.Map;
* @author abreslav
*/
public class ResolveSession {
private static final Function<FqName, Name> NO_ALIASES = new Function<FqName, Name>() {
@Override
public Name fun(FqName name) {
return null;
}
};
private final ModuleDescriptor module;
private final LazyPackageDescriptor rootPackage;
@@ -58,6 +67,7 @@ public class ResolveSession {
private final ModuleConfiguration moduleConfiguration;
private final Map<JetEnumEntry, ClassDescriptor> enumEntryClassDescriptorCache = Maps.newHashMap();
private final Function<FqName, Name> classifierAliases;
public ResolveSession(
@NotNull Project project,
@@ -65,7 +75,7 @@ public class ResolveSession {
@NotNull ModuleConfiguration moduleConfiguration,
@NotNull DeclarationProviderFactory declarationProviderFactory
) {
this(project, rootDescriptor, moduleConfiguration, declarationProviderFactory, Predicates.<FqNameUnsafe>alwaysFalse());
this(project, rootDescriptor, moduleConfiguration, declarationProviderFactory, NO_ALIASES, Predicates.<FqNameUnsafe>alwaysFalse());
}
@Deprecated // Internal use only
@@ -74,8 +84,10 @@ public class ResolveSession {
@NotNull ModuleDescriptor rootDescriptor,
@NotNull ModuleConfiguration moduleConfiguration,
@NotNull DeclarationProviderFactory declarationProviderFactory,
@NotNull Function<FqName, Name> classifierAliases,
@NotNull Predicate<FqNameUnsafe> specialClasses
) {
this.classifierAliases = classifierAliases;
this.specialClasses = specialClasses;
this.injector = new InjectorForLazyResolve(project, this, trace);
this.module = rootDescriptor;
@@ -303,4 +315,14 @@ public class ResolveSession {
}
return result;
}
@NotNull
/*package*/ Name resolveClassifierAlias(@NotNull FqName packageName, @NotNull Name alias) {
// TODO: creating a new FqName object every time...
Name actualName = classifierAliases.fun(packageName.child(alias));
if (actualName == null) {
return alias;
}
return actualName;
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,111 @@
/*
* 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.lazy;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.Function;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.jvm.compiler.NamespaceComparator;
import org.jetbrains.jet.lang.DefaultModuleConfiguration;
import org.jetbrains.jet.lang.ModuleConfiguration;
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetImportDirective;
import org.jetbrains.jet.lang.psi.JetPsiFactory;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.ImportPath;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* @author abreslav
*/
public class LazyResolveBuiltinClassesTest extends AbstractLazyResolveTest {
@Test
public void testJetStandardLibrary() throws Exception {
List<JetFile> files = Lists.newArrayList();
addJetFilesFromDir(files, new File("compiler/frontend/src/jet"));
addJetFilesFromDir(files, new File("compiler/frontend/src/jet.src"));
final Map<FqName, Name> aliases = ImmutableMap.<FqName, Name>builder()
.put(new FqName("jet.Unit"), Name.identifier("Tuple0"))
.build();
ModuleDescriptor lazyModule = new ModuleDescriptor(Name.special("<lazy module>"));
ResolveSession session = new ResolveSession(
project,
lazyModule,
new SpecialModuleConfiguration(),
new FileBasedDeclarationProviderFactory(files),
new Function<FqName, Name>() {
@Override
public Name fun(FqName name) {
return aliases.get(name);
}
},
Predicates.in(Sets.newHashSet(new FqNameUnsafe("jet.Any"), new FqNameUnsafe("jet.Nothing"))));
NamespaceDescriptor jetNamespaceFromJSL =
(NamespaceDescriptor) JetStandardLibrary.getInstance().getInt().getContainingDeclaration();
NamespaceDescriptor jetNamespaceFromLazy = lazyModule.getRootNamespace().getMemberScope().getNamespace(
jetNamespaceFromJSL.getName());
NamespaceComparator.compareNamespaces(jetNamespaceFromJSL, jetNamespaceFromLazy,
true, Predicates.<NamespaceDescriptor>alwaysTrue(),
new File("compiler/testData/builtin-classes.txt"));
}
private void addJetFilesFromDir(List<JetFile> files, File jetDir) throws IOException {
for (File file : jetDir.listFiles()) {
if (FileUtil.getExtension(file.getName()).equals("jet")) {
files.add(JetPsiFactory.createFile(project, file.getName(), FileUtil.loadFile(file, true)));
}
}
}
private class SpecialModuleConfiguration implements ModuleConfiguration {
@Override
public void addDefaultImports(@NotNull Collection<JetImportDirective> directives) {
for (ImportPath defaultJetImport : DefaultModuleConfiguration.DEFAULT_JET_IMPORTS) {
directives.add(JetPsiFactory.createImportDirective(project, defaultJetImport));
}
}
@Override
public void extendNamespaceScope(@NotNull BindingTrace trace,
@NotNull NamespaceDescriptor namespaceDescriptor,
@NotNull WritableScope namespaceMemberScope) {
// DO nothing
}
}
}