TopDownAnalysisContext introduced

This commit is contained in:
Andrey Breslav
2011-09-09 18:22:45 +04:00
parent dcc84a0e48
commit 5587b027e6
5 changed files with 100 additions and 71 deletions
@@ -32,14 +32,14 @@ public class BodyResolver {
private final BindingTraceAdapter traceForConstructors;
private final BindingTraceAdapter traceForMembers;
private final DeclarationResolver declarationResolver;
private final TypeHierarchyResolver typeHierarchyResolver;
private final TopDownAnalysisContext context;
public BodyResolver(JetSemanticServices semanticServices, @NotNull BindingTrace trace, TypeHierarchyResolver typeHierarchyResolver, DeclarationResolver declarationResolver) {
public BodyResolver(JetSemanticServices semanticServices, @NotNull BindingTrace trace, TopDownAnalysisContext context, DeclarationResolver declarationResolver) {
this.semanticServices = semanticServices;
this.classDescriptorResolver = semanticServices.getClassDescriptorResolver(trace);
this.trace = trace;
this.declarationResolver = declarationResolver;
this.typeHierarchyResolver = typeHierarchyResolver;
this.context = context;
// This allows access to backing fields
this.traceForConstructors = new BindingTraceAdapter(trace).addHandler(BindingContext.REFERENCE_TARGET, new BindingTraceAdapter.RecordHandler<JetReferenceExpression, DeclarationDescriptor>() {
@@ -88,10 +88,10 @@ public class BodyResolver {
}
private void bindOverrides() {
for (Map.Entry<JetClass, MutableClassDescriptor> entry : typeHierarchyResolver.getClasses().entrySet()) {
for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) {
bindOverridesInAClass(entry.getValue());
}
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : typeHierarchyResolver.getObjects().entrySet()) {
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : context.getObjects().entrySet()) {
bindOverridesInAClass(entry.getValue());
}
}
@@ -140,7 +140,7 @@ public class BodyResolver {
}
private void checkIfPrimaryConstructorIsNecessary() {
for (Map.Entry<JetClass, MutableClassDescriptor> entry : typeHierarchyResolver.getClasses().entrySet()) {
for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) {
MutableClassDescriptor classDescriptor = entry.getValue();
JetClass jetClass = entry.getKey();
if (classDescriptor.getUnsubstitutedPrimaryConstructor() == null) {
@@ -160,10 +160,10 @@ public class BodyResolver {
private void resolveDelegationSpecifierLists() {
// TODO : Make sure the same thing is not initialized twice
for (Map.Entry<JetClass, MutableClassDescriptor> entry : typeHierarchyResolver.getClasses().entrySet()) {
for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) {
resolveDelegationSpecifierList(entry.getKey(), entry.getValue());
}
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : typeHierarchyResolver.getObjects().entrySet()) {
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : context.getObjects().entrySet()) {
resolveDelegationSpecifierList(entry.getKey(), entry.getValue());
}
}
@@ -316,10 +316,10 @@ public class BodyResolver {
}
private void resolveAnonymousInitializers() {
for (Map.Entry<JetClass, MutableClassDescriptor> entry : typeHierarchyResolver.getClasses().entrySet()) {
for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) {
resolveAnonymousInitializers(entry.getKey(), entry.getValue());
}
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : typeHierarchyResolver.getObjects().entrySet()) {
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : context.getObjects().entrySet()) {
resolveAnonymousInitializers(entry.getKey(), entry.getValue());
}
}
@@ -450,7 +450,7 @@ public class BodyResolver {
// Member properties
Set<JetProperty> processed = Sets.newHashSet();
for (Map.Entry<JetClass, MutableClassDescriptor> entry : typeHierarchyResolver.getClasses().entrySet()) {
for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) {
JetClass jetClass = entry.getKey();
MutableClassDescriptor classDescriptor = entry.getValue();
@@ -20,8 +20,8 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.ANNOTATION;
public class DeclarationResolver {
private final BindingTrace trace;
private final AnnotationResolver annotationResolver;
private final TypeHierarchyResolver typeHierarchyResolver;
private final ClassDescriptorResolver classDescriptorResolver;
private final TopDownAnalysisContext context;
private final Map<JetNamedFunction, FunctionDescriptorImpl> functions = Maps.newLinkedHashMap();
private final Map<JetDeclaration, ConstructorDescriptor> constructors = Maps.newLinkedHashMap();
@@ -29,9 +29,9 @@ public class DeclarationResolver {
private final Set<PropertyDescriptor> primaryConstructorParameterProperties = Sets.newHashSet();
private final Map<JetDeclaration, JetScope> declaringScopes = Maps.newHashMap();
public DeclarationResolver(JetSemanticServices semanticServices, BindingTrace trace, TypeHierarchyResolver typeHierarchyResolver) {
public DeclarationResolver(JetSemanticServices semanticServices, BindingTrace trace, TopDownAnalysisContext context) {
this.trace = trace;
this.typeHierarchyResolver = typeHierarchyResolver;
this.context = context;
this.annotationResolver = new AnnotationResolver(semanticServices, trace);
this.classDescriptorResolver = semanticServices.getClassDescriptorResolver(trace);
}
@@ -43,7 +43,7 @@ public class DeclarationResolver {
}
private void resolveConstructorHeaders() {
for (Map.Entry<JetClass, MutableClassDescriptor> entry : typeHierarchyResolver.getClasses().entrySet()) {
for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) {
JetClass jetClass = entry.getKey();
MutableClassDescriptor classDescriptor = entry.getValue();
@@ -55,7 +55,7 @@ public class DeclarationResolver {
}
private void resolveAnnotationStubsOnClassesAndConstructors() {
for (Map.Entry<JetClass, MutableClassDescriptor> entry : typeHierarchyResolver.getClasses().entrySet()) {
for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) {
JetClass jetClass = entry.getKey();
MutableClassDescriptor mutableClassDescriptor = entry.getValue();
@@ -73,14 +73,14 @@ public class DeclarationResolver {
}
private void resolveFunctionAndPropertyHeaders() {
for (Map.Entry<JetNamespace, WritableScope> entry : typeHierarchyResolver.getNamespaceScopes().entrySet()) {
for (Map.Entry<JetNamespace, WritableScope> entry : context.getNamespaceScopes().entrySet()) {
JetNamespace namespace = entry.getKey();
WritableScope namespaceScope = entry.getValue();
NamespaceLike namespaceDescriptor = typeHierarchyResolver.getNamespaceDescriptors().get(namespace);
NamespaceLike namespaceDescriptor = context.getNamespaceDescriptors().get(namespace);
resolveFunctionAndPropertyHeaders(namespace.getDeclarations(), namespaceScope, namespaceDescriptor);
}
for (Map.Entry<JetClass, MutableClassDescriptor> entry : typeHierarchyResolver.getClasses().entrySet()) {
for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) {
JetClass jetClass = entry.getKey();
MutableClassDescriptor classDescriptor = entry.getValue();
@@ -90,7 +90,7 @@ public class DeclarationResolver {
// processSecondaryConstructor(classDescriptor, jetConstructor);
// }
}
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : typeHierarchyResolver.getObjects().entrySet()) {
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : context.getObjects().entrySet()) {
JetObjectDeclaration object = entry.getKey();
MutableClassDescriptor classDescriptor = entry.getValue();
@@ -121,14 +121,14 @@ public class DeclarationResolver {
@Override
public void visitObjectDeclaration(JetObjectDeclaration declaration) {
PropertyDescriptor propertyDescriptor = classDescriptorResolver.resolveObjectDeclarationAsPropertyDescriptor(namespaceLike, declaration, typeHierarchyResolver.getObjects().get(declaration));
PropertyDescriptor propertyDescriptor = classDescriptorResolver.resolveObjectDeclarationAsPropertyDescriptor(namespaceLike, declaration, context.getObjects().get(declaration));
namespaceLike.addPropertyDescriptor(propertyDescriptor);
}
@Override
public void visitEnumEntry(JetEnumEntry enumEntry) {
if (enumEntry.getPrimaryConstructorParameterList() == null) {
PropertyDescriptor propertyDescriptor = classDescriptorResolver.resolveObjectDeclarationAsPropertyDescriptor(namespaceLike, enumEntry, typeHierarchyResolver.getClasses().get(enumEntry));
PropertyDescriptor propertyDescriptor = classDescriptorResolver.resolveObjectDeclarationAsPropertyDescriptor(namespaceLike, enumEntry, context.getClasses().get(enumEntry));
MutableClassDescriptor classObjectDescriptor = ((MutableClassDescriptor) namespaceLike).getClassObjectDescriptor();
assert classObjectDescriptor != null;
classObjectDescriptor.addPropertyDescriptor(propertyDescriptor);
@@ -0,0 +1,39 @@
package org.jetbrains.jet.lang.resolve;
import com.google.common.collect.Maps;
import org.jetbrains.jet.lang.descriptors.MutableClassDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptorImpl;
import org.jetbrains.jet.lang.psi.JetClass;
import org.jetbrains.jet.lang.psi.JetNamespace;
import org.jetbrains.jet.lang.psi.JetObjectDeclaration;
import java.util.Map;
/**
* @author abreslav
*/
public class TopDownAnalysisContext {
private final Map<JetClass, MutableClassDescriptor> classes = Maps.newLinkedHashMap();
private final Map<JetObjectDeclaration, MutableClassDescriptor> objects = Maps.newLinkedHashMap();
protected final Map<JetNamespace, WritableScope> namespaceScopes = Maps.newHashMap();
protected final Map<JetNamespace, NamespaceDescriptorImpl> namespaceDescriptors = Maps.newHashMap();
public Map<JetClass, MutableClassDescriptor> getClasses() {
return classes;
}
public Map<JetObjectDeclaration, MutableClassDescriptor> getObjects() {
return objects;
}
public Map<JetNamespace, WritableScope> getNamespaceScopes() {
return namespaceScopes;
}
public Map<JetNamespace, NamespaceDescriptorImpl> getNamespaceDescriptors() {
return namespaceDescriptors;
}
}
@@ -61,12 +61,12 @@ public class TopDownAnalyzer {
@NotNull BindingTrace trace,
@NotNull JetScope outerScope, NamespaceLike owner, @NotNull List<JetDeclaration> declarations) {
TypeHierarchyResolver typeHierarchyResolver = new TypeHierarchyResolver(semanticServices, trace);
typeHierarchyResolver.process(outerScope, owner, declarations);
TopDownAnalysisContext context = typeHierarchyResolver.process(outerScope, owner, declarations);
DeclarationResolver declarationResolver = new DeclarationResolver(semanticServices, trace, typeHierarchyResolver);
DeclarationResolver declarationResolver = new DeclarationResolver(semanticServices, trace, context);
declarationResolver.process();
new BodyResolver(semanticServices, trace, typeHierarchyResolver, declarationResolver).resolveBehaviorDeclarationBodies();
new BodyResolver(semanticServices, trace, context, declarationResolver).resolveBehaviorDeclarationBodies();
}
public static void processStandardLibraryNamespace(
@@ -74,14 +74,12 @@ public class TopDownAnalyzer {
@NotNull BindingTrace trace,
@NotNull WritableScope outerScope, @NotNull NamespaceDescriptorImpl standardLibraryNamespace, @NotNull JetNamespace namespace) {
TypeHierarchyResolver typeHierarchyResolver = new TypeHierarchyResolver(semanticServices, trace);
typeHierarchyResolver.getNamespaceScopes().put(namespace, standardLibraryNamespace.getMemberScope());
typeHierarchyResolver.getNamespaceDescriptors().put(namespace, standardLibraryNamespace);
typeHierarchyResolver.process(outerScope, standardLibraryNamespace, namespace.getDeclarations());
TopDownAnalysisContext context = typeHierarchyResolver.processStandardLibraryNamespace(outerScope, standardLibraryNamespace, namespace);
DeclarationResolver declarationResolver = new DeclarationResolver(semanticServices, trace, typeHierarchyResolver);
DeclarationResolver declarationResolver = new DeclarationResolver(semanticServices, trace, context);
declarationResolver.process();
BodyResolver bodyResolver = new BodyResolver(semanticServices, trace, typeHierarchyResolver, declarationResolver) {
BodyResolver bodyResolver = new BodyResolver(semanticServices, trace, context, declarationResolver) {
@Override
protected void checkProperty(JetProperty property, PropertyDescriptor propertyDescriptor, @Nullable ClassDescriptor classDescriptor) {
}
@@ -1,6 +1,5 @@
package org.jetbrains.jet.lang.resolve;
import com.google.common.collect.Maps;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.JetSemanticServices;
import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider;
@@ -25,45 +24,38 @@ public class TypeHierarchyResolver {
private final JetSemanticServices semanticServices;
private final ClassDescriptorResolver classDescriptorResolver;
private final Map<JetClass, MutableClassDescriptor> classes = Maps.newLinkedHashMap();
private final Map<JetObjectDeclaration, MutableClassDescriptor> objects = Maps.newLinkedHashMap();
protected final Map<JetNamespace, WritableScope> namespaceScopes = Maps.newHashMap();
protected final Map<JetNamespace, NamespaceDescriptorImpl> namespaceDescriptors = Maps.newHashMap();
public TypeHierarchyResolver(JetSemanticServices semanticServices, BindingTrace trace) {
this.trace = trace;
this.semanticServices = semanticServices;
this.classDescriptorResolver = semanticServices.getClassDescriptorResolver(trace);
}
public Map<JetClass, MutableClassDescriptor> getClasses() {
return classes;
public TopDownAnalysisContext process(@NotNull JetScope outerScope, NamespaceLike owner, @NotNull List<JetDeclaration> declarations) {
TopDownAnalysisContext context = new TopDownAnalysisContext();
return doProcess(outerScope, owner, declarations, context);
}
public Map<JetObjectDeclaration, MutableClassDescriptor> getObjects() {
return objects;
public TopDownAnalysisContext processStandardLibraryNamespace(@NotNull JetScope outerScope, @NotNull NamespaceDescriptorImpl standardLibraryNamespace, @NotNull JetNamespace namespace) {
TopDownAnalysisContext context = new TopDownAnalysisContext();
context.getNamespaceScopes().put(namespace, standardLibraryNamespace.getMemberScope());
context.getNamespaceDescriptors().put(namespace, standardLibraryNamespace);
return doProcess(outerScope, standardLibraryNamespace, namespace.getDeclarations(), context);
}
public Map<JetNamespace, WritableScope> getNamespaceScopes() {
return namespaceScopes;
}
private TopDownAnalysisContext doProcess(JetScope outerScope, NamespaceLike owner, List<JetDeclaration> declarations, TopDownAnalysisContext context) {
collectNamespacesAndClassifiers(outerScope, owner, declarations, context); // namespaceScopes, classes
public Map<JetNamespace, NamespaceDescriptorImpl> getNamespaceDescriptors() {
return namespaceDescriptors;
}
public void process(@NotNull JetScope outerScope, NamespaceLike owner, @NotNull List<JetDeclaration> declarations) {
collectNamespacesAndClassifiers(outerScope, owner, declarations); // namespaceScopes, classes
createTypeConstructors(); // create type constructors for classes and generic parameters
resolveTypesInClassHeaders(); // Generic bounds and types in supertype lists (no expressions or constructor resolution)
checkTypesInClassHeaders(); // Generic bounds and supertype lists
createTypeConstructors(context); // create type constructors for classes and generic parameters
resolveTypesInClassHeaders(context); // Generic bounds and types in supertype lists (no expressions or constructor resolution)
checkTypesInClassHeaders(context); // Generic bounds and supertype lists
return context;
}
private void collectNamespacesAndClassifiers(
@NotNull final JetScope outerScope,
@NotNull final NamespaceLike owner,
@NotNull Collection<JetDeclaration> declarations) {
@NotNull Collection<JetDeclaration> declarations,
@NotNull final TopDownAnalysisContext context) {
for (JetDeclaration declaration : declarations) {
declaration.accept(new JetVisitorVoid() {
@Override
@@ -84,14 +76,14 @@ public class TypeHierarchyResolver {
owner.addNamespace(namespaceDescriptor);
trace.record(BindingContext.NAMESPACE, namespace, namespaceDescriptor);
}
namespaceDescriptors.put(namespace, namespaceDescriptor);
context.getNamespaceDescriptors().put(namespace, namespaceDescriptor);
WriteThroughScope namespaceScope = new WriteThroughScope(outerScope, namespaceDescriptor.getMemberScope(), trace.getErrorHandler());
namespaceScopes.put(namespace, namespaceScope);
context.getNamespaceScopes().put(namespace, namespaceScope);
processImports(namespace, namespaceScope, outerScope);
collectNamespacesAndClassifiers(namespaceScope, namespaceDescriptor, namespace.getDeclarations());
collectNamespacesAndClassifiers(namespaceScope, namespaceDescriptor, namespace.getDeclarations(), context);
}
@Override
@@ -108,7 +100,7 @@ public class TypeHierarchyResolver {
}
visitClassOrObject(
klass,
(Map) classes,
(Map) context.getClasses(),
owner,
outerScope,
mutableClassDescriptor);
@@ -126,14 +118,14 @@ public class TypeHierarchyResolver {
assert classObjectDescriptor != null : enumEntry.getParent().getText();
if (enumEntry.getPrimaryConstructorParameterList() == null) {
MutableClassDescriptor classDescriptor = createClassDescriptorForObject(enumEntry, classObjectDescriptor);
objects.remove(enumEntry);
classes.put(enumEntry, classDescriptor);
context.getObjects().remove(enumEntry);
context.getClasses().put(enumEntry, classDescriptor);
}
else {
MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor(trace, classObjectDescriptor, outerScope, ClassKind.CLASS); // TODO : Special kind for enum entry classes?
visitClassOrObject(
enumEntry,
(Map) classes,
(Map) context.getClasses(),
classObjectDescriptor,
outerScope,
mutableClassDescriptor);
@@ -148,7 +140,7 @@ public class TypeHierarchyResolver {
return ClassObjectStatus.NOT_ALLOWED;
}
};
visitClassOrObject(declaration, (Map) objects, owner, outerScope, mutableClassDescriptor);
visitClassOrObject(declaration, (Map) context.getObjects(), owner, outerScope, mutableClassDescriptor);
createPrimaryConstructor(mutableClassDescriptor);
trace.record(BindingContext.CLASS, declaration, mutableClassDescriptor);
return mutableClassDescriptor;
@@ -169,7 +161,7 @@ public class TypeHierarchyResolver {
// declaringScopes.put((JetDeclaration) declaration, outerScope);
JetScope classScope = mutableClassDescriptor.getScopeForMemberResolution();
collectNamespacesAndClassifiers(classScope, mutableClassDescriptor, declaration.getDeclarations());
collectNamespacesAndClassifiers(classScope, mutableClassDescriptor, declaration.getDeclarations(), context);
}
@Override
@@ -259,36 +251,36 @@ public class TypeHierarchyResolver {
}
}
private void createTypeConstructors() {
for (Map.Entry<JetClass, MutableClassDescriptor> entry : classes.entrySet()) {
private void createTypeConstructors(TopDownAnalysisContext context) {
for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) {
JetClass jetClass = entry.getKey();
MutableClassDescriptor descriptor = entry.getValue();
classDescriptorResolver.resolveMutableClassDescriptor(jetClass, descriptor);
descriptor.createTypeConstructor();
}
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : objects.entrySet()) {
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : context.getObjects().entrySet()) {
MutableClassDescriptor descriptor = entry.getValue();
descriptor.setModality(Modality.FINAL);
descriptor.createTypeConstructor();
}
}
private void resolveTypesInClassHeaders() {
for (Map.Entry<JetClass, MutableClassDescriptor> entry : classes.entrySet()) {
private void resolveTypesInClassHeaders(TopDownAnalysisContext context) {
for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) {
JetClass jetClass = entry.getKey();
MutableClassDescriptor descriptor = entry.getValue();
classDescriptorResolver.resolveGenericBounds(jetClass, descriptor.getScopeForSupertypeResolution(), descriptor.getTypeConstructor().getParameters());
classDescriptorResolver.resolveSupertypes(jetClass, descriptor);
}
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : objects.entrySet()) {
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : context.getObjects().entrySet()) {
JetClassOrObject jetClass = entry.getKey();
MutableClassDescriptor descriptor = entry.getValue();
classDescriptorResolver.resolveSupertypes(jetClass, descriptor);
}
}
private void checkTypesInClassHeaders() {
for (Map.Entry<JetClass, MutableClassDescriptor> entry : classes.entrySet()) {
private void checkTypesInClassHeaders(TopDownAnalysisContext context) {
for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) {
JetClass jetClass = entry.getKey();
for (JetDelegationSpecifier delegationSpecifier : jetClass.getDelegationSpecifiers()) {