From 78e26c0cf9fadf28ce473aa4bdb5ee4e1cc64313 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Tue, 18 Nov 2014 16:26:14 +0300 Subject: [PATCH] Fixed partial body resolve when element to resolve is not inside body --- .../lang/resolve/lazy/ElementResolver.java | 35 +++++++++++++------ .../resolve/lazy/PartialBodyResolveFilter.kt | 6 +++- .../plugin/project/ResolveElementCache.java | 1 - 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/idea/ide-common/src/org/jetbrains/jet/lang/resolve/lazy/ElementResolver.java b/idea/ide-common/src/org/jetbrains/jet/lang/resolve/lazy/ElementResolver.java index a934214e6b4..c373b003c3a 100644 --- a/idea/ide-common/src/org/jetbrains/jet/lang/resolve/lazy/ElementResolver.java +++ b/idea/ide-common/src/org/jetbrains/jet/lang/resolve/lazy/ElementResolver.java @@ -91,9 +91,21 @@ public abstract class ElementResolver { } if (partialBodyResolve && elementOfAdditionalResolve instanceof JetDeclarationWithBody) { - //TODO: do not resolve again if whole body resolve cached already JetExpression body = ((JetDeclarationWithBody) elementOfAdditionalResolve).getBodyExpression(); - Function1 filter = body != null ? new PartialBodyResolveFilter(jetElement, body) : null; + //TODO: do not resolve with filter if whole body resolve cached already + boolean inBody = body != null && PsiTreeUtil.isAncestor(body, jetElement, false); + Function1 filter; + if (inBody) { + filter = new PartialBodyResolveFilter(jetElement, body); + } + else { // do as less as possible body-resolve + filter = new Function1() { + @Override + public Boolean invoke(JetElement element) { + return false; + } + }; + } return elementAdditionalResolve(elementOfAdditionalResolve, filter); } @@ -121,7 +133,10 @@ public abstract class ElementResolver { } @NotNull - protected BindingContext elementAdditionalResolve(@NotNull JetElement resolveElement, @Nullable Function1 filter) { + protected BindingContext elementAdditionalResolve( + @NotNull JetElement resolveElement, + @Nullable Function1 bodyResolveFilter + ) { // All additional resolve should be done to separate trace BindingTrace trace = resolveSession.getStorageManager().createSafeTrace( new DelegatingBindingTrace(resolveSession.getBindingContext(), "trace to resolve element", resolveElement)); @@ -129,10 +144,10 @@ public abstract class ElementResolver { JetFile file = resolveElement.getContainingJetFile(); if (resolveElement instanceof JetNamedFunction) { - functionAdditionalResolve(resolveSession, (JetNamedFunction) resolveElement, trace, file, filter); + functionAdditionalResolve(resolveSession, (JetNamedFunction) resolveElement, trace, file, bodyResolveFilter); } else if (resolveElement instanceof JetClassInitializer) { - initializerAdditionalResolve(resolveSession, (JetClassInitializer) resolveElement, trace, file, filter); + initializerAdditionalResolve(resolveSession, (JetClassInitializer) resolveElement, trace, file, bodyResolveFilter); } else if (resolveElement instanceof JetProperty) { propertyAdditionalResolve(resolveSession, (JetProperty) resolveElement, trace, file); @@ -149,7 +164,7 @@ public abstract class ElementResolver { annotationAdditionalResolve(resolveSession, (JetAnnotationEntry) resolveElement); } else if (resolveElement instanceof JetClass) { - constructorAdditionalResolve(resolveSession, (JetClass) resolveElement, trace, file, filter); + constructorAdditionalResolve(resolveSession, (JetClass) resolveElement, trace, file, bodyResolveFilter); } else if (resolveElement instanceof JetTypeParameter) { typeParameterAdditionalResolve(resolveSession, (JetTypeParameter) resolveElement); @@ -353,13 +368,13 @@ public abstract class ElementResolver { JetNamedFunction namedFunction, BindingTrace trace, JetFile file, - @Nullable Function1 filter + @Nullable Function1 bodyResolveFilter ) { JetScope scope = resolveSession.getScopeProvider().getResolutionScopeForDeclaration(namedFunction); FunctionDescriptor functionDescriptor = (FunctionDescriptor) resolveSession.resolveToDescriptor(namedFunction); ForceResolveUtil.forceResolveAllContents(functionDescriptor); - BodyResolver bodyResolver = createBodyResolver(resolveSession, trace, file, filter); + BodyResolver bodyResolver = createBodyResolver(resolveSession, trace, file, bodyResolveFilter); bodyResolver.resolveFunctionBody(createEmptyContext(resolveSession), trace, namedFunction, functionDescriptor, scope); } @@ -384,7 +399,7 @@ public abstract class ElementResolver { constructorDescriptor, scope); } - private boolean initializerAdditionalResolve( + private void initializerAdditionalResolve( ResolveSession resolveSession, JetClassInitializer classInitializer, BindingTrace trace, @@ -396,8 +411,6 @@ public abstract class ElementResolver { BodyResolver bodyResolver = createBodyResolver(resolveSession, trace, file, filter); bodyResolver.resolveAnonymousInitializer(createEmptyContext(resolveSession), classInitializer, classOrObjectDescriptor); - - return true; } private BodyResolver createBodyResolver(ResolveSession resolveSession, BindingTrace trace, JetFile file, @Nullable Function1 filter) { diff --git a/idea/ide-common/src/org/jetbrains/jet/lang/resolve/lazy/PartialBodyResolveFilter.kt b/idea/ide-common/src/org/jetbrains/jet/lang/resolve/lazy/PartialBodyResolveFilter.kt index ca65eabc16f..c0e0ed5f113 100644 --- a/idea/ide-common/src/org/jetbrains/jet/lang/resolve/lazy/PartialBodyResolveFilter.kt +++ b/idea/ide-common/src/org/jetbrains/jet/lang/resolve/lazy/PartialBodyResolveFilter.kt @@ -25,6 +25,7 @@ import java.util.ArrayList import java.util.HashMap import com.intellij.psi.PsiElement import org.jetbrains.jet.JetNodeTypes +import org.jetbrains.jet.lang.psi.psiUtil.isAncestor class PartialBodyResolveFilter(elementToResolve: JetElement, private val body: JetExpression) : (JetElement) -> Boolean { @@ -32,6 +33,8 @@ class PartialBodyResolveFilter(elementToResolve: JetElement, private val body: J private val processedBlocks = HashSet() ;{ + assert(body.isAncestor(elementToResolve, strict = false)) + addStatementsToResolve(elementToResolve) } @@ -45,7 +48,8 @@ class PartialBodyResolveFilter(elementToResolve: JetElement, private val body: J private fun addStatementsToResolve(element: JetElement) { if (element == body) return - val parent = element.getParent() as JetElement + val parent = element.getParent() as? JetElement + ?: return if (parent is JetBlockExpression) { processBlock(parent) diff --git a/idea/idea-analysis/src/org/jetbrains/jet/plugin/project/ResolveElementCache.java b/idea/idea-analysis/src/org/jetbrains/jet/plugin/project/ResolveElementCache.java index cc7e2d55b75..5275f51ca0e 100644 --- a/idea/idea-analysis/src/org/jetbrains/jet/plugin/project/ResolveElementCache.java +++ b/idea/idea-analysis/src/org/jetbrains/jet/plugin/project/ResolveElementCache.java @@ -28,7 +28,6 @@ import org.jetbrains.jet.lang.psi.JetElement; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.AdditionalCheckerProvider; import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lang.resolve.kotlin.JavaDeclarationCheckerProvider; import org.jetbrains.jet.lang.resolve.lazy.ElementResolver; import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; import org.jetbrains.jet.storage.LazyResolveStorageManager;