Navigation to invoke() from {}

Example:

foo <caret>{}
This commit is contained in:
Andrey Breslav
2013-08-28 15:26:47 +04:00
parent a53986e1d6
commit 87293a8831
12 changed files with 179 additions and 19 deletions
@@ -20,7 +20,7 @@ import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.JetNodeTypes;
import org.jetbrains.jet.lexer.JetToken;
import org.jetbrains.jet.lexer.JetTokens;
import java.util.List;
@@ -65,4 +65,14 @@ public class JetFunctionLiteralExpression extends JetExpressionImpl {
public JetElement asElement() {
return this;
}
@NotNull
public ASTNode getLeftCurlyBrace() {
return getFunctionLiteral().getNode().findChildByType(JetTokens.LBRACE);
}
@Nullable
public ASTNode getRightCurlyBrace() {
return getFunctionLiteral().getNode().findChildByType(JetTokens.RBRACE);
}
}
@@ -22,9 +22,7 @@ import com.intellij.psi.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.psi.JetCallExpression;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetValueArgumentList;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
@@ -79,26 +77,43 @@ class JetInvokeFunctionReference extends JetPsiReference implements MultiRangeRe
@Override
public List<TextRange> getRanges() {
JetCallExpression callExpression = (JetCallExpression) myExpression;
List<TextRange> list = new ArrayList<TextRange>();
JetValueArgumentList valueArgumentList = ((JetCallExpression) myExpression).getValueArgumentList();
if (valueArgumentList == null) {
return list;
JetValueArgumentList valueArgumentList = callExpression.getValueArgumentList();
if (valueArgumentList != null) {
if (valueArgumentList.getArguments().size() > 0) {
ASTNode valueArgumentListNode = valueArgumentList.getNode();
ASTNode lPar = valueArgumentListNode.findChildByType(JetTokens.LPAR);
if (lPar != null) {
list.add(getRange(lPar));
}
ASTNode rPar = valueArgumentListNode.findChildByType(JetTokens.RPAR);
if (rPar != null) {
list.add(getRange(rPar));
}
}
else {
list.add(getRange(valueArgumentList.getNode()));
}
}
if (valueArgumentList.getArguments().size() > 0) {
ASTNode valueArgumentListNode = valueArgumentList.getNode();
ASTNode lPar = valueArgumentListNode.findChildByType(JetTokens.LPAR);
if (lPar != null) {
list.add(getRange(lPar));
List<JetExpression> functionLiteralArguments = callExpression.getFunctionLiteralArguments();
for (JetExpression functionLiteralArgument : functionLiteralArguments) {
while (functionLiteralArgument instanceof JetPrefixExpression) {
functionLiteralArgument = ((JetPrefixExpression) functionLiteralArgument).getBaseExpression();
}
ASTNode rPar = valueArgumentListNode.findChildByType(JetTokens.RPAR);
if (rPar != null) {
list.add(getRange(rPar));
if (functionLiteralArgument instanceof JetFunctionLiteralExpression) {
JetFunctionLiteralExpression functionLiteralExpression = (JetFunctionLiteralExpression) functionLiteralArgument;
list.add(getRange(functionLiteralExpression.getLeftCurlyBrace()));
ASTNode rightCurlyBrace = functionLiteralExpression.getRightCurlyBrace();
if (rightCurlyBrace != null) {
list.add(getRange(rightCurlyBrace));
}
}
}
else {
list.add(getRange(valueArgumentList.getNode()));
}
return list;
}
@@ -0,0 +1,9 @@
class Foo {
fun invoke(vararg a: Any) {}
}
fun test(f: Foo) {
f() <caret>{}
}
// REF: (in Foo).invoke(Any)
@@ -0,0 +1,9 @@
class Foo {
fun invoke(vararg a: Any) {}
}
fun test(f: Foo) {
f <caret>{}
}
// REF: (in Foo).invoke(Any)
@@ -0,0 +1,9 @@
class Foo {
fun invoke(vararg a: Any) {}
}
fun test(f: Foo) {
f @f <caret>{}
}
// REF: (in Foo).invoke(Any)
@@ -0,0 +1,9 @@
class Foo {
fun invoke(vararg a: Any) {}
}
fun test(f: Foo) {
f {<caret>}
}
// REF: (in Foo).invoke(Any)
@@ -0,0 +1,9 @@
class Foo {
fun invoke(vararg a: Any) {}
}
fun test(f: Foo) {
f<caret>()
}
// REF: (in Foo).invoke(Any)
@@ -0,0 +1,9 @@
class Foo {
fun invoke(vararg a: Any) {}
}
fun test(f: Foo) {
f(<caret>)
}
// REF: (in Foo).invoke(Any)
@@ -0,0 +1,9 @@
class Foo {
fun invoke(vararg a: Any) {}
}
fun test(f: Foo) {
f() { 1<caret>}
}
// REF: (in Foo).invoke(Any)
@@ -0,0 +1,9 @@
class Foo {
fun invoke(vararg a: Any) {}
}
fun test(f: Foo) {
f<caret>(1)
}
// REF: (in Foo).invoke(Any)
@@ -0,0 +1,9 @@
class Foo {
fun invoke(vararg a: Any) {}
}
fun test(f: Foo) {
f(1<caret>)
}
// REF: (in Foo).invoke(Any)
@@ -31,7 +31,7 @@ import org.jetbrains.jet.resolve.AbstractResolveBaseTest;
/** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("idea/testData/resolve/references")
@InnerTestClasses({ReferenceResolveTestGenerated.DelegatedPropertyAccessors.class, ReferenceResolveTestGenerated.ForLoopIn.class})
@InnerTestClasses({ReferenceResolveTestGenerated.DelegatedPropertyAccessors.class, ReferenceResolveTestGenerated.ForLoopIn.class, ReferenceResolveTestGenerated.Invoke.class})
public class ReferenceResolveTestGenerated extends AbstractResolveBaseTest {
public void testAllFilesPresentInReferences() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/resolve/references"), Pattern.compile("^(.+)\\.kt$"), true);
@@ -325,11 +325,65 @@ public class ReferenceResolveTestGenerated extends AbstractResolveBaseTest {
}
}
@TestMetadata("idea/testData/resolve/references/invoke")
public static class Invoke extends AbstractResolveBaseTest {
public void testAllFilesPresentInInvoke() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/resolve/references/invoke"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("lambdaAndParens.kt")
public void testLambdaAndParens() throws Exception {
doTest("idea/testData/resolve/references/invoke/lambdaAndParens.kt");
}
@TestMetadata("lambdaNoPar.kt")
public void testLambdaNoPar() throws Exception {
doTest("idea/testData/resolve/references/invoke/lambdaNoPar.kt");
}
@TestMetadata("lambdaNoParLabel.kt")
public void testLambdaNoParLabel() throws Exception {
doTest("idea/testData/resolve/references/invoke/lambdaNoParLabel.kt");
}
@TestMetadata("lambdaNoParRCurly.kt")
public void testLambdaNoParRCurly() throws Exception {
doTest("idea/testData/resolve/references/invoke/lambdaNoParRCurly.kt");
}
@TestMetadata("noParams.kt")
public void testNoParams() throws Exception {
doTest("idea/testData/resolve/references/invoke/noParams.kt");
}
@TestMetadata("noParamsRPar.kt")
public void testNoParamsRPar() throws Exception {
doTest("idea/testData/resolve/references/invoke/noParamsRPar.kt");
}
@TestMetadata("nonemptyLambdaRPar.kt")
public void testNonemptyLambdaRPar() throws Exception {
doTest("idea/testData/resolve/references/invoke/nonemptyLambdaRPar.kt");
}
@TestMetadata("oneParam.kt")
public void testOneParam() throws Exception {
doTest("idea/testData/resolve/references/invoke/oneParam.kt");
}
@TestMetadata("oneParamRPar.kt")
public void testOneParamRPar() throws Exception {
doTest("idea/testData/resolve/references/invoke/oneParamRPar.kt");
}
}
public static Test suite() {
TestSuite suite = new TestSuite("ReferenceResolveTestGenerated");
suite.addTestSuite(ReferenceResolveTestGenerated.class);
suite.addTest(DelegatedPropertyAccessors.innerSuite());
suite.addTest(ForLoopIn.innerSuite());
suite.addTestSuite(Invoke.class);
return suite;
}
}