Support top-down analysis starting from anonymous initializers
This commit is contained in:
@@ -49,6 +49,8 @@ public interface BodiesResolveContext extends GlobalContext {
|
||||
@Mutable
|
||||
Map<JetClassOrObject, ClassDescriptorWithResolutionScopes> getDeclaredClasses();
|
||||
@Mutable
|
||||
Map<JetClassInitializer, ClassDescriptorWithResolutionScopes> getAnonymousInitializers();
|
||||
@Mutable
|
||||
Map<JetScript, ScriptDescriptor> getScripts();
|
||||
|
||||
@Mutable
|
||||
|
||||
@@ -334,35 +334,43 @@ public class BodyResolver {
|
||||
}
|
||||
|
||||
private void resolveAnonymousInitializers(@NotNull BodiesResolveContext c) {
|
||||
for (Map.Entry<JetClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getDeclaredClasses().entrySet()) {
|
||||
JetClassOrObject classOrObject = entry.getKey();
|
||||
ClassDescriptorWithResolutionScopes descriptor = entry.getValue();
|
||||
resolveAnonymousInitializers(c, classOrObject, descriptor.getUnsubstitutedPrimaryConstructor(),
|
||||
descriptor.getScopeForInitializerResolution());
|
||||
}
|
||||
}
|
||||
|
||||
public void resolveAnonymousInitializers(
|
||||
@NotNull BodiesResolveContext c,
|
||||
@NotNull JetClassOrObject jetClassOrObject,
|
||||
@Nullable ConstructorDescriptor primaryConstructor,
|
||||
@NotNull JetScope scopeForInitializers) {
|
||||
if (!c.completeAnalysisNeeded(jetClassOrObject)) {
|
||||
return;
|
||||
}
|
||||
List<JetClassInitializer> anonymousInitializers = jetClassOrObject.getAnonymousInitializers();
|
||||
if (primaryConstructor != null) {
|
||||
for (JetClassInitializer anonymousInitializer : anonymousInitializers) {
|
||||
expressionTypingServices.getType(scopeForInitializers, anonymousInitializer.getBody(), NO_EXPECTED_TYPE, c.getOuterDataFlowInfo(), trace);
|
||||
processModifiersOnInitializer(anonymousInitializer, scopeForInitializers);
|
||||
if (c.getTopDownAnalysisParameters().isLazyTopDownAnalysis()) {
|
||||
for (Map.Entry<JetClassInitializer, ClassDescriptorWithResolutionScopes> entry : c.getAnonymousInitializers().entrySet()) {
|
||||
JetClassInitializer initializer = entry.getKey();
|
||||
ClassDescriptorWithResolutionScopes descriptor = entry.getValue();
|
||||
resolveAnonymousInitializer(c, initializer, descriptor);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (JetClassInitializer anonymousInitializer : anonymousInitializers) {
|
||||
trace.report(ANONYMOUS_INITIALIZER_IN_TRAIT.on(anonymousInitializer));
|
||||
processModifiersOnInitializer(anonymousInitializer, scopeForInitializers);
|
||||
for (Map.Entry<JetClassOrObject, ClassDescriptorWithResolutionScopes> entry : c.getDeclaredClasses().entrySet()) {
|
||||
JetClassOrObject classOrObject = entry.getKey();
|
||||
ClassDescriptorWithResolutionScopes descriptor = entry.getValue();
|
||||
|
||||
if (!c.completeAnalysisNeeded(classOrObject)) return;
|
||||
for (JetClassInitializer initializer : classOrObject.getAnonymousInitializers()) {
|
||||
resolveAnonymousInitializer(c, initializer, descriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void resolveAnonymousInitializer(
|
||||
@NotNull BodiesResolveContext c,
|
||||
@NotNull JetClassInitializer anonymousInitializer,
|
||||
@NotNull ClassDescriptorWithResolutionScopes classDescriptor
|
||||
) {
|
||||
if (!c.completeAnalysisNeeded(anonymousInitializer)) return;
|
||||
|
||||
JetScope scopeForInitializers = classDescriptor.getScopeForInitializerResolution();
|
||||
if (classDescriptor.getUnsubstitutedPrimaryConstructor() != null) {
|
||||
expressionTypingServices.getType(scopeForInitializers, anonymousInitializer.getBody(), NO_EXPECTED_TYPE, c.getOuterDataFlowInfo(), trace);
|
||||
processModifiersOnInitializer(anonymousInitializer, scopeForInitializers);
|
||||
}
|
||||
else {
|
||||
trace.report(ANONYMOUS_INITIALIZER_IN_TRAIT.on(anonymousInitializer));
|
||||
processModifiersOnInitializer(anonymousInitializer, scopeForInitializers);
|
||||
}
|
||||
}
|
||||
|
||||
private void processModifiersOnInitializer(@NotNull JetModifierListOwner owner, @NotNull JetScope scope) {
|
||||
|
||||
@@ -41,6 +41,7 @@ import java.util.Map;
|
||||
public class CachedBodiesResolveContext implements BodiesResolveContext {
|
||||
private final Collection<JetFile> files;
|
||||
private final Map<JetClassOrObject, ClassDescriptorWithResolutionScopes> classes;
|
||||
private final Map<JetClassInitializer, ClassDescriptorWithResolutionScopes> anonymousInitializers;
|
||||
private final Map<JetProperty, PropertyDescriptor> properties;
|
||||
private final Map<JetNamedFunction, SimpleFunctionDescriptor> functions;
|
||||
private final Function<JetDeclaration, JetScope> declaringScopes;
|
||||
@@ -52,6 +53,7 @@ public class CachedBodiesResolveContext implements BodiesResolveContext {
|
||||
public CachedBodiesResolveContext(TopDownAnalysisContext context) {
|
||||
files = Collections.unmodifiableCollection(context.getFiles());
|
||||
classes = Collections.unmodifiableMap(context.getDeclaredClasses());
|
||||
anonymousInitializers = Collections.unmodifiableMap(context.getAnonymousInitializers());
|
||||
properties = Collections.unmodifiableMap(context.getProperties());
|
||||
functions = Collections.unmodifiableMap(context.getFunctions());
|
||||
declaringScopes = context.getDeclaringScopes();
|
||||
@@ -83,6 +85,11 @@ public class CachedBodiesResolveContext implements BodiesResolveContext {
|
||||
return classes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<JetClassInitializer, ClassDescriptorWithResolutionScopes> getAnonymousInitializers() {
|
||||
return anonymousInitializers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<JetProperty, PropertyDescriptor> getProperties() {
|
||||
return properties;
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.resolve;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
@@ -206,6 +207,11 @@ public class LazyTopDownAnalyzer {
|
||||
@Override
|
||||
public void visitAnonymousInitializer(@NotNull JetClassInitializer initializer) {
|
||||
registerScope(c, resolveSession, initializer);
|
||||
JetClassOrObject classOrObject = PsiTreeUtil.getParentOfType(initializer, JetClassOrObject.class);
|
||||
c.getAnonymousInitializers().put(
|
||||
initializer,
|
||||
(ClassDescriptorWithResolutionScopes) resolveSession.resolveToDescriptor(classOrObject)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -42,6 +42,7 @@ public class TopDownAnalysisContext implements BodiesResolveContext {
|
||||
private DataFlowInfo outerDataFlowInfo = DataFlowInfo.EMPTY;
|
||||
|
||||
private final Map<JetClassOrObject, ClassDescriptorWithResolutionScopes> classes = Maps.newLinkedHashMap();
|
||||
private final Map<JetClassInitializer, ClassDescriptorWithResolutionScopes> anonymousInitializers = Maps.newLinkedHashMap();
|
||||
protected final Map<JetFile, MutablePackageFragmentDescriptor> packageFragments = Maps.newHashMap();
|
||||
protected final Set<JetFile> files = new LinkedHashSet<JetFile>();
|
||||
private List<MutableClassDescriptor> classesTopologicalOrder = null;
|
||||
@@ -114,6 +115,11 @@ public class TopDownAnalysisContext implements BodiesResolveContext {
|
||||
return classes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<JetClassInitializer, ClassDescriptorWithResolutionScopes> getAnonymousInitializers() {
|
||||
return anonymousInitializers;
|
||||
}
|
||||
|
||||
public Map<JetFile, WritableScope> getFileScopes() {
|
||||
return fileScopes;
|
||||
}
|
||||
|
||||
@@ -348,9 +348,7 @@ public class ResolveElementCache {
|
||||
LazyClassDescriptor classOrObjectDescriptor = (LazyClassDescriptor) resolveSession.resolveToDescriptor(classOrObject);
|
||||
|
||||
BodyResolver bodyResolver = createBodyResolver(resolveSession, trace, file);
|
||||
bodyResolver.resolveAnonymousInitializers(createEmptyContext(resolveSession), classOrObject,
|
||||
classOrObjectDescriptor.getUnsubstitutedPrimaryConstructor(),
|
||||
classOrObjectDescriptor.getScopeForInitializerResolution());
|
||||
bodyResolver.resolveAnonymousInitializer(createEmptyContext(resolveSession), classInitializer, classOrObjectDescriptor);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -493,6 +491,11 @@ public class ResolveElementCache {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<JetClassInitializer, ClassDescriptorWithResolutionScopes> getAnonymousInitializers() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<JetProperty, PropertyDescriptor> getProperties() {
|
||||
return Collections.emptyMap();
|
||||
|
||||
Reference in New Issue
Block a user