Partial body resolve works for property accessor body

This commit is contained in:
Valentin Kipyatkov
2014-11-21 13:05:40 +03:00
parent 8ccf56415a
commit 0b56760910
6 changed files with 59 additions and 27 deletions
@@ -95,22 +95,11 @@ public abstract class ElementResolver {
elementOfAdditionalResolve = jetElement;
}
if (partialBodyResolve && elementOfAdditionalResolve instanceof JetDeclarationWithBody) {
JetExpression body = ((JetDeclarationWithBody) elementOfAdditionalResolve).getBodyExpression();
if (partialBodyResolve && elementOfAdditionalResolve instanceof JetDeclaration) {
//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, probablyNothingCallableNames());
}
else { // do as less as possible body-resolve
filter = new Function1<JetElement, Boolean>() {
@Override
public Boolean invoke(JetElement element) {
return false;
}
};
}
Function1<JetElement, Boolean> filter = new PartialBodyResolveFilter(
jetElement,
(JetDeclaration) elementOfAdditionalResolve, probablyNothingCallableNames());
return elementAdditionalResolve(elementOfAdditionalResolve, filter);
}
@@ -155,7 +144,7 @@ public abstract class ElementResolver {
initializerAdditionalResolve(resolveSession, (JetClassInitializer) resolveElement, trace, file, bodyResolveFilter);
}
else if (resolveElement instanceof JetProperty) {
propertyAdditionalResolve(resolveSession, (JetProperty) resolveElement, trace, file);
propertyAdditionalResolve(resolveSession, (JetProperty) resolveElement, trace, file, bodyResolveFilter);
}
else if (resolveElement instanceof JetDelegationSpecifierList) {
delegationSpecifierAdditionalResolve(resolveSession, (JetDelegationSpecifierList) resolveElement, trace, file);
@@ -334,7 +323,12 @@ public abstract class ElementResolver {
descriptor.getScopeForMemberDeclarationResolution());
}
private void propertyAdditionalResolve(final ResolveSession resolveSession, final JetProperty jetProperty, BindingTrace trace, JetFile file) {
private void propertyAdditionalResolve(
final ResolveSession resolveSession,
final JetProperty jetProperty,
BindingTrace trace,
JetFile file,
@Nullable Function1<JetElement, Boolean> bodyResolveFilter) {
JetScope propertyResolutionScope = resolveSession.getScopeProvider().getResolutionScopeForDeclaration(jetProperty);
BodyResolveContextForLazy bodyResolveContext = new BodyResolveContextForLazy(
@@ -347,7 +341,7 @@ public abstract class ElementResolver {
return resolveSession.getScopeProvider().getResolutionScopeForDeclaration(declaration);
}
});
BodyResolver bodyResolver = createBodyResolver(resolveSession, trace, file, null);
BodyResolver bodyResolver = createBodyResolver(resolveSession, trace, file, bodyResolveFilter);
PropertyDescriptor descriptor = (PropertyDescriptor) resolveSession.resolveToDescriptor(jetProperty);
ForceResolveUtil.forceResolveAllContents(descriptor);
@@ -388,7 +382,7 @@ public abstract class ElementResolver {
JetClass klass,
BindingTrace trace,
JetFile file,
@Nullable Function1<JetElement, Boolean> filter
@Nullable Function1<JetElement, Boolean> bodyResolveFilter
) {
JetScope scope = resolveSession.getScopeProvider().getResolutionScopeForDeclaration(klass);
@@ -399,7 +393,7 @@ public abstract class ElementResolver {
classDescriptor,
JetPsiUtil.getElementTextWithContext(klass));
BodyResolver bodyResolver = createBodyResolver(resolveSession, trace, file, filter);
BodyResolver bodyResolver = createBodyResolver(resolveSession, trace, file, bodyResolveFilter);
bodyResolver.resolveConstructorParameterDefaultValuesAndAnnotations(createEmptyContext(resolveSession), trace, klass,
constructorDescriptor, scope);
}
@@ -25,15 +25,15 @@ 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
import org.jetbrains.jet.lang.psi.psiUtil.isProbablyNothing
import org.jetbrains.jet.utils.addToStdlib.firstOrNullIsInstance
import org.jetbrains.jet.lang.psi.psiUtil.isAncestor
//TODO: do resolve anonymous object's body
class PartialBodyResolveFilter(
elementToResolve: JetElement,
private val body: JetExpression,
private val declaration: JetDeclaration,
probablyNothingCallableNames: ProbablyNothingCallableNames
) : (JetElement) -> Boolean {
@@ -43,9 +43,9 @@ class PartialBodyResolveFilter(
private val nothingPropertyNames = probablyNothingCallableNames.propertyNames()
;{
assert(body.isAncestor(elementToResolve, strict = false))
assert(declaration.isAncestor(elementToResolve))
body.accept(object : JetVisitorVoid() {
declaration.accept(object : JetVisitorVoid() {
override fun visitNamedFunction(function: JetNamedFunction) {
super.visitNamedFunction(function)
@@ -60,7 +60,7 @@ class PartialBodyResolveFilter(
})
statementTree.mark(elementToResolve, MarkLevel.NEED_COMPLETION)
statementTree.blocks(body).forEach {
statementTree.blocks(declaration).forEach {
processBlock(it)
}
}
@@ -489,7 +489,7 @@ class PartialBodyResolveFilter(
private val statementMarks = HashMap<JetExpression, MarkLevel>()
private val blockLevels = HashMap<JetBlockExpression, MarkLevel>()
val topLevelBlocks: Collection<JetBlockExpression> = blocks(body)
val topLevelBlocks: Collection<JetBlockExpression> = blocks(declaration)
fun blocks(statement: JetExpression): Collection<JetBlockExpression>
= blocks(statement : JetElement)
@@ -510,7 +510,7 @@ class PartialBodyResolveFilter(
fun mark(element: PsiElement, level: MarkLevel) {
var e = element
while (e != body) {
while (e != declaration) {
if (e.isStatement()) {
markStatement(e as JetExpression, level)
}
@@ -0,0 +1,14 @@
Resolve target: val v: kotlin.Int
----------------------------------------------
var prop: Int
get() {
// STATEMENT DELETED: print("get")
val v = 1
<caret>v
// STATEMENT DELETED: return 1
}
set {
// STATEMENT DELETED: print("set")
// STATEMENT DELETED: val v = 2
// STATEMENT DELETED: print("yes")
}
@@ -0,0 +1,12 @@
var prop: Int
get() {
print("get")
val v = 1
<caret>v
return 1
}
set {
print("set")
val v = 2
print("yes")
}
@@ -0,0 +1,6 @@
val prop: Int = run {
print("a")
val v = 1
<caret>v
1
}
@@ -312,6 +312,12 @@ public class PartialBodyResolveTestGenerated extends AbstractPartialBodyResolveT
doTest(fileName);
}
@TestMetadata("PropertyAccessorBody.kt")
public void testPropertyAccessorBody() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/resolve/partialBodyResolve/PropertyAccessorBody.kt");
doTest(fileName);
}
@TestMetadata("ReturnLambda.kt")
public void testReturnLambda() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/resolve/partialBodyResolve/ReturnLambda.kt");