diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodiesResolveContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodiesResolveContext.java index 546ebf93e3d..24542e9dbe0 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodiesResolveContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodiesResolveContext.java @@ -49,6 +49,8 @@ public interface BodiesResolveContext extends GlobalContext { @Mutable Map getDeclaredClasses(); @Mutable + Map getAnonymousInitializers(); + @Mutable Map getScripts(); @Mutable diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java index 05b6a5e0ac1..07af8272d77 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java @@ -334,35 +334,43 @@ public class BodyResolver { } private void resolveAnonymousInitializers(@NotNull BodiesResolveContext c) { - for (Map.Entry 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 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 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 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) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/CachedBodiesResolveContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/CachedBodiesResolveContext.java index ba34ba72a9e..3588d9d05ab 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/CachedBodiesResolveContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/CachedBodiesResolveContext.java @@ -41,6 +41,7 @@ import java.util.Map; public class CachedBodiesResolveContext implements BodiesResolveContext { private final Collection files; private final Map classes; + private final Map anonymousInitializers; private final Map properties; private final Map functions; private final Function 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 getAnonymousInitializers() { + return anonymousInitializers; + } + @Override public Map getProperties() { return properties; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/LazyTopDownAnalyzer.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/LazyTopDownAnalyzer.java index c7fa22f642a..48287cd6d4f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/LazyTopDownAnalyzer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/LazyTopDownAnalyzer.java @@ -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 diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalysisContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalysisContext.java index a3fce7cd8cb..44fb218ced1 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalysisContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TopDownAnalysisContext.java @@ -42,6 +42,7 @@ public class TopDownAnalysisContext implements BodiesResolveContext { private DataFlowInfo outerDataFlowInfo = DataFlowInfo.EMPTY; private final Map classes = Maps.newLinkedHashMap(); + private final Map anonymousInitializers = Maps.newLinkedHashMap(); protected final Map packageFragments = Maps.newHashMap(); protected final Set files = new LinkedHashSet(); private List classesTopologicalOrder = null; @@ -114,6 +115,11 @@ public class TopDownAnalysisContext implements BodiesResolveContext { return classes; } + @Override + public Map getAnonymousInitializers() { + return anonymousInitializers; + } + public Map getFileScopes() { return fileScopes; } diff --git a/idea/src/org/jetbrains/jet/plugin/project/ResolveElementCache.java b/idea/src/org/jetbrains/jet/plugin/project/ResolveElementCache.java index d12766b4d64..b91b85d2680 100644 --- a/idea/src/org/jetbrains/jet/plugin/project/ResolveElementCache.java +++ b/idea/src/org/jetbrains/jet/plugin/project/ResolveElementCache.java @@ -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 getAnonymousInitializers() { + return Collections.emptyMap(); + } + @Override public Map getProperties() { return Collections.emptyMap();