LazyTopDownAnalyzer extracted as a separate component
This commit is contained in:
@@ -59,6 +59,7 @@ import org.jetbrains.jet.lang.resolve.ImportsResolver;
|
|||||||
import org.jetbrains.jet.lang.psi.JetImportsFactory;
|
import org.jetbrains.jet.lang.psi.JetImportsFactory;
|
||||||
import org.jetbrains.jet.lang.resolve.ScriptHeaderResolver;
|
import org.jetbrains.jet.lang.resolve.ScriptHeaderResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.ScriptParameterResolver;
|
import org.jetbrains.jet.lang.resolve.ScriptParameterResolver;
|
||||||
|
import org.jetbrains.jet.lang.resolve.LazyTopDownAnalyzer;
|
||||||
import org.jetbrains.jet.lang.resolve.OverloadResolver;
|
import org.jetbrains.jet.lang.resolve.OverloadResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.OverrideResolver;
|
import org.jetbrains.jet.lang.resolve.OverrideResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.TypeHierarchyResolver;
|
import org.jetbrains.jet.lang.resolve.TypeHierarchyResolver;
|
||||||
@@ -119,6 +120,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
|
|||||||
private final JetImportsFactory jetImportsFactory;
|
private final JetImportsFactory jetImportsFactory;
|
||||||
private final ScriptHeaderResolver scriptHeaderResolver;
|
private final ScriptHeaderResolver scriptHeaderResolver;
|
||||||
private final ScriptParameterResolver scriptParameterResolver;
|
private final ScriptParameterResolver scriptParameterResolver;
|
||||||
|
private final LazyTopDownAnalyzer lazyTopDownAnalyzer;
|
||||||
private final OverloadResolver overloadResolver;
|
private final OverloadResolver overloadResolver;
|
||||||
private final OverrideResolver overrideResolver;
|
private final OverrideResolver overrideResolver;
|
||||||
private final TypeHierarchyResolver typeHierarchyResolver;
|
private final TypeHierarchyResolver typeHierarchyResolver;
|
||||||
@@ -183,6 +185,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
|
|||||||
this.jetImportsFactory = new JetImportsFactory();
|
this.jetImportsFactory = new JetImportsFactory();
|
||||||
this.scriptHeaderResolver = new ScriptHeaderResolver();
|
this.scriptHeaderResolver = new ScriptHeaderResolver();
|
||||||
this.scriptParameterResolver = new ScriptParameterResolver();
|
this.scriptParameterResolver = new ScriptParameterResolver();
|
||||||
|
this.lazyTopDownAnalyzer = new LazyTopDownAnalyzer();
|
||||||
this.overloadResolver = new OverloadResolver();
|
this.overloadResolver = new OverloadResolver();
|
||||||
this.overrideResolver = new OverrideResolver();
|
this.overrideResolver = new OverrideResolver();
|
||||||
this.typeHierarchyResolver = new TypeHierarchyResolver();
|
this.typeHierarchyResolver = new TypeHierarchyResolver();
|
||||||
@@ -193,6 +196,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
|
|||||||
|
|
||||||
this.topDownAnalyzer.setBodyResolver(bodyResolver);
|
this.topDownAnalyzer.setBodyResolver(bodyResolver);
|
||||||
this.topDownAnalyzer.setDeclarationResolver(declarationResolver);
|
this.topDownAnalyzer.setDeclarationResolver(declarationResolver);
|
||||||
|
this.topDownAnalyzer.setLazyTopDownAnalyzer(lazyTopDownAnalyzer);
|
||||||
this.topDownAnalyzer.setModuleDescriptor(moduleDescriptor);
|
this.topDownAnalyzer.setModuleDescriptor(moduleDescriptor);
|
||||||
this.topDownAnalyzer.setOverloadResolver(overloadResolver);
|
this.topDownAnalyzer.setOverloadResolver(overloadResolver);
|
||||||
this.topDownAnalyzer.setOverrideResolver(overrideResolver);
|
this.topDownAnalyzer.setOverrideResolver(overrideResolver);
|
||||||
@@ -301,6 +305,13 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
|
|||||||
|
|
||||||
scriptParameterResolver.setDependencyClassByQualifiedNameResolver(javaDescriptorResolver);
|
scriptParameterResolver.setDependencyClassByQualifiedNameResolver(javaDescriptorResolver);
|
||||||
|
|
||||||
|
lazyTopDownAnalyzer.setBodyResolver(bodyResolver);
|
||||||
|
lazyTopDownAnalyzer.setDeclarationResolver(declarationResolver);
|
||||||
|
lazyTopDownAnalyzer.setModuleDescriptor(moduleDescriptor);
|
||||||
|
lazyTopDownAnalyzer.setOverloadResolver(overloadResolver);
|
||||||
|
lazyTopDownAnalyzer.setOverrideResolver(overrideResolver);
|
||||||
|
lazyTopDownAnalyzer.setTrace(bindingTrace);
|
||||||
|
|
||||||
overloadResolver.setTrace(bindingTrace);
|
overloadResolver.setTrace(bindingTrace);
|
||||||
|
|
||||||
overrideResolver.setTrace(bindingTrace);
|
overrideResolver.setTrace(bindingTrace);
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ import org.jetbrains.jet.lang.resolve.ImportsResolver;
|
|||||||
import org.jetbrains.jet.lang.psi.JetImportsFactory;
|
import org.jetbrains.jet.lang.psi.JetImportsFactory;
|
||||||
import org.jetbrains.jet.lang.resolve.ScriptHeaderResolver;
|
import org.jetbrains.jet.lang.resolve.ScriptHeaderResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.ScriptParameterResolver;
|
import org.jetbrains.jet.lang.resolve.ScriptParameterResolver;
|
||||||
|
import org.jetbrains.jet.lang.resolve.LazyTopDownAnalyzer;
|
||||||
import org.jetbrains.jet.lang.resolve.OverloadResolver;
|
import org.jetbrains.jet.lang.resolve.OverloadResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.OverrideResolver;
|
import org.jetbrains.jet.lang.resolve.OverrideResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.TypeHierarchyResolver;
|
import org.jetbrains.jet.lang.resolve.TypeHierarchyResolver;
|
||||||
@@ -94,6 +95,7 @@ public class InjectorForTopDownAnalyzerBasic {
|
|||||||
private final JetImportsFactory jetImportsFactory;
|
private final JetImportsFactory jetImportsFactory;
|
||||||
private final ScriptHeaderResolver scriptHeaderResolver;
|
private final ScriptHeaderResolver scriptHeaderResolver;
|
||||||
private final ScriptParameterResolver scriptParameterResolver;
|
private final ScriptParameterResolver scriptParameterResolver;
|
||||||
|
private final LazyTopDownAnalyzer lazyTopDownAnalyzer;
|
||||||
private final OverloadResolver overloadResolver;
|
private final OverloadResolver overloadResolver;
|
||||||
private final OverrideResolver overrideResolver;
|
private final OverrideResolver overrideResolver;
|
||||||
private final TypeHierarchyResolver typeHierarchyResolver;
|
private final TypeHierarchyResolver typeHierarchyResolver;
|
||||||
@@ -138,12 +140,14 @@ public class InjectorForTopDownAnalyzerBasic {
|
|||||||
this.jetImportsFactory = new JetImportsFactory();
|
this.jetImportsFactory = new JetImportsFactory();
|
||||||
this.scriptHeaderResolver = new ScriptHeaderResolver();
|
this.scriptHeaderResolver = new ScriptHeaderResolver();
|
||||||
this.scriptParameterResolver = new ScriptParameterResolver();
|
this.scriptParameterResolver = new ScriptParameterResolver();
|
||||||
|
this.lazyTopDownAnalyzer = new LazyTopDownAnalyzer();
|
||||||
this.overloadResolver = new OverloadResolver();
|
this.overloadResolver = new OverloadResolver();
|
||||||
this.overrideResolver = new OverrideResolver();
|
this.overrideResolver = new OverrideResolver();
|
||||||
this.typeHierarchyResolver = new TypeHierarchyResolver();
|
this.typeHierarchyResolver = new TypeHierarchyResolver();
|
||||||
|
|
||||||
this.topDownAnalyzer.setBodyResolver(bodyResolver);
|
this.topDownAnalyzer.setBodyResolver(bodyResolver);
|
||||||
this.topDownAnalyzer.setDeclarationResolver(declarationResolver);
|
this.topDownAnalyzer.setDeclarationResolver(declarationResolver);
|
||||||
|
this.topDownAnalyzer.setLazyTopDownAnalyzer(lazyTopDownAnalyzer);
|
||||||
this.topDownAnalyzer.setModuleDescriptor(moduleDescriptor);
|
this.topDownAnalyzer.setModuleDescriptor(moduleDescriptor);
|
||||||
this.topDownAnalyzer.setOverloadResolver(overloadResolver);
|
this.topDownAnalyzer.setOverloadResolver(overloadResolver);
|
||||||
this.topDownAnalyzer.setOverrideResolver(overrideResolver);
|
this.topDownAnalyzer.setOverrideResolver(overrideResolver);
|
||||||
@@ -239,6 +243,13 @@ public class InjectorForTopDownAnalyzerBasic {
|
|||||||
|
|
||||||
scriptParameterResolver.setDependencyClassByQualifiedNameResolver(dependencyClassByQualifiedNameResolverDummy);
|
scriptParameterResolver.setDependencyClassByQualifiedNameResolver(dependencyClassByQualifiedNameResolverDummy);
|
||||||
|
|
||||||
|
lazyTopDownAnalyzer.setBodyResolver(bodyResolver);
|
||||||
|
lazyTopDownAnalyzer.setDeclarationResolver(declarationResolver);
|
||||||
|
lazyTopDownAnalyzer.setModuleDescriptor(moduleDescriptor);
|
||||||
|
lazyTopDownAnalyzer.setOverloadResolver(overloadResolver);
|
||||||
|
lazyTopDownAnalyzer.setOverrideResolver(overrideResolver);
|
||||||
|
lazyTopDownAnalyzer.setTrace(bindingTrace);
|
||||||
|
|
||||||
overloadResolver.setTrace(bindingTrace);
|
overloadResolver.setTrace(bindingTrace);
|
||||||
|
|
||||||
overrideResolver.setTrace(bindingTrace);
|
overrideResolver.setTrace(bindingTrace);
|
||||||
|
|||||||
@@ -0,0 +1,258 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2013 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;
|
||||||
|
|
||||||
|
import com.google.common.collect.HashMultimap;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
|
import org.jetbrains.jet.lang.resolve.lazy.ForceResolveUtil;
|
||||||
|
import org.jetbrains.jet.lang.resolve.lazy.LazyImportScope;
|
||||||
|
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
|
||||||
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.jetbrains.jet.lang.diagnostics.Errors.MANY_CLASS_OBJECTS;
|
||||||
|
|
||||||
|
public class LazyTopDownAnalyzer {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private BindingTrace trace;
|
||||||
|
@NotNull
|
||||||
|
private DeclarationResolver declarationResolver;
|
||||||
|
@NotNull
|
||||||
|
private OverrideResolver overrideResolver;
|
||||||
|
@NotNull
|
||||||
|
private OverloadResolver overloadResolver;
|
||||||
|
@NotNull
|
||||||
|
private ModuleDescriptor moduleDescriptor;
|
||||||
|
@NotNull
|
||||||
|
private BodyResolver bodyResolver;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public void setTrace(@NotNull BindingTrace trace) {
|
||||||
|
this.trace = trace;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public void setDeclarationResolver(@NotNull DeclarationResolver declarationResolver) {
|
||||||
|
this.declarationResolver = declarationResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public void setOverrideResolver(@NotNull OverrideResolver overrideResolver) {
|
||||||
|
this.overrideResolver = overrideResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public void setOverloadResolver(@NotNull OverloadResolver overloadResolver) {
|
||||||
|
this.overloadResolver = overloadResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public void setModuleDescriptor(@NotNull ModuleDescriptor moduleDescriptor) {
|
||||||
|
this.moduleDescriptor = moduleDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public void setBodyResolver(@NotNull BodyResolver bodyResolver) {
|
||||||
|
this.bodyResolver = bodyResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void analyzeDeclarations(
|
||||||
|
final ResolveSession resolveSession,
|
||||||
|
@NotNull TopDownAnalysisParameters topDownAnalysisParameters,
|
||||||
|
@NotNull Collection<? extends PsiElement> declarations
|
||||||
|
) {
|
||||||
|
assert topDownAnalysisParameters.isLazyTopDownAnalysis() : "Lazy analyzer is run in non-lazy mode";
|
||||||
|
|
||||||
|
final TopDownAnalysisContext c = new TopDownAnalysisContext(topDownAnalysisParameters);
|
||||||
|
final Multimap<FqName, JetElement> topLevelFqNames = HashMultimap.create();
|
||||||
|
|
||||||
|
// fill in the context
|
||||||
|
for (PsiElement declaration : declarations) {
|
||||||
|
declaration.accept(
|
||||||
|
new JetVisitorVoid() {
|
||||||
|
private void registerDeclarations(@NotNull List<JetDeclaration> declarations) {
|
||||||
|
for (JetDeclaration jetDeclaration : declarations) {
|
||||||
|
jetDeclaration.accept(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerTopLevelFqName(
|
||||||
|
@NotNull JetNamedDeclaration declaration,
|
||||||
|
@NotNull DeclarationDescriptor descriptor
|
||||||
|
) {
|
||||||
|
if (DescriptorUtils.isTopLevelDeclaration(descriptor)) {
|
||||||
|
FqName fqName = declaration.getFqName();
|
||||||
|
if (fqName != null) {
|
||||||
|
topLevelFqNames.put(fqName, declaration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerScope(@Nullable JetDeclaration declaration) {
|
||||||
|
if (declaration == null) return;
|
||||||
|
c.registerDeclaringScope(
|
||||||
|
declaration,
|
||||||
|
resolveSession.getScopeProvider().getResolutionScopeForDeclaration(declaration)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitDeclaration(@NotNull JetDeclaration dcl) {
|
||||||
|
throw new IllegalArgumentException("Unsupported declaration: " + dcl + " " + dcl.getText());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitJetFile(@NotNull JetFile file) {
|
||||||
|
if (file.isScript()) {
|
||||||
|
JetScript script = file.getScript();
|
||||||
|
assert script != null;
|
||||||
|
|
||||||
|
c.getScripts().put(script, resolveSession.getScriptDescriptor(script));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
JetPackageDirective packageDirective = file.getPackageDirective();
|
||||||
|
assert packageDirective != null : "No package in a non-script file: " + file;
|
||||||
|
|
||||||
|
c.addFile(file);
|
||||||
|
|
||||||
|
DescriptorResolver.resolvePackageHeader(packageDirective, moduleDescriptor, trace);
|
||||||
|
DescriptorResolver.registerFileInPackage(trace, file);
|
||||||
|
|
||||||
|
registerDeclarations(file.getDeclarations());
|
||||||
|
|
||||||
|
topLevelFqNames.put(file.getPackageFqName(), packageDirective);
|
||||||
|
}
|
||||||
|
resolveAndCheckImports(file, resolveSession);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resolveAndCheckImports(@NotNull JetFile file, @NotNull ResolveSession resolveSession) {
|
||||||
|
LazyImportScope fileScope = resolveSession.getScopeProvider().getExplicitImportsScopeForFile(file);
|
||||||
|
fileScope.forceResolveAllContents();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void visitClassOrObject(@NotNull JetClassOrObject classOrObject) {
|
||||||
|
ClassDescriptorWithResolutionScopes descriptor = ForceResolveUtil.forceResolveAllContents(
|
||||||
|
(ClassDescriptorWithResolutionScopes) resolveSession.getClassDescriptor(classOrObject)
|
||||||
|
);
|
||||||
|
|
||||||
|
c.getDeclaredClasses().put(classOrObject, descriptor);
|
||||||
|
registerDeclarations(classOrObject.getDeclarations());
|
||||||
|
registerTopLevelFqName(classOrObject, descriptor);
|
||||||
|
|
||||||
|
checkManyClassObjects(classOrObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkManyClassObjects(JetClassOrObject classOrObject) {
|
||||||
|
boolean classObjectAlreadyFound = false;
|
||||||
|
for (JetDeclaration jetDeclaration : classOrObject.getDeclarations()) {
|
||||||
|
jetDeclaration.accept(this);
|
||||||
|
|
||||||
|
if (jetDeclaration instanceof JetClassObject) {
|
||||||
|
if (classObjectAlreadyFound) {
|
||||||
|
trace.report(MANY_CLASS_OBJECTS.on((JetClassObject) jetDeclaration));
|
||||||
|
}
|
||||||
|
classObjectAlreadyFound = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitClass(@NotNull JetClass klass) {
|
||||||
|
visitClassOrObject(klass);
|
||||||
|
|
||||||
|
registerPrimaryConstructorParameters(klass);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerPrimaryConstructorParameters(@NotNull JetClass klass) {
|
||||||
|
for (JetParameter jetParameter : klass.getPrimaryConstructorParameters()) {
|
||||||
|
if (jetParameter.getValOrVarNode() != null) {
|
||||||
|
c.getPrimaryConstructorParameterProperties().put(
|
||||||
|
jetParameter,
|
||||||
|
(PropertyDescriptor) resolveSession.resolveToDescriptor(jetParameter)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitClassObject(@NotNull JetClassObject classObject) {
|
||||||
|
visitClassOrObject(classObject.getObjectDeclaration());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitEnumEntry(@NotNull JetEnumEntry enumEntry) {
|
||||||
|
visitClassOrObject(enumEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitObjectDeclaration(@NotNull JetObjectDeclaration declaration) {
|
||||||
|
visitClassOrObject(declaration);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitAnonymousInitializer(@NotNull JetClassInitializer initializer) {
|
||||||
|
registerScope(initializer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitNamedFunction(@NotNull JetNamedFunction function) {
|
||||||
|
c.getFunctions().put(
|
||||||
|
function,
|
||||||
|
ForceResolveUtil.forceResolveAllContents(
|
||||||
|
(SimpleFunctionDescriptor) resolveSession.resolveToDescriptor(function)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
registerScope(function);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitProperty(@NotNull JetProperty property) {
|
||||||
|
PropertyDescriptor descriptor = ForceResolveUtil.forceResolveAllContents(
|
||||||
|
(PropertyDescriptor) resolveSession.resolveToDescriptor(property)
|
||||||
|
);
|
||||||
|
|
||||||
|
c.getProperties().put(property, descriptor);
|
||||||
|
registerTopLevelFqName(property, descriptor);
|
||||||
|
|
||||||
|
registerScope(property);
|
||||||
|
registerScope(property.getGetter());
|
||||||
|
registerScope(property.getSetter());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
declarationResolver.checkRedeclarationsInPackages(resolveSession, topLevelFqNames);
|
||||||
|
declarationResolver.checkRedeclarationsInInnerClassNames(c);
|
||||||
|
overrideResolver.check(c);
|
||||||
|
|
||||||
|
overloadResolver.process(c);
|
||||||
|
|
||||||
|
bodyResolver.resolveBodies(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -17,8 +17,6 @@
|
|||||||
package org.jetbrains.jet.lang.resolve;
|
package org.jetbrains.jet.lang.resolve;
|
||||||
|
|
||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
import com.google.common.collect.HashMultimap;
|
|
||||||
import com.google.common.collect.Multimap;
|
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
@@ -36,9 +34,8 @@ import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor;
|
|||||||
import org.jetbrains.jet.lang.descriptors.impl.MutablePackageFragmentDescriptor;
|
import org.jetbrains.jet.lang.descriptors.impl.MutablePackageFragmentDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.impl.PackageLikeBuilder;
|
import org.jetbrains.jet.lang.descriptors.impl.PackageLikeBuilder;
|
||||||
import org.jetbrains.jet.lang.descriptors.impl.PackageLikeBuilderDummy;
|
import org.jetbrains.jet.lang.descriptors.impl.PackageLikeBuilderDummy;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
||||||
import org.jetbrains.jet.lang.resolve.lazy.ForceResolveUtil;
|
import org.jetbrains.jet.lang.psi.JetFile;
|
||||||
import org.jetbrains.jet.lang.resolve.lazy.LazyImportScope;
|
|
||||||
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
|
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
|
||||||
import org.jetbrains.jet.lang.resolve.lazy.declarations.FileBasedDeclarationProviderFactory;
|
import org.jetbrains.jet.lang.resolve.lazy.declarations.FileBasedDeclarationProviderFactory;
|
||||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
@@ -50,9 +47,10 @@ import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
|||||||
import org.jetbrains.jet.storage.LockBasedStorageManager;
|
import org.jetbrains.jet.storage.LockBasedStorageManager;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import java.util.*;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import static org.jetbrains.jet.lang.diagnostics.Errors.MANY_CLASS_OBJECTS;
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public class TopDownAnalyzer {
|
public class TopDownAnalyzer {
|
||||||
|
|
||||||
@@ -75,6 +73,9 @@ public class TopDownAnalyzer {
|
|||||||
@NotNull
|
@NotNull
|
||||||
private Project project;
|
private Project project;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private LazyTopDownAnalyzer lazyTopDownAnalyzer;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public void setTrace(@NotNull BindingTrace trace) {
|
public void setTrace(@NotNull BindingTrace trace) {
|
||||||
this.trace = trace;
|
this.trace = trace;
|
||||||
@@ -120,8 +121,13 @@ public class TopDownAnalyzer {
|
|||||||
this.project = project;
|
this.project = project;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public void setLazyTopDownAnalyzer(@NotNull LazyTopDownAnalyzer lazyTopDownAnalyzer) {
|
||||||
|
this.lazyTopDownAnalyzer = lazyTopDownAnalyzer;
|
||||||
|
}
|
||||||
|
|
||||||
public void doProcess(
|
public void doProcess(
|
||||||
@NotNull final TopDownAnalysisContext c,
|
@NotNull TopDownAnalysisContext c,
|
||||||
@NotNull JetScope outerScope,
|
@NotNull JetScope outerScope,
|
||||||
@NotNull PackageLikeBuilder owner,
|
@NotNull PackageLikeBuilder owner,
|
||||||
@NotNull Collection<? extends PsiElement> declarations
|
@NotNull Collection<? extends PsiElement> declarations
|
||||||
@@ -130,7 +136,7 @@ public class TopDownAnalyzer {
|
|||||||
c.debug("Enter");
|
c.debug("Enter");
|
||||||
|
|
||||||
if (c.getTopDownAnalysisParameters().isLazyTopDownAnalysis()) {
|
if (c.getTopDownAnalysisParameters().isLazyTopDownAnalysis()) {
|
||||||
final ResolveSession resolveSession = new InjectorForLazyResolve(
|
ResolveSession resolveSession = new InjectorForLazyResolve(
|
||||||
project,
|
project,
|
||||||
new GlobalContextImpl((LockBasedStorageManager) c.getStorageManager(), c.getExceptionTracker()), // TODO
|
new GlobalContextImpl((LockBasedStorageManager) c.getStorageManager(), c.getExceptionTracker()), // TODO
|
||||||
(ModuleDescriptorImpl) moduleDescriptor, // TODO
|
(ModuleDescriptorImpl) moduleDescriptor, // TODO
|
||||||
@@ -138,172 +144,19 @@ public class TopDownAnalyzer {
|
|||||||
trace
|
trace
|
||||||
).getResolveSession();
|
).getResolveSession();
|
||||||
|
|
||||||
final Multimap<FqName, JetElement> topLevelFqNames = HashMultimap.create();
|
lazyTopDownAnalyzer.analyzeDeclarations(
|
||||||
|
resolveSession,
|
||||||
// fill in the context
|
c.getTopDownAnalysisParameters(),
|
||||||
for (PsiElement declaration : declarations) {
|
declarations
|
||||||
declaration.accept(
|
);
|
||||||
new JetVisitorVoid() {
|
return;
|
||||||
private void registerDeclarations(@NotNull List<JetDeclaration> declarations) {
|
|
||||||
for (JetDeclaration jetDeclaration : declarations) {
|
|
||||||
jetDeclaration.accept(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerTopLevelFqName(@NotNull JetNamedDeclaration declaration, @NotNull DeclarationDescriptor descriptor) {
|
|
||||||
if (DescriptorUtils.isTopLevelDeclaration(descriptor)) {
|
|
||||||
FqName fqName = declaration.getFqName();
|
|
||||||
if (fqName != null) {
|
|
||||||
topLevelFqNames.put(fqName, declaration);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerScope(@Nullable JetDeclaration declaration) {
|
|
||||||
if (declaration == null) return;
|
|
||||||
c.registerDeclaringScope(
|
|
||||||
declaration,
|
|
||||||
resolveSession.getScopeProvider().getResolutionScopeForDeclaration(declaration)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitDeclaration(@NotNull JetDeclaration dcl) {
|
|
||||||
throw new IllegalArgumentException("Unsupported declaration: " + dcl + " " + dcl.getText());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitJetFile(@NotNull JetFile file) {
|
|
||||||
if (file.isScript()) {
|
|
||||||
JetScript script = file.getScript();
|
|
||||||
assert script != null;
|
|
||||||
|
|
||||||
c.getScripts().put(script, resolveSession.getScriptDescriptor(script));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
JetPackageDirective packageDirective = file.getPackageDirective();
|
|
||||||
assert packageDirective != null : "No package in a non-script file: " + file;
|
|
||||||
|
|
||||||
c.addFile(file);
|
|
||||||
|
|
||||||
DescriptorResolver.resolvePackageHeader(packageDirective, moduleDescriptor, trace);
|
|
||||||
DescriptorResolver.registerFileInPackage(trace, file);
|
|
||||||
|
|
||||||
registerDeclarations(file.getDeclarations());
|
|
||||||
|
|
||||||
topLevelFqNames.put(file.getPackageFqName(), packageDirective);
|
|
||||||
}
|
|
||||||
resolveAndCheckImports(file, resolveSession);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void resolveAndCheckImports(@NotNull JetFile file, @NotNull ResolveSession resolveSession) {
|
|
||||||
LazyImportScope fileScope = resolveSession.getScopeProvider().getExplicitImportsScopeForFile(file);
|
|
||||||
fileScope.forceResolveAllContents();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void visitClassOrObject(@NotNull JetClassOrObject classOrObject) {
|
|
||||||
ClassDescriptorWithResolutionScopes descriptor = ForceResolveUtil.forceResolveAllContents(
|
|
||||||
(ClassDescriptorWithResolutionScopes) resolveSession.getClassDescriptor(classOrObject)
|
|
||||||
);
|
|
||||||
|
|
||||||
c.getDeclaredClasses().put(classOrObject, descriptor);
|
|
||||||
registerDeclarations(classOrObject.getDeclarations());
|
|
||||||
registerTopLevelFqName(classOrObject, descriptor);
|
|
||||||
|
|
||||||
checkManyClassObjects(classOrObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkManyClassObjects(JetClassOrObject classOrObject) {
|
|
||||||
boolean classObjectAlreadyFound = false;
|
|
||||||
for (JetDeclaration jetDeclaration : classOrObject.getDeclarations()) {
|
|
||||||
jetDeclaration.accept(this);
|
|
||||||
|
|
||||||
if (jetDeclaration instanceof JetClassObject) {
|
|
||||||
if (classObjectAlreadyFound) {
|
|
||||||
trace.report(MANY_CLASS_OBJECTS.on((JetClassObject) jetDeclaration));
|
|
||||||
}
|
|
||||||
classObjectAlreadyFound = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitClass(@NotNull JetClass klass) {
|
|
||||||
visitClassOrObject(klass);
|
|
||||||
|
|
||||||
registerPrimaryConstructorParameters(klass);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerPrimaryConstructorParameters(@NotNull JetClass klass) {
|
|
||||||
for (JetParameter jetParameter : klass.getPrimaryConstructorParameters()) {
|
|
||||||
if (jetParameter.getValOrVarNode() != null) {
|
|
||||||
c.getPrimaryConstructorParameterProperties().put(
|
|
||||||
jetParameter,
|
|
||||||
(PropertyDescriptor) resolveSession.resolveToDescriptor(jetParameter)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitClassObject(@NotNull JetClassObject classObject) {
|
|
||||||
visitClassOrObject(classObject.getObjectDeclaration());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitEnumEntry(@NotNull JetEnumEntry enumEntry) {
|
|
||||||
visitClassOrObject(enumEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitObjectDeclaration(@NotNull JetObjectDeclaration declaration) {
|
|
||||||
visitClassOrObject(declaration);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitAnonymousInitializer(@NotNull JetClassInitializer initializer) {
|
|
||||||
registerScope(initializer);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitNamedFunction(@NotNull JetNamedFunction function) {
|
|
||||||
c.getFunctions().put(
|
|
||||||
function,
|
|
||||||
ForceResolveUtil.forceResolveAllContents(
|
|
||||||
(SimpleFunctionDescriptor) resolveSession.resolveToDescriptor(function)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
registerScope(function);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitProperty(@NotNull JetProperty property) {
|
|
||||||
PropertyDescriptor descriptor = ForceResolveUtil.forceResolveAllContents(
|
|
||||||
(PropertyDescriptor) resolveSession.resolveToDescriptor(property)
|
|
||||||
);
|
|
||||||
|
|
||||||
c.getProperties().put(property, descriptor);
|
|
||||||
registerTopLevelFqName(property, descriptor);
|
|
||||||
|
|
||||||
registerScope(property);
|
|
||||||
registerScope(property.getGetter());
|
|
||||||
registerScope(property.getSetter());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
declarationResolver.checkRedeclarationsInPackages(resolveSession, topLevelFqNames);
|
|
||||||
declarationResolver.checkRedeclarationsInInnerClassNames(c);
|
|
||||||
overrideResolver.check(c);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
typeHierarchyResolver.process(c, outerScope, owner, declarations);
|
|
||||||
declarationResolver.process(c);
|
|
||||||
overrideResolver.process(c);
|
|
||||||
lockScopes(c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typeHierarchyResolver.process(c, outerScope, owner, declarations);
|
||||||
|
declarationResolver.process(c);
|
||||||
|
overrideResolver.process(c);
|
||||||
|
lockScopes(c);
|
||||||
|
|
||||||
overloadResolver.process(c);
|
overloadResolver.process(c);
|
||||||
|
|
||||||
if (!c.getTopDownAnalysisParameters().isAnalyzingBootstrapLibrary()) {
|
if (!c.getTopDownAnalysisParameters().isAnalyzingBootstrapLibrary()) {
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ import org.jetbrains.jet.lang.resolve.ImportsResolver;
|
|||||||
import org.jetbrains.jet.lang.psi.JetImportsFactory;
|
import org.jetbrains.jet.lang.psi.JetImportsFactory;
|
||||||
import org.jetbrains.jet.lang.resolve.ScriptHeaderResolver;
|
import org.jetbrains.jet.lang.resolve.ScriptHeaderResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.ScriptParameterResolver;
|
import org.jetbrains.jet.lang.resolve.ScriptParameterResolver;
|
||||||
|
import org.jetbrains.jet.lang.resolve.LazyTopDownAnalyzer;
|
||||||
import org.jetbrains.jet.lang.resolve.OverloadResolver;
|
import org.jetbrains.jet.lang.resolve.OverloadResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.OverrideResolver;
|
import org.jetbrains.jet.lang.resolve.OverrideResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.TypeHierarchyResolver;
|
import org.jetbrains.jet.lang.resolve.TypeHierarchyResolver;
|
||||||
@@ -94,6 +95,7 @@ public class InjectorForTopDownAnalyzerForJs {
|
|||||||
private final JetImportsFactory jetImportsFactory;
|
private final JetImportsFactory jetImportsFactory;
|
||||||
private final ScriptHeaderResolver scriptHeaderResolver;
|
private final ScriptHeaderResolver scriptHeaderResolver;
|
||||||
private final ScriptParameterResolver scriptParameterResolver;
|
private final ScriptParameterResolver scriptParameterResolver;
|
||||||
|
private final LazyTopDownAnalyzer lazyTopDownAnalyzer;
|
||||||
private final OverloadResolver overloadResolver;
|
private final OverloadResolver overloadResolver;
|
||||||
private final OverrideResolver overrideResolver;
|
private final OverrideResolver overrideResolver;
|
||||||
private final TypeHierarchyResolver typeHierarchyResolver;
|
private final TypeHierarchyResolver typeHierarchyResolver;
|
||||||
@@ -138,12 +140,14 @@ public class InjectorForTopDownAnalyzerForJs {
|
|||||||
this.jetImportsFactory = new JetImportsFactory();
|
this.jetImportsFactory = new JetImportsFactory();
|
||||||
this.scriptHeaderResolver = new ScriptHeaderResolver();
|
this.scriptHeaderResolver = new ScriptHeaderResolver();
|
||||||
this.scriptParameterResolver = new ScriptParameterResolver();
|
this.scriptParameterResolver = new ScriptParameterResolver();
|
||||||
|
this.lazyTopDownAnalyzer = new LazyTopDownAnalyzer();
|
||||||
this.overloadResolver = new OverloadResolver();
|
this.overloadResolver = new OverloadResolver();
|
||||||
this.overrideResolver = new OverrideResolver();
|
this.overrideResolver = new OverrideResolver();
|
||||||
this.typeHierarchyResolver = new TypeHierarchyResolver();
|
this.typeHierarchyResolver = new TypeHierarchyResolver();
|
||||||
|
|
||||||
this.topDownAnalyzer.setBodyResolver(bodyResolver);
|
this.topDownAnalyzer.setBodyResolver(bodyResolver);
|
||||||
this.topDownAnalyzer.setDeclarationResolver(declarationResolver);
|
this.topDownAnalyzer.setDeclarationResolver(declarationResolver);
|
||||||
|
this.topDownAnalyzer.setLazyTopDownAnalyzer(lazyTopDownAnalyzer);
|
||||||
this.topDownAnalyzer.setModuleDescriptor(moduleDescriptor);
|
this.topDownAnalyzer.setModuleDescriptor(moduleDescriptor);
|
||||||
this.topDownAnalyzer.setOverloadResolver(overloadResolver);
|
this.topDownAnalyzer.setOverloadResolver(overloadResolver);
|
||||||
this.topDownAnalyzer.setOverrideResolver(overrideResolver);
|
this.topDownAnalyzer.setOverrideResolver(overrideResolver);
|
||||||
@@ -239,6 +243,13 @@ public class InjectorForTopDownAnalyzerForJs {
|
|||||||
|
|
||||||
scriptParameterResolver.setDependencyClassByQualifiedNameResolver(dependencyClassByQualifiedNameResolverDummy);
|
scriptParameterResolver.setDependencyClassByQualifiedNameResolver(dependencyClassByQualifiedNameResolverDummy);
|
||||||
|
|
||||||
|
lazyTopDownAnalyzer.setBodyResolver(bodyResolver);
|
||||||
|
lazyTopDownAnalyzer.setDeclarationResolver(declarationResolver);
|
||||||
|
lazyTopDownAnalyzer.setModuleDescriptor(moduleDescriptor);
|
||||||
|
lazyTopDownAnalyzer.setOverloadResolver(overloadResolver);
|
||||||
|
lazyTopDownAnalyzer.setOverrideResolver(overrideResolver);
|
||||||
|
lazyTopDownAnalyzer.setTrace(bindingTrace);
|
||||||
|
|
||||||
overloadResolver.setTrace(bindingTrace);
|
overloadResolver.setTrace(bindingTrace);
|
||||||
|
|
||||||
overrideResolver.setTrace(bindingTrace);
|
overrideResolver.setTrace(bindingTrace);
|
||||||
|
|||||||
Reference in New Issue
Block a user