Fixed partial body resolve when element to resolve is not inside body
This commit is contained in:
@@ -91,9 +91,21 @@ public abstract class ElementResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (partialBodyResolve && elementOfAdditionalResolve instanceof JetDeclarationWithBody) {
|
if (partialBodyResolve && elementOfAdditionalResolve instanceof JetDeclarationWithBody) {
|
||||||
//TODO: do not resolve again if whole body resolve cached already
|
|
||||||
JetExpression body = ((JetDeclarationWithBody) elementOfAdditionalResolve).getBodyExpression();
|
JetExpression body = ((JetDeclarationWithBody) elementOfAdditionalResolve).getBodyExpression();
|
||||||
Function1<JetElement, Boolean> 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<JetElement, Boolean> filter;
|
||||||
|
if (inBody) {
|
||||||
|
filter = new PartialBodyResolveFilter(jetElement, body);
|
||||||
|
}
|
||||||
|
else { // do as less as possible body-resolve
|
||||||
|
filter = new Function1<JetElement, Boolean>() {
|
||||||
|
@Override
|
||||||
|
public Boolean invoke(JetElement element) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
return elementAdditionalResolve(elementOfAdditionalResolve, filter);
|
return elementAdditionalResolve(elementOfAdditionalResolve, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,7 +133,10 @@ public abstract class ElementResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
protected BindingContext elementAdditionalResolve(@NotNull JetElement resolveElement, @Nullable Function1<JetElement, Boolean> filter) {
|
protected BindingContext elementAdditionalResolve(
|
||||||
|
@NotNull JetElement resolveElement,
|
||||||
|
@Nullable Function1<JetElement, Boolean> bodyResolveFilter
|
||||||
|
) {
|
||||||
// All additional resolve should be done to separate trace
|
// All additional resolve should be done to separate trace
|
||||||
BindingTrace trace = resolveSession.getStorageManager().createSafeTrace(
|
BindingTrace trace = resolveSession.getStorageManager().createSafeTrace(
|
||||||
new DelegatingBindingTrace(resolveSession.getBindingContext(), "trace to resolve element", resolveElement));
|
new DelegatingBindingTrace(resolveSession.getBindingContext(), "trace to resolve element", resolveElement));
|
||||||
@@ -129,10 +144,10 @@ public abstract class ElementResolver {
|
|||||||
JetFile file = resolveElement.getContainingJetFile();
|
JetFile file = resolveElement.getContainingJetFile();
|
||||||
|
|
||||||
if (resolveElement instanceof JetNamedFunction) {
|
if (resolveElement instanceof JetNamedFunction) {
|
||||||
functionAdditionalResolve(resolveSession, (JetNamedFunction) resolveElement, trace, file, filter);
|
functionAdditionalResolve(resolveSession, (JetNamedFunction) resolveElement, trace, file, bodyResolveFilter);
|
||||||
}
|
}
|
||||||
else if (resolveElement instanceof JetClassInitializer) {
|
else if (resolveElement instanceof JetClassInitializer) {
|
||||||
initializerAdditionalResolve(resolveSession, (JetClassInitializer) resolveElement, trace, file, filter);
|
initializerAdditionalResolve(resolveSession, (JetClassInitializer) resolveElement, trace, file, bodyResolveFilter);
|
||||||
}
|
}
|
||||||
else if (resolveElement instanceof JetProperty) {
|
else if (resolveElement instanceof JetProperty) {
|
||||||
propertyAdditionalResolve(resolveSession, (JetProperty) resolveElement, trace, file);
|
propertyAdditionalResolve(resolveSession, (JetProperty) resolveElement, trace, file);
|
||||||
@@ -149,7 +164,7 @@ public abstract class ElementResolver {
|
|||||||
annotationAdditionalResolve(resolveSession, (JetAnnotationEntry) resolveElement);
|
annotationAdditionalResolve(resolveSession, (JetAnnotationEntry) resolveElement);
|
||||||
}
|
}
|
||||||
else if (resolveElement instanceof JetClass) {
|
else if (resolveElement instanceof JetClass) {
|
||||||
constructorAdditionalResolve(resolveSession, (JetClass) resolveElement, trace, file, filter);
|
constructorAdditionalResolve(resolveSession, (JetClass) resolveElement, trace, file, bodyResolveFilter);
|
||||||
}
|
}
|
||||||
else if (resolveElement instanceof JetTypeParameter) {
|
else if (resolveElement instanceof JetTypeParameter) {
|
||||||
typeParameterAdditionalResolve(resolveSession, (JetTypeParameter) resolveElement);
|
typeParameterAdditionalResolve(resolveSession, (JetTypeParameter) resolveElement);
|
||||||
@@ -353,13 +368,13 @@ public abstract class ElementResolver {
|
|||||||
JetNamedFunction namedFunction,
|
JetNamedFunction namedFunction,
|
||||||
BindingTrace trace,
|
BindingTrace trace,
|
||||||
JetFile file,
|
JetFile file,
|
||||||
@Nullable Function1<JetElement, Boolean> filter
|
@Nullable Function1<JetElement, Boolean> bodyResolveFilter
|
||||||
) {
|
) {
|
||||||
JetScope scope = resolveSession.getScopeProvider().getResolutionScopeForDeclaration(namedFunction);
|
JetScope scope = resolveSession.getScopeProvider().getResolutionScopeForDeclaration(namedFunction);
|
||||||
FunctionDescriptor functionDescriptor = (FunctionDescriptor) resolveSession.resolveToDescriptor(namedFunction);
|
FunctionDescriptor functionDescriptor = (FunctionDescriptor) resolveSession.resolveToDescriptor(namedFunction);
|
||||||
ForceResolveUtil.forceResolveAllContents(functionDescriptor);
|
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);
|
bodyResolver.resolveFunctionBody(createEmptyContext(resolveSession), trace, namedFunction, functionDescriptor, scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,7 +399,7 @@ public abstract class ElementResolver {
|
|||||||
constructorDescriptor, scope);
|
constructorDescriptor, scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean initializerAdditionalResolve(
|
private void initializerAdditionalResolve(
|
||||||
ResolveSession resolveSession,
|
ResolveSession resolveSession,
|
||||||
JetClassInitializer classInitializer,
|
JetClassInitializer classInitializer,
|
||||||
BindingTrace trace,
|
BindingTrace trace,
|
||||||
@@ -396,8 +411,6 @@ public abstract class ElementResolver {
|
|||||||
|
|
||||||
BodyResolver bodyResolver = createBodyResolver(resolveSession, trace, file, filter);
|
BodyResolver bodyResolver = createBodyResolver(resolveSession, trace, file, filter);
|
||||||
bodyResolver.resolveAnonymousInitializer(createEmptyContext(resolveSession), classInitializer, classOrObjectDescriptor);
|
bodyResolver.resolveAnonymousInitializer(createEmptyContext(resolveSession), classInitializer, classOrObjectDescriptor);
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private BodyResolver createBodyResolver(ResolveSession resolveSession, BindingTrace trace, JetFile file, @Nullable Function1<JetElement, Boolean> filter) {
|
private BodyResolver createBodyResolver(ResolveSession resolveSession, BindingTrace trace, JetFile file, @Nullable Function1<JetElement, Boolean> filter) {
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import java.util.ArrayList
|
|||||||
import java.util.HashMap
|
import java.util.HashMap
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.jet.JetNodeTypes
|
import org.jetbrains.jet.JetNodeTypes
|
||||||
|
import org.jetbrains.jet.lang.psi.psiUtil.isAncestor
|
||||||
|
|
||||||
class PartialBodyResolveFilter(elementToResolve: JetElement, private val body: JetExpression) : (JetElement) -> Boolean {
|
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<JetBlockExpression>()
|
private val processedBlocks = HashSet<JetBlockExpression>()
|
||||||
|
|
||||||
;{
|
;{
|
||||||
|
assert(body.isAncestor(elementToResolve, strict = false))
|
||||||
|
|
||||||
addStatementsToResolve(elementToResolve)
|
addStatementsToResolve(elementToResolve)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,7 +48,8 @@ class PartialBodyResolveFilter(elementToResolve: JetElement, private val body: J
|
|||||||
|
|
||||||
private fun addStatementsToResolve(element: JetElement) {
|
private fun addStatementsToResolve(element: JetElement) {
|
||||||
if (element == body) return
|
if (element == body) return
|
||||||
val parent = element.getParent() as JetElement
|
val parent = element.getParent() as? JetElement
|
||||||
|
?: return
|
||||||
|
|
||||||
if (parent is JetBlockExpression) {
|
if (parent is JetBlockExpression) {
|
||||||
processBlock(parent)
|
processBlock(parent)
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import org.jetbrains.jet.lang.psi.JetElement;
|
|||||||
import org.jetbrains.jet.lang.psi.JetFile;
|
import org.jetbrains.jet.lang.psi.JetFile;
|
||||||
import org.jetbrains.jet.lang.resolve.AdditionalCheckerProvider;
|
import org.jetbrains.jet.lang.resolve.AdditionalCheckerProvider;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
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.ElementResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
|
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
|
||||||
import org.jetbrains.jet.storage.LazyResolveStorageManager;
|
import org.jetbrains.jet.storage.LazyResolveStorageManager;
|
||||||
|
|||||||
Reference in New Issue
Block a user