TopDownAnalyzer and TypeHierarchyResolver deleted

This commit is contained in:
Andrey Breslav
2015-01-23 19:11:06 +03:00
parent 6395fd819f
commit 2b432dd085
5 changed files with 37 additions and 1005 deletions
@@ -1,299 +0,0 @@
/*
* Copyright 2010-2015 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.kotlin.di;
import com.intellij.openapi.project.Project;
import org.jetbrains.kotlin.context.GlobalContext;
import org.jetbrains.kotlin.storage.StorageManager;
import org.jetbrains.kotlin.resolve.BindingTrace;
import org.jetbrains.kotlin.descriptors.ModuleDescriptor;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.platform.PlatformToKotlinClassMap;
import org.jetbrains.kotlin.resolve.TopDownAnalyzer;
import org.jetbrains.kotlin.resolve.MutablePackageFragmentProvider;
import org.jetbrains.kotlin.resolve.AdditionalCheckerProvider;
import org.jetbrains.kotlin.types.DynamicTypesSettings;
import org.jetbrains.kotlin.resolve.BodyResolver;
import org.jetbrains.kotlin.resolve.AnnotationResolver;
import org.jetbrains.kotlin.resolve.calls.CallResolver;
import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver;
import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices;
import org.jetbrains.kotlin.types.expressions.ExpressionTypingComponents;
import org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils;
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils;
import org.jetbrains.kotlin.types.expressions.ForLoopConventionsChecker;
import org.jetbrains.kotlin.types.expressions.LocalClassifierAnalyzer;
import org.jetbrains.kotlin.resolve.DescriptorResolver;
import org.jetbrains.kotlin.resolve.DelegatedPropertyResolver;
import org.jetbrains.kotlin.resolve.TypeResolver;
import org.jetbrains.kotlin.resolve.QualifiedExpressionResolver;
import org.jetbrains.kotlin.resolve.TypeResolver.FlexibleTypeCapabilitiesProvider;
import org.jetbrains.kotlin.context.LazinessToken;
import org.jetbrains.kotlin.types.reflect.ReflectionTypes;
import org.jetbrains.kotlin.resolve.calls.CallExpressionResolver;
import org.jetbrains.kotlin.resolve.PartialBodyResolveProvider;
import org.jetbrains.kotlin.resolve.calls.CallCompleter;
import org.jetbrains.kotlin.resolve.calls.CandidateResolver;
import org.jetbrains.kotlin.resolve.calls.tasks.TaskPrioritizer;
import org.jetbrains.kotlin.resolve.ControlFlowAnalyzer;
import org.jetbrains.kotlin.resolve.DeclarationsChecker;
import org.jetbrains.kotlin.resolve.ModifiersChecker;
import org.jetbrains.kotlin.resolve.FunctionAnalyzerExtension;
import org.jetbrains.kotlin.resolve.ScriptBodyResolver;
import org.jetbrains.kotlin.resolve.DeclarationResolver;
import org.jetbrains.kotlin.resolve.ImportsResolver;
import org.jetbrains.kotlin.psi.JetImportsFactory;
import org.jetbrains.kotlin.resolve.OverloadResolver;
import org.jetbrains.kotlin.resolve.OverrideResolver;
import org.jetbrains.kotlin.resolve.TypeHierarchyResolver;
import org.jetbrains.kotlin.resolve.ScriptHeaderResolver;
import org.jetbrains.kotlin.resolve.varianceChecker.VarianceChecker;
import org.jetbrains.annotations.NotNull;
import javax.annotation.PreDestroy;
/* This file is generated by org.jetbrains.kotlin.generators.injectors.InjectorsPackage. DO NOT EDIT! */
@SuppressWarnings("all")
public class InjectorForTopDownAnalyzerBasic {
private final Project project;
private final GlobalContext globalContext;
private final StorageManager storageManager;
private final BindingTrace bindingTrace;
private final ModuleDescriptor moduleDescriptor;
private final KotlinBuiltIns kotlinBuiltIns;
private final PlatformToKotlinClassMap platformToKotlinClassMap;
private final TopDownAnalyzer topDownAnalyzer;
private final MutablePackageFragmentProvider mutablePackageFragmentProvider;
private final AdditionalCheckerProvider additionalCheckerProvider;
private final DynamicTypesSettings dynamicTypesSettings;
private final BodyResolver bodyResolver;
private final AnnotationResolver annotationResolver;
private final CallResolver callResolver;
private final ArgumentTypeResolver argumentTypeResolver;
private final ExpressionTypingServices expressionTypingServices;
private final ExpressionTypingComponents expressionTypingComponents;
private final ControlStructureTypingUtils controlStructureTypingUtils;
private final ExpressionTypingUtils expressionTypingUtils;
private final ForLoopConventionsChecker forLoopConventionsChecker;
private final LocalClassifierAnalyzer localClassifierAnalyzer;
private final DescriptorResolver descriptorResolver;
private final DelegatedPropertyResolver delegatedPropertyResolver;
private final TypeResolver typeResolver;
private final QualifiedExpressionResolver qualifiedExpressionResolver;
private final FlexibleTypeCapabilitiesProvider flexibleTypeCapabilitiesProvider;
private final LazinessToken lazinessToken;
private final ReflectionTypes reflectionTypes;
private final CallExpressionResolver callExpressionResolver;
private final PartialBodyResolveProvider partialBodyResolveProvider;
private final CallCompleter callCompleter;
private final CandidateResolver candidateResolver;
private final TaskPrioritizer taskPrioritizer;
private final ControlFlowAnalyzer controlFlowAnalyzer;
private final DeclarationsChecker declarationsChecker;
private final ModifiersChecker modifiersChecker;
private final FunctionAnalyzerExtension functionAnalyzerExtension;
private final ScriptBodyResolver scriptBodyResolver;
private final DeclarationResolver declarationResolver;
private final ImportsResolver importsResolver;
private final JetImportsFactory jetImportsFactory;
private final OverloadResolver overloadResolver;
private final OverrideResolver overrideResolver;
private final TypeHierarchyResolver typeHierarchyResolver;
private final ScriptHeaderResolver scriptHeaderResolver;
private final VarianceChecker varianceChecker;
public InjectorForTopDownAnalyzerBasic(
@NotNull Project project,
@NotNull GlobalContext globalContext,
@NotNull BindingTrace bindingTrace,
@NotNull ModuleDescriptor moduleDescriptor,
@NotNull AdditionalCheckerProvider additionalCheckerProvider,
@NotNull DynamicTypesSettings dynamicTypesSettings
) {
this.project = project;
this.globalContext = globalContext;
this.storageManager = globalContext.getStorageManager();
this.bindingTrace = bindingTrace;
this.moduleDescriptor = moduleDescriptor;
this.kotlinBuiltIns = moduleDescriptor.getBuiltIns();
this.platformToKotlinClassMap = moduleDescriptor.getPlatformToKotlinClassMap();
this.topDownAnalyzer = new TopDownAnalyzer();
this.mutablePackageFragmentProvider = new MutablePackageFragmentProvider(getModuleDescriptor());
this.additionalCheckerProvider = additionalCheckerProvider;
this.dynamicTypesSettings = dynamicTypesSettings;
this.bodyResolver = new BodyResolver();
this.annotationResolver = new AnnotationResolver();
this.callResolver = new CallResolver();
this.argumentTypeResolver = new ArgumentTypeResolver();
this.expressionTypingComponents = new ExpressionTypingComponents();
this.expressionTypingServices = new ExpressionTypingServices(expressionTypingComponents);
this.controlStructureTypingUtils = new ControlStructureTypingUtils(expressionTypingServices);
this.expressionTypingUtils = new ExpressionTypingUtils(expressionTypingServices, callResolver, kotlinBuiltIns);
this.forLoopConventionsChecker = new ForLoopConventionsChecker();
this.descriptorResolver = new DescriptorResolver();
this.qualifiedExpressionResolver = new QualifiedExpressionResolver();
this.flexibleTypeCapabilitiesProvider = new FlexibleTypeCapabilitiesProvider();
this.lazinessToken = new LazinessToken();
this.typeResolver = new TypeResolver(annotationResolver, qualifiedExpressionResolver, getModuleDescriptor(), flexibleTypeCapabilitiesProvider, storageManager, lazinessToken, dynamicTypesSettings);
this.localClassifierAnalyzer = new LocalClassifierAnalyzer(descriptorResolver, typeResolver, annotationResolver);
this.delegatedPropertyResolver = new DelegatedPropertyResolver();
this.reflectionTypes = new ReflectionTypes(getModuleDescriptor());
this.callExpressionResolver = new CallExpressionResolver();
this.partialBodyResolveProvider = new PartialBodyResolveProvider();
this.candidateResolver = new CandidateResolver();
this.callCompleter = new CallCompleter(argumentTypeResolver, candidateResolver);
this.taskPrioritizer = new TaskPrioritizer(storageManager);
this.controlFlowAnalyzer = new ControlFlowAnalyzer();
this.declarationsChecker = new DeclarationsChecker();
this.modifiersChecker = new ModifiersChecker(bindingTrace, additionalCheckerProvider);
this.functionAnalyzerExtension = new FunctionAnalyzerExtension();
this.scriptBodyResolver = new ScriptBodyResolver();
this.declarationResolver = new DeclarationResolver();
this.importsResolver = new ImportsResolver();
this.jetImportsFactory = new JetImportsFactory();
this.overloadResolver = new OverloadResolver();
this.overrideResolver = new OverrideResolver();
this.typeHierarchyResolver = new TypeHierarchyResolver();
this.scriptHeaderResolver = new ScriptHeaderResolver();
this.varianceChecker = new VarianceChecker(bindingTrace);
this.topDownAnalyzer.setBodyResolver(bodyResolver);
this.topDownAnalyzer.setDeclarationResolver(declarationResolver);
this.topDownAnalyzer.setModuleDescriptor(moduleDescriptor);
this.topDownAnalyzer.setOverloadResolver(overloadResolver);
this.topDownAnalyzer.setOverrideResolver(overrideResolver);
this.topDownAnalyzer.setPackageFragmentProvider(mutablePackageFragmentProvider);
this.topDownAnalyzer.setTypeHierarchyResolver(typeHierarchyResolver);
this.topDownAnalyzer.setVarianceChecker(varianceChecker);
bodyResolver.setAnnotationResolver(annotationResolver);
bodyResolver.setCallResolver(callResolver);
bodyResolver.setControlFlowAnalyzer(controlFlowAnalyzer);
bodyResolver.setDeclarationsChecker(declarationsChecker);
bodyResolver.setDelegatedPropertyResolver(delegatedPropertyResolver);
bodyResolver.setExpressionTypingServices(expressionTypingServices);
bodyResolver.setFunctionAnalyzerExtension(functionAnalyzerExtension);
bodyResolver.setScriptBodyResolverResolver(scriptBodyResolver);
bodyResolver.setTrace(bindingTrace);
annotationResolver.setCallResolver(callResolver);
annotationResolver.setStorageManager(storageManager);
annotationResolver.setTypeResolver(typeResolver);
callResolver.setArgumentTypeResolver(argumentTypeResolver);
callResolver.setCallCompleter(callCompleter);
callResolver.setCandidateResolver(candidateResolver);
callResolver.setExpressionTypingServices(expressionTypingServices);
callResolver.setTaskPrioritizer(taskPrioritizer);
callResolver.setTypeResolver(typeResolver);
argumentTypeResolver.setBuiltIns(kotlinBuiltIns);
argumentTypeResolver.setExpressionTypingServices(expressionTypingServices);
argumentTypeResolver.setTypeResolver(typeResolver);
expressionTypingServices.setAnnotationResolver(annotationResolver);
expressionTypingServices.setBuiltIns(kotlinBuiltIns);
expressionTypingServices.setCallExpressionResolver(callExpressionResolver);
expressionTypingServices.setCallResolver(callResolver);
expressionTypingServices.setDescriptorResolver(descriptorResolver);
expressionTypingServices.setPartialBodyResolveProvider(partialBodyResolveProvider);
expressionTypingServices.setProject(project);
expressionTypingServices.setTypeResolver(typeResolver);
expressionTypingComponents.setAdditionalCheckerProvider(additionalCheckerProvider);
expressionTypingComponents.setBuiltIns(kotlinBuiltIns);
expressionTypingComponents.setCallResolver(callResolver);
expressionTypingComponents.setControlStructureTypingUtils(controlStructureTypingUtils);
expressionTypingComponents.setDynamicTypesSettings(dynamicTypesSettings);
expressionTypingComponents.setExpressionTypingServices(expressionTypingServices);
expressionTypingComponents.setExpressionTypingUtils(expressionTypingUtils);
expressionTypingComponents.setForLoopConventionsChecker(forLoopConventionsChecker);
expressionTypingComponents.setGlobalContext(globalContext);
expressionTypingComponents.setLocalClassifierAnalyzer(localClassifierAnalyzer);
expressionTypingComponents.setPlatformToKotlinClassMap(platformToKotlinClassMap);
expressionTypingComponents.setReflectionTypes(reflectionTypes);
forLoopConventionsChecker.setBuiltIns(kotlinBuiltIns);
forLoopConventionsChecker.setExpressionTypingServices(expressionTypingServices);
forLoopConventionsChecker.setExpressionTypingUtils(expressionTypingUtils);
forLoopConventionsChecker.setProject(project);
descriptorResolver.setAnnotationResolver(annotationResolver);
descriptorResolver.setBuiltIns(kotlinBuiltIns);
descriptorResolver.setDelegatedPropertyResolver(delegatedPropertyResolver);
descriptorResolver.setExpressionTypingServices(expressionTypingServices);
descriptorResolver.setStorageManager(storageManager);
descriptorResolver.setTypeResolver(typeResolver);
delegatedPropertyResolver.setBuiltIns(kotlinBuiltIns);
delegatedPropertyResolver.setCallResolver(callResolver);
delegatedPropertyResolver.setExpressionTypingServices(expressionTypingServices);
callExpressionResolver.setExpressionTypingServices(expressionTypingServices);
candidateResolver.setArgumentTypeResolver(argumentTypeResolver);
controlFlowAnalyzer.setTrace(bindingTrace);
declarationsChecker.setDescriptorResolver(descriptorResolver);
declarationsChecker.setModifiersChecker(modifiersChecker);
declarationsChecker.setTrace(bindingTrace);
functionAnalyzerExtension.setTrace(bindingTrace);
scriptBodyResolver.setExpressionTypingServices(expressionTypingServices);
declarationResolver.setAnnotationResolver(annotationResolver);
declarationResolver.setDescriptorResolver(descriptorResolver);
declarationResolver.setImportsResolver(importsResolver);
declarationResolver.setTrace(bindingTrace);
importsResolver.setImportsFactory(jetImportsFactory);
importsResolver.setModuleDescriptor(moduleDescriptor);
importsResolver.setQualifiedExpressionResolver(qualifiedExpressionResolver);
importsResolver.setTrace(bindingTrace);
jetImportsFactory.setProject(project);
overloadResolver.setTrace(bindingTrace);
overrideResolver.setTrace(bindingTrace);
typeHierarchyResolver.setDescriptorResolver(descriptorResolver);
typeHierarchyResolver.setImportsResolver(importsResolver);
typeHierarchyResolver.setPackageFragmentProvider(mutablePackageFragmentProvider);
typeHierarchyResolver.setScriptHeaderResolver(scriptHeaderResolver);
typeHierarchyResolver.setTrace(bindingTrace);
scriptHeaderResolver.setPackageFragmentProvider(mutablePackageFragmentProvider);
scriptHeaderResolver.setTrace(bindingTrace);
}
@PreDestroy
public void destroy() {
}
public ModuleDescriptor getModuleDescriptor() {
return this.moduleDescriptor;
}
public TopDownAnalyzer getTopDownAnalyzer() {
return this.topDownAnalyzer;
}
}
@@ -1,179 +0,0 @@
/*
* Copyright 2010-2015 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.kotlin.resolve;
import com.google.common.collect.Sets;
import com.intellij.psi.PsiElement;
import kotlin.KotlinPackage;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.descriptors.ClassDescriptorWithResolutionScopes;
import org.jetbrains.kotlin.descriptors.ModuleDescriptor;
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider;
import org.jetbrains.kotlin.descriptors.impl.*;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.psi.JetFile;
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
import org.jetbrains.kotlin.resolve.scopes.JetScope;
import org.jetbrains.kotlin.resolve.scopes.WritableScope;
import org.jetbrains.kotlin.resolve.varianceChecker.VarianceChecker;
import javax.inject.Inject;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Set;
@Deprecated
public class TopDownAnalyzer {
private DeclarationResolver declarationResolver;
private TypeHierarchyResolver typeHierarchyResolver;
private OverrideResolver overrideResolver;
private VarianceChecker varianceChecker;
private OverloadResolver overloadResolver;
private ModuleDescriptor moduleDescriptor;
private MutablePackageFragmentProvider packageFragmentProvider;
private BodyResolver bodyResolver;
public TopDownAnalyzer() {
}
@Inject
public void setDeclarationResolver(@NotNull DeclarationResolver declarationResolver) {
this.declarationResolver = declarationResolver;
}
@Inject
public void setTypeHierarchyResolver(@NotNull TypeHierarchyResolver typeHierarchyResolver) {
this.typeHierarchyResolver = typeHierarchyResolver;
}
@Inject
public void setOverrideResolver(@NotNull OverrideResolver overrideResolver) {
this.overrideResolver = overrideResolver;
}
@Inject
public void setVarianceChecker(@NotNull VarianceChecker varianceChecker) {
this.varianceChecker = varianceChecker;
}
@Inject
public void setOverloadResolver(@NotNull OverloadResolver overloadResolver) {
this.overloadResolver = overloadResolver;
}
@Inject
public void setModuleDescriptor(@NotNull ModuleDescriptor moduleDescriptor) {
this.moduleDescriptor = moduleDescriptor;
}
@Inject
public void setPackageFragmentProvider(@NotNull MutablePackageFragmentProvider packageFragmentProvider) {
this.packageFragmentProvider = packageFragmentProvider;
}
@Inject
public void setBodyResolver(@NotNull BodyResolver bodyResolver) {
this.bodyResolver = bodyResolver;
}
public void doProcess(
@NotNull TopDownAnalysisContext c,
@NotNull JetScope outerScope,
@NotNull PackageLikeBuilder owner,
@NotNull Collection<? extends PsiElement> declarations
) {
// c.enableDebugOutput();
c.debug("Enter");
typeHierarchyResolver.process(c, outerScope, owner, declarations);
declarationResolver.process(c);
overrideResolver.process(c);
varianceChecker.process(c);
lockScopes(c);
overloadResolver.process(c);
if (!c.getTopDownAnalysisParameters().isAnalyzingBootstrapLibrary()) {
bodyResolver.resolveBodies(c);
}
c.debug("Exit");
//noinspection UseOfSystemOutOrSystemErr
c.printDebugOutput(System.out);
}
private void lockScopes(@NotNull TopDownAnalysisContext c) {
for (ClassDescriptorWithResolutionScopes mutableClassDescriptor : c.getDeclaredClasses().values()) {
((MutableClassDescriptor) mutableClassDescriptor).lockScopes();
}
// SCRIPT: extra code for scripts
Set<FqName> scriptFqNames = Sets.newHashSet();
for (JetFile file : c.getFileScopes().keySet()) {
if (file.isScript()) {
scriptFqNames.add(file.getPackageFqName());
}
}
for (MutablePackageFragmentDescriptor fragment : packageFragmentProvider.getAllFragments()) {
// todo: this is hack in favor of REPL
if (!scriptFqNames.contains(fragment.getFqName())) {
fragment.getMemberScope().changeLockLevel(WritableScope.LockLevel.READING);
}
}
}
@NotNull
public TopDownAnalysisContext analyzeFiles(
@NotNull TopDownAnalysisParameters topDownAnalysisParameters,
@NotNull Collection<JetFile> files,
@NotNull PackageFragmentProvider... additionalProviders
) {
return analyzeFiles(topDownAnalysisParameters, files, Arrays.asList(additionalProviders));
}
@NotNull
public TopDownAnalysisContext analyzeFiles(
@NotNull TopDownAnalysisParameters topDownAnalysisParameters,
@NotNull Collection<JetFile> files,
@NotNull List<PackageFragmentProvider> additionalProviders
) {
//noinspection deprecation
assert !topDownAnalysisParameters.isLazy() : "Lazy resolve must be disabled for this method";
TopDownAnalysisContext c = new TopDownAnalysisContext(topDownAnalysisParameters, DataFlowInfo.EMPTY);
CompositePackageFragmentProvider provider =
new CompositePackageFragmentProvider(KotlinPackage.plus(Arrays.asList(packageFragmentProvider), additionalProviders));
((ModuleDescriptorImpl) moduleDescriptor).initialize(provider);
// dummy builder is used because "root" is module descriptor,
// packages added to module explicitly in
doProcess(c, JetModuleUtil.getSubpackagesOfRootScope(moduleDescriptor), new PackageLikeBuilderDummy(), files);
return c;
}
@NotNull
public MutablePackageFragmentProvider getPackageFragmentProvider() {
return packageFragmentProvider;
}
}
@@ -1,505 +0,0 @@
/*
* Copyright 2010-2015 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.kotlin.resolve;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiNameIdentifierOwner;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.impl.ConstructorDescriptorImpl;
import org.jetbrains.kotlin.descriptors.impl.MutableClassDescriptor;
import org.jetbrains.kotlin.descriptors.impl.MutablePackageFragmentDescriptor;
import org.jetbrains.kotlin.descriptors.impl.PackageLikeBuilder;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.name.SpecialNames;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.scopes.ChainedScope;
import org.jetbrains.kotlin.resolve.scopes.JetScope;
import org.jetbrains.kotlin.resolve.scopes.WritableScope;
import org.jetbrains.kotlin.resolve.scopes.WriteThroughScope;
import org.jetbrains.kotlin.types.JetType;
import org.jetbrains.kotlin.utils.DFS;
import javax.inject.Inject;
import java.util.*;
import static org.jetbrains.kotlin.diagnostics.Errors.*;
import static org.jetbrains.kotlin.name.SpecialNames.getClassObjectName;
import static org.jetbrains.kotlin.resolve.BindingContext.FQNAME_TO_CLASS_DESCRIPTOR;
import static org.jetbrains.kotlin.resolve.BindingContext.TYPE;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isEnumEntry;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isObject;
import static org.jetbrains.kotlin.resolve.ModifiersChecker.getDefaultClassVisibility;
import static org.jetbrains.kotlin.resolve.ModifiersChecker.resolveVisibilityFromModifiers;
import static org.jetbrains.kotlin.resolve.source.SourcePackage.toSourceElement;
public class TypeHierarchyResolver {
private static final DFS.Neighbors<ClassDescriptor> CLASS_INHERITANCE_EDGES = new DFS.Neighbors<ClassDescriptor>() {
@NotNull
@Override
public Iterable<ClassDescriptor> getNeighbors(ClassDescriptor current) {
List<ClassDescriptor> result = new ArrayList<ClassDescriptor>();
for (JetType supertype : current.getDefaultType().getConstructor().getSupertypes()) {
DeclarationDescriptor descriptor = supertype.getConstructor().getDeclarationDescriptor();
if (descriptor instanceof ClassDescriptor) {
result.add((ClassDescriptor) descriptor);
}
}
DeclarationDescriptor container = current.getContainingDeclaration();
if (container instanceof ClassDescriptor) {
result.add((ClassDescriptor) container);
}
return result;
}
};
@NotNull
private ImportsResolver importsResolver;
@NotNull
private DescriptorResolver descriptorResolver;
@NotNull
private ScriptHeaderResolver scriptHeaderResolver;
@NotNull
private MutablePackageFragmentProvider packageFragmentProvider;
@NotNull
private BindingTrace trace;
@Inject
public void setImportsResolver(@NotNull ImportsResolver importsResolver) {
this.importsResolver = importsResolver;
}
@Inject
public void setDescriptorResolver(@NotNull DescriptorResolver descriptorResolver) {
this.descriptorResolver = descriptorResolver;
}
// SCRIPT: inject script header resolver
@Inject
public void setScriptHeaderResolver(@NotNull ScriptHeaderResolver scriptHeaderResolver) {
this.scriptHeaderResolver = scriptHeaderResolver;
}
@Inject
public void setPackageFragmentProvider(@NotNull MutablePackageFragmentProvider packageFragmentProvider) {
this.packageFragmentProvider = packageFragmentProvider;
}
@Inject
public void setTrace(@NotNull BindingTrace trace) {
this.trace = trace;
}
public void process(
@NotNull TopDownAnalysisContext c,
@NotNull JetScope outerScope,
@NotNull PackageLikeBuilder owner,
@NotNull Collection<? extends PsiElement> declarations
) {
{
// TODO: Very temp code - main goal is to remove recursion from collectPackageFragmentsAndClassifiers
Queue<JetDeclarationContainer> forDeferredResolve = new LinkedList<JetDeclarationContainer>();
forDeferredResolve.addAll(collectPackageFragmentsAndClassifiers(c, outerScope, owner, declarations));
while (!forDeferredResolve.isEmpty()) {
JetDeclarationContainer declarationContainer = forDeferredResolve.poll();
assert declarationContainer != null;
DeclarationDescriptor descriptorForDeferredResolve = c.forDeferredResolver.get(declarationContainer);
JetScope scope = c.normalScope.get(declarationContainer);
// Even more temp code
if (descriptorForDeferredResolve instanceof MutableClassDescriptor) {
forDeferredResolve.addAll(
collectPackageFragmentsAndClassifiers(
c,
scope,
((MutableClassDescriptor) descriptorForDeferredResolve).getBuilder(),
declarationContainer.getDeclarations()));
}
else if (descriptorForDeferredResolve instanceof MutablePackageFragmentDescriptor) {
forDeferredResolve.addAll(
collectPackageFragmentsAndClassifiers(
c,
scope,
((MutablePackageFragmentDescriptor) descriptorForDeferredResolve).getBuilder(),
declarationContainer.getDeclarations()));
}
else {
assert false;
}
}
}
importsResolver.processTypeImports(c);
createTypeConstructors(c); // create type constructors for classes and generic parameters, supertypes are not filled in
resolveTypesInClassHeaders(c); // Generic bounds and types in supertype lists (no expressions or constructor resolution)
c.setClassesTopologicalOrder(topologicallySortClassesAndObjects(c));
// Detect and disconnect all loops in the hierarchy
detectAndDisconnectLoops(c);
}
@NotNull
private Collection<JetDeclarationContainer> collectPackageFragmentsAndClassifiers(
@NotNull TopDownAnalysisContext c,
@NotNull JetScope outerScope,
@NotNull PackageLikeBuilder owner,
@NotNull Iterable<? extends PsiElement> declarations
) {
Collection<JetDeclarationContainer> forDeferredResolve = new ArrayList<JetDeclarationContainer>();
ClassifierCollector collector = new ClassifierCollector(c, outerScope, owner, forDeferredResolve);
for (PsiElement declaration : declarations) {
declaration.accept(collector);
}
return forDeferredResolve;
}
@NotNull
private static ClassKind getClassKind(@NotNull JetClass jetClass) {
if (jetClass.isTrait()) return ClassKind.TRAIT;
if (jetClass.isAnnotation()) return ClassKind.ANNOTATION_CLASS;
if (jetClass.isEnum()) return ClassKind.ENUM_CLASS;
return ClassKind.CLASS;
}
private void createTypeConstructors(@NotNull TopDownAnalysisContext c) {
for (Map.Entry<JetClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getDeclaredClasses().entrySet()) {
JetClassOrObject classOrObject = entry.getKey();
MutableClassDescriptor descriptor = (MutableClassDescriptor) entry.getValue();
if (classOrObject instanceof JetClass) {
descriptorResolver.resolveMutableClassDescriptor(
c.getTopDownAnalysisParameters(),
(JetClass) classOrObject, descriptor, trace);
}
else if (classOrObject instanceof JetObjectDeclaration) {
descriptor.setModality(Modality.FINAL);
descriptor.setVisibility(resolveVisibilityFromModifiers(classOrObject, getDefaultClassVisibility(descriptor)));
descriptor.setTypeParameterDescriptors(Collections.<TypeParameterDescriptor>emptyList());
}
descriptor.createTypeConstructor();
ClassKind kind = descriptor.getKind();
if (kind == ClassKind.ENUM_ENTRY || kind == ClassKind.OBJECT) {
MutableClassDescriptor classObject = descriptor.getClassObjectDescriptor();
assert classObject != null : "Enum entries and named objects should have class objects: " + classOrObject.getText();
// This is a clever hack: each enum entry and object declaration (i.e. singleton) has a synthetic class object.
// We make this class object inherit from the singleton here, thus allowing to use the singleton's class object where
// the instance of the singleton is applicable. Effectively all members of the singleton would be present in its class
// object as fake overrides, so you can access them via standard class object notation: ObjectName.memberName()
classObject.setSupertypes(Collections.singleton(descriptor.getDefaultType()));
classObject.createTypeConstructor();
}
}
}
private void resolveTypesInClassHeaders(@NotNull TopDownAnalysisContext c) {
for (Map.Entry<JetClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getDeclaredClasses().entrySet()) {
JetClassOrObject classOrObject = entry.getKey();
if (classOrObject instanceof JetClass) {
ClassDescriptorWithResolutionScopes descriptor = entry.getValue();
//noinspection unchecked
descriptorResolver.resolveGenericBounds((JetClass) classOrObject, descriptor, descriptor.getScopeForClassHeaderResolution(),
(List) descriptor.getTypeConstructor().getParameters(), trace);
}
}
for (Map.Entry<JetClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getDeclaredClasses().entrySet()) {
descriptorResolver.resolveSupertypesForMutableClassDescriptor(entry.getKey(), (MutableClassDescriptor) entry.getValue(), trace);
}
}
@NotNull
@SuppressWarnings("unchecked")
private static List<MutableClassDescriptor> topologicallySortClassesAndObjects(@NotNull TopDownAnalysisContext c) {
Collection<ClassDescriptor> sourceClasses = (Collection) c.getAllClasses();
List<ClassDescriptor> allClassesOrdered = DFS.topologicalOrder(sourceClasses, CLASS_INHERITANCE_EDGES);
allClassesOrdered.retainAll(sourceClasses);
return (List) allClassesOrdered;
}
private void detectAndDisconnectLoops(@NotNull TopDownAnalysisContext c) {
List<Runnable> tasks = new ArrayList<Runnable>();
for (final MutableClassDescriptor klass : c.getClassesTopologicalOrder()) {
for (final JetType supertype : klass.getSupertypes()) {
ClassifierDescriptor supertypeDescriptor = supertype.getConstructor().getDeclarationDescriptor();
if (supertypeDescriptor instanceof ClassDescriptor) {
ClassDescriptor superclass = (ClassDescriptor) supertypeDescriptor;
if (isReachable(superclass, klass, new HashSet<ClassDescriptor>())) {
tasks.add(new Runnable() {
@Override
public void run() {
klass.getSupertypes().remove(supertype);
}
});
reportCyclicInheritanceHierarchyError(trace, klass, superclass);
}
}
}
}
for (Runnable task : tasks) {
task.run();
}
}
// TODO: use DFS and copy to LazyClassTypeConstructor.isReachable
private static boolean isReachable(
@NotNull ClassDescriptor from,
@NotNull MutableClassDescriptor to,
@NotNull Set<ClassDescriptor> visited
) {
if (!visited.add(from)) return false;
for (ClassDescriptor superclass : CLASS_INHERITANCE_EDGES.getNeighbors(from)) {
if (superclass == to || isReachable(superclass, to, visited)) return true;
}
return false;
}
public static void reportCyclicInheritanceHierarchyError(
@NotNull BindingTrace trace,
@NotNull ClassDescriptor classDescriptor,
@NotNull ClassDescriptor superclass
) {
PsiElement psiElement = DescriptorToSourceUtils.classDescriptorToDeclaration(classDescriptor);
PsiElement elementToMark = null;
if (psiElement instanceof JetClassOrObject) {
JetClassOrObject classOrObject = (JetClassOrObject) psiElement;
for (JetDelegationSpecifier delegationSpecifier : classOrObject.getDelegationSpecifiers()) {
JetTypeReference typeReference = delegationSpecifier.getTypeReference();
if (typeReference == null) continue;
JetType supertype = trace.get(TYPE, typeReference);
if (supertype != null && supertype.getConstructor() == superclass.getTypeConstructor()) {
elementToMark = typeReference;
}
}
}
if (elementToMark == null && psiElement instanceof PsiNameIdentifierOwner) {
PsiNameIdentifierOwner namedElement = (PsiNameIdentifierOwner) psiElement;
PsiElement nameIdentifier = namedElement.getNameIdentifier();
if (nameIdentifier != null) {
elementToMark = nameIdentifier;
}
}
if (elementToMark != null) {
trace.report(CYCLIC_INHERITANCE_HIERARCHY.on(elementToMark));
}
}
private class ClassifierCollector extends JetVisitorVoid {
private final TopDownAnalysisContext c;
private final JetScope outerScope;
private final PackageLikeBuilder owner;
private final Collection<JetDeclarationContainer> forDeferredResolve;
public ClassifierCollector(
@NotNull TopDownAnalysisContext c,
@NotNull JetScope outerScope,
@NotNull PackageLikeBuilder owner,
@NotNull Collection<JetDeclarationContainer> forDeferredResolve
) {
this.c = c;
this.outerScope = outerScope;
this.owner = owner;
this.forDeferredResolve = forDeferredResolve;
}
@Override
public void visitJetFile(@NotNull JetFile file) {
MutablePackageFragmentDescriptor packageFragment = getOrCreatePackageFragmentForFile(file);
c.getPackageFragments().put(file, packageFragment);
c.addFile(file);
PackageViewDescriptor packageView = packageFragment.getContainingDeclaration().getPackage(packageFragment.getFqName());
ChainedScope rootPlusPackageScope = new ChainedScope(packageView, "Root scope for " + file, packageView.getMemberScope(), outerScope);
WriteThroughScope packageScope = new WriteThroughScope(rootPlusPackageScope, packageFragment.getMemberScope(),
new TraceBasedRedeclarationHandler(trace), "package in file " + file.getName());
packageScope.changeLockLevel(WritableScope.LockLevel.BOTH);
c.getFileScopes().put(file, packageScope);
if (file.isScript()) {
// SCRIPT: process script hierarchy
scriptHeaderResolver.processScriptHierarchy(c, file.getScript(), packageScope);
}
prepareForDeferredCall(packageScope, packageFragment, file);
}
@Override
public void visitClass(@NotNull JetClass klass) {
MutableClassDescriptor mutableClassDescriptor = createClassDescriptorForClass(klass, owner.getOwnerForChildren());
owner.addClassifierDescriptor(mutableClassDescriptor);
}
@Override
public void visitObjectDeclaration(@NotNull JetObjectDeclaration declaration) {
if (declaration.isObjectLiteral()) {
createClassDescriptorForSingleton(declaration, SpecialNames.NO_NAME_PROVIDED, ClassKind.CLASS);
return;
}
MutableClassDescriptor descriptor =
createClassDescriptorForSingleton(declaration, JetPsiUtil.safeName(declaration.getName()), ClassKind.OBJECT);
owner.addClassifierDescriptor(descriptor);
trace.record(FQNAME_TO_CLASS_DESCRIPTOR, JetNamedDeclarationUtil.getUnsafeFQName(declaration), descriptor);
descriptor.getBuilder().setClassObjectDescriptor(createSyntheticClassObjectForSingleton(descriptor));
}
@Override
public void visitEnumEntry(@NotNull JetEnumEntry declaration) {
MutableClassDescriptor descriptor =
createClassDescriptorForSingleton(declaration, JetPsiUtil.safeName(declaration.getName()), ClassKind.ENUM_ENTRY);
owner.addClassifierDescriptor(descriptor);
descriptor.getBuilder().setClassObjectDescriptor(createSyntheticClassObjectForSingleton(descriptor));
}
@Override
public void visitTypedef(@NotNull JetTypedef typedef) {
trace.report(UNSUPPORTED.on(typedef, "TypeHierarchyResolver"));
}
@Override
public void visitClassObject(@NotNull JetClassObject classObject) {
JetObjectDeclaration objectDeclaration = classObject.getObjectDeclaration();
DeclarationDescriptor container = owner.getOwnerForChildren();
MutableClassDescriptor classObjectDescriptor =
createClassDescriptorForSingleton(objectDeclaration, getClassObjectName(container.getName()), ClassKind.CLASS_OBJECT);
PackageLikeBuilder.ClassObjectStatus status =
isEnumEntry(container) || isObject(container) || c.getTopDownAnalysisParameters().isDeclaredLocally() ?
PackageLikeBuilder.ClassObjectStatus.NOT_ALLOWED :
owner.setClassObjectDescriptor(classObjectDescriptor);
switch (status) {
case DUPLICATE:
trace.report(MANY_CLASS_OBJECTS.on(classObject));
break;
case NOT_ALLOWED:
trace.report(CLASS_OBJECT_NOT_ALLOWED.on(classObject));
break;
case OK:
// Everything is OK so no errors to trace.
break;
}
}
@NotNull
private MutablePackageFragmentDescriptor getOrCreatePackageFragmentForFile(@NotNull JetFile file) {
JetPackageDirective packageDirective = file.getPackageDirective();
assert packageDirective != null : "scripts are not supported";
MutablePackageFragmentDescriptor fragment = packageFragmentProvider.getOrCreateFragment(packageDirective.getFqName());
ModuleDescriptor module = packageFragmentProvider.getModule();
DescriptorResolver.resolvePackageHeader(packageDirective, module, trace);
DescriptorResolver.registerFileInPackage(trace, file);
trace.record(BindingContext.FILE_TO_PACKAGE_FRAGMENT, file, fragment);
return fragment;
}
@NotNull
private MutableClassDescriptor createSyntheticClassObjectForSingleton(@NotNull ClassDescriptor classDescriptor) {
MutableClassDescriptor classObject =
new MutableClassDescriptor(classDescriptor, outerScope, ClassKind.CLASS_OBJECT, false,
getClassObjectName(classDescriptor.getName()), SourceElement.NO_SOURCE);
classObject.setModality(Modality.FINAL);
classObject.setVisibility(DescriptorUtils.getSyntheticClassObjectVisibility());
classObject.setTypeParameterDescriptors(Collections.<TypeParameterDescriptor>emptyList());
createPrimaryConstructorForObject(null, classObject);
return classObject;
}
@NotNull
private MutableClassDescriptor createClassDescriptorForClass(
@NotNull JetClass klass,
@NotNull DeclarationDescriptor containingDeclaration
) {
MutableClassDescriptor descriptor = new MutableClassDescriptor(
containingDeclaration, outerScope, getClassKind(klass), klass.isInner(), JetPsiUtil.safeName(klass.getName()),
toSourceElement(klass)
);
c.getDeclaredClasses().put(klass, descriptor);
trace.record(FQNAME_TO_CLASS_DESCRIPTOR, JetNamedDeclarationUtil.getUnsafeFQName(klass), descriptor);
prepareForDeferredCall(descriptor.getScopeForMemberDeclarationResolution(), descriptor, klass);
return descriptor;
}
@NotNull
private MutableClassDescriptor createClassDescriptorForSingleton(
@NotNull JetClassOrObject declaration,
@NotNull Name name,
@NotNull ClassKind kind
) {
MutableClassDescriptor descriptor = new MutableClassDescriptor(owner.getOwnerForChildren(), outerScope, kind, false, name,
toSourceElement(declaration));
prepareForDeferredCall(descriptor.getScopeForMemberDeclarationResolution(), descriptor, declaration);
createPrimaryConstructorForObject(declaration, descriptor);
trace.record(BindingContext.CLASS, declaration, descriptor);
c.getDeclaredClasses().put(declaration, descriptor);
return descriptor;
}
@NotNull
private ConstructorDescriptorImpl createPrimaryConstructorForObject(
@Nullable JetClassOrObject object,
@NotNull MutableClassDescriptor mutableClassDescriptor
) {
ConstructorDescriptorImpl constructorDescriptor = DescriptorResolver
.createAndRecordPrimaryConstructorForObject(object, mutableClassDescriptor, trace);
mutableClassDescriptor.setPrimaryConstructor(constructorDescriptor);
return constructorDescriptor;
}
private void prepareForDeferredCall(
@NotNull JetScope outerScope,
@NotNull DeclarationDescriptor descriptorForDeferredResolve,
@NotNull JetDeclarationContainer container
) {
forDeferredResolve.add(container);
c.normalScope.put(container, outerScope);
c.forDeferredResolver.put(container, descriptorForDeferredResolve);
}
}
}
@@ -19,6 +19,8 @@ package org.jetbrains.kotlin.resolve.lazy.descriptors;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiNameIdentifierOwner;
import kotlin.Function0;
import kotlin.Function1;
import kotlin.KotlinPackage;
@@ -34,10 +36,7 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorBase;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.ModifiersChecker;
import org.jetbrains.kotlin.resolve.TypeHierarchyResolver;
import org.jetbrains.kotlin.resolve.*;
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil;
import org.jetbrains.kotlin.resolve.lazy.LazyEntity;
import org.jetbrains.kotlin.resolve.lazy.data.JetClassInfoUtil;
@@ -57,8 +56,10 @@ import org.jetbrains.kotlin.types.TypeUtils;
import java.util.*;
import static org.jetbrains.kotlin.diagnostics.Errors.CLASS_OBJECT_NOT_ALLOWED;
import static org.jetbrains.kotlin.diagnostics.Errors.CYCLIC_INHERITANCE_HIERARCHY;
import static org.jetbrains.kotlin.diagnostics.Errors.TYPE_PARAMETERS_IN_ENUM;
import static org.jetbrains.kotlin.name.SpecialNames.getClassObjectName;
import static org.jetbrains.kotlin.resolve.BindingContext.TYPE;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isSyntheticClassObject;
import static org.jetbrains.kotlin.resolve.ModifiersChecker.*;
import static org.jetbrains.kotlin.resolve.source.SourcePackage.toSourceElement;
@@ -620,13 +621,43 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
ClassifierDescriptor supertypeDescriptor = supertype.getConstructor().getDeclarationDescriptor();
if (supertypeDescriptor instanceof ClassDescriptor) {
ClassDescriptor superclass = (ClassDescriptor) supertypeDescriptor;
TypeHierarchyResolver.reportCyclicInheritanceHierarchyError(c.getTrace(), LazyClassDescriptor.this,
superclass);
reportCyclicInheritanceHierarchyError(c.getTrace(), LazyClassDescriptor.this, superclass);
}
}
}
}
private void reportCyclicInheritanceHierarchyError(
@NotNull BindingTrace trace,
@NotNull ClassDescriptor classDescriptor,
@NotNull ClassDescriptor superclass
) {
PsiElement psiElement = DescriptorToSourceUtils.classDescriptorToDeclaration(classDescriptor);
PsiElement elementToMark = null;
if (psiElement instanceof JetClassOrObject) {
JetClassOrObject classOrObject = (JetClassOrObject) psiElement;
for (JetDelegationSpecifier delegationSpecifier : classOrObject.getDelegationSpecifiers()) {
JetTypeReference typeReference = delegationSpecifier.getTypeReference();
if (typeReference == null) continue;
JetType supertype = trace.get(TYPE, typeReference);
if (supertype != null && supertype.getConstructor() == superclass.getTypeConstructor()) {
elementToMark = typeReference;
}
}
}
if (elementToMark == null && psiElement instanceof PsiNameIdentifierOwner) {
PsiNameIdentifierOwner namedElement = (PsiNameIdentifierOwner) psiElement;
PsiElement nameIdentifier = namedElement.getNameIdentifier();
if (nameIdentifier != null) {
elementToMark = nameIdentifier;
}
}
if (elementToMark != null) {
trace.report(CYCLIC_INHERITANCE_HIERARCHY.on(elementToMark));
}
}
private boolean isReachable(TypeConstructor from, TypeConstructor to, Set<TypeConstructor> visited) {
if (!visited.add(from)) return false;
for (JetType supertype : getNeighbors(from)) {
@@ -76,7 +76,6 @@ private val DI_DEFAULT_PACKAGE = "org.jetbrains.kotlin.di"
public fun createInjectorGenerators(): List<DependencyInjectorGenerator> =
listOf(
generatorForTopDownAnalyzerBasic(),
generatorForLazyTopDownAnalyzerBasic(),
generatorForLazyLocalClassifierAnalyzer(),
generatorForTopDownAnalyzerForJvm(),
@@ -91,21 +90,6 @@ public fun createInjectorGenerators(): List<DependencyInjectorGenerator> =
generatorForReplWithJava()
)
private fun generatorForTopDownAnalyzerBasic() =
generator("compiler/frontend/src", DI_DEFAULT_PACKAGE, "InjectorForTopDownAnalyzerBasic") {
parameter<Project>()
parameter<GlobalContext>(useAsContext = true)
parameter<BindingTrace>()
publicParameter<ModuleDescriptor>(useAsContext = true)
publicField<TopDownAnalyzer>()
field<MutablePackageFragmentProvider>()
parameter<AdditionalCheckerProvider>()
parameter<DynamicTypesSettings>()
}
private fun generatorForLazyTopDownAnalyzerBasic() =
generator("compiler/frontend/src", DI_DEFAULT_PACKAGE, "InjectorForLazyTopDownAnalyzerBasic") {
commonForResolveSessionBased()