Bug 573298: [R-Source] Add support for special argument matching of
replacement/assignment function calls
Follow-up-to: b7881103eb457817a085d4ee938fcf894649f331
Change-Id: If7ef8da36c5652a2b41a835a5fbbbed17fa76105
diff --git a/r/org.eclipse.statet.r.core-tests/src/org/eclipse/statet/r/core/rsource/ast/RArgumentMatchingTest.java b/r/org.eclipse.statet.r.core-tests/src/org/eclipse/statet/r/core/rsource/ast/RArgumentMatchingTest.java
index f8c65bb..7d4ec79 100644
--- a/r/org.eclipse.statet.r.core-tests/src/org/eclipse/statet/r/core/rsource/ast/RArgumentMatchingTest.java
+++ b/r/org.eclipse.statet.r.core-tests/src/org/eclipse/statet/r/core/rsource/ast/RArgumentMatchingTest.java
@@ -144,155 +144,180 @@
@Test
- public void PipeContext_match_simple() {
+ public void PipeTarget_match_simple() {
final ArgsDefinition argsDef = new ArgsDefinition("a", "b", "c");
- assertArgsPipeTarget(argsDef, "1, 2", newIntList(0, 1, 2));
- assertArgsPipeTarget(argsDef, "b=1, c=2", newIntList(0, 1, 2));
- assertArgsPipeTarget(argsDef, "a=1, 2", newIntList(1, 0, 2));
- assertArgsPipeTarget(argsDef, "1, a=2", newIntList(1, 2, 0));
- assertArgsPipeTarget(argsDef, "1, b=2", newIntList(0, 2, 1));
- assertArgsPipeTarget(argsDef, "b=1, 2", newIntList(0, 1, 2));
- assertArgsPipeTarget(argsDef, "c=1, 2", newIntList(0, 2, 1));
- assertArgsPipeTarget(argsDef, "a=1, b=2", newIntList(2, 0, 1));
- assertArgsPipeTarget(argsDef, "b=1, a=2", newIntList(2, 1, 0));
- assertArgsPipeTarget(argsDef, "c=1, b=2", newIntList(0, 2, 1));
+ assertArgs_PipeTarget(argsDef, "1, 2", newIntList(0, 1, 2));
+ assertArgs_PipeTarget(argsDef, "b=1, c=2", newIntList(0, 1, 2));
+ assertArgs_PipeTarget(argsDef, "a=1, 2", newIntList(1, 0, 2));
+ assertArgs_PipeTarget(argsDef, "1, a=2", newIntList(1, 2, 0));
+ assertArgs_PipeTarget(argsDef, "1, b=2", newIntList(0, 2, 1));
+ assertArgs_PipeTarget(argsDef, "b=1, 2", newIntList(0, 1, 2));
+ assertArgs_PipeTarget(argsDef, "c=1, 2", newIntList(0, 2, 1));
+ assertArgs_PipeTarget(argsDef, "a=1, b=2", newIntList(2, 0, 1));
+ assertArgs_PipeTarget(argsDef, "b=1, a=2", newIntList(2, 1, 0));
+ assertArgs_PipeTarget(argsDef, "c=1, b=2", newIntList(0, 2, 1));
}
@Test
- public void PipeContext_match_lessThanDef() {
+ public void PipeTarget_match_lessThanDef() {
final ArgsDefinition argsDef = new ArgsDefinition("a", "b", "c");
- assertArgsPipeTarget(argsDef, "1", newIntList(0, 1));
- assertArgsPipeTarget(argsDef, "b=1", newIntList(0, 1));
- assertArgsPipeTarget(argsDef, "a=1", newIntList(1, 0));
- assertArgsPipeTarget(argsDef, "c=1", newIntList(0, 2));
+ assertArgs_PipeTarget(argsDef, "1", newIntList(0, 1));
+ assertArgs_PipeTarget(argsDef, "b=1", newIntList(0, 1));
+ assertArgs_PipeTarget(argsDef, "a=1", newIntList(1, 0));
+ assertArgs_PipeTarget(argsDef, "c=1", newIntList(0, 2));
}
@Test
- public void PipeContext_match_emptyArg1() {
+ public void PipeTarget_match_emptyArg1() {
final ArgsDefinition argsDef = new ArgsDefinition("a", "b", "c");
- assertArgsPipeTarget(argsDef, ", 2", newIntList(0, 1, 2));
- assertArgsPipeTarget(argsDef, "b=, 2", newIntList(0, 1, 2));
- assertArgsPipeTarget(argsDef, "a=, 2", newIntList(1, 0, 2));
- assertArgsPipeTarget(argsDef, ", a=2", newIntList(1, 2, 0));
- assertArgsPipeTarget(argsDef, "c=, 2", newIntList(0, 2, 1));
- assertArgsPipeTarget(argsDef, "a=, b=2", newIntList(2, 0, 1));
- assertArgsPipeTarget(argsDef, "b=, a=2", newIntList(2, 1, 0));
+ assertArgs_PipeTarget(argsDef, ", 2", newIntList(0, 1, 2));
+ assertArgs_PipeTarget(argsDef, "b=, 2", newIntList(0, 1, 2));
+ assertArgs_PipeTarget(argsDef, "a=, 2", newIntList(1, 0, 2));
+ assertArgs_PipeTarget(argsDef, ", a=2", newIntList(1, 2, 0));
+ assertArgs_PipeTarget(argsDef, "c=, 2", newIntList(0, 2, 1));
+ assertArgs_PipeTarget(argsDef, "a=, b=2", newIntList(2, 0, 1));
+ assertArgs_PipeTarget(argsDef, "b=, a=2", newIntList(2, 1, 0));
}
@Test
- public void PipeContext_match_emptyArg2() {
+ public void PipeTarget_match_emptyArg2() {
final ArgsDefinition argsDef = new ArgsDefinition("a", "b", "c");
- assertArgsPipeTarget(argsDef, "1, ", newIntList(0, 1, 2));
- assertArgsPipeTarget(argsDef, "b=1, ", newIntList(0, 1, 2));
- assertArgsPipeTarget(argsDef, "a=1, ", newIntList(1, 0, 2));
- assertArgsPipeTarget(argsDef, "1, a=", newIntList(1, 2, 0));
- assertArgsPipeTarget(argsDef, "b=1, ", newIntList(0, 1, 2));
- assertArgsPipeTarget(argsDef, "c=1, ", newIntList(0, 2, 1));
- assertArgsPipeTarget(argsDef, "a=1, b=", newIntList(2, 0, 1));
- assertArgsPipeTarget(argsDef, "b=1, a=", newIntList(2, 1, 0));
- assertArgsPipeTarget(argsDef, "c=1, a=", newIntList(1, 2, 0));
+ assertArgs_PipeTarget(argsDef, "1, ", newIntList(0, 1, 2));
+ assertArgs_PipeTarget(argsDef, "b=1, ", newIntList(0, 1, 2));
+ assertArgs_PipeTarget(argsDef, "a=1, ", newIntList(1, 0, 2));
+ assertArgs_PipeTarget(argsDef, "1, a=", newIntList(1, 2, 0));
+ assertArgs_PipeTarget(argsDef, "b=1, ", newIntList(0, 1, 2));
+ assertArgs_PipeTarget(argsDef, "c=1, ", newIntList(0, 2, 1));
+ assertArgs_PipeTarget(argsDef, "a=1, b=", newIntList(2, 0, 1));
+ assertArgs_PipeTarget(argsDef, "b=1, a=", newIntList(2, 1, 0));
+ assertArgs_PipeTarget(argsDef, "c=1, a=", newIntList(1, 2, 0));
}
@Test
- public void PipeContext_match_partialMatch() {
+ public void PipeTarget_match_partialMatch() {
final ArgsDefinition argsDef = new ArgsDefinition("aaa", "bbb", "bb", "c");
- assertArgsPipeTarget(argsDef, "bbb=1, b=2, 3", newIntList(0, 1, 2, 3));
- assertArgsPipeTarget(argsDef, "bbb=1, b=2, b=3", newIntList(0, 1, 2, -1));
- assertArgsPipeTarget(argsDef, "b=1, b=2, bbb=3", newIntList(0, 2, -1, 1));
- assertArgsPipeTarget(argsDef, "b=1, 2", newIntList(0, -1, 1));
- assertArgsPipeTarget(argsDef, "a=1, 2", newIntList(1, 0, 2));
- assertArgsPipeTarget(argsDef, "a=1, b=2", newIntList(1, 0, -1));
+ assertArgs_PipeTarget(argsDef, "bbb=1, b=2, 3", newIntList(0, 1, 2, 3));
+ assertArgs_PipeTarget(argsDef, "bbb=1, b=2, b=3", newIntList(0, 1, 2, -1));
+ assertArgs_PipeTarget(argsDef, "b=1, b=2, bbb=3", newIntList(0, 2, -1, 1));
+ assertArgs_PipeTarget(argsDef, "b=1, 2", newIntList(0, -1, 1));
+ assertArgs_PipeTarget(argsDef, "a=1, 2", newIntList(1, 0, 2));
+ assertArgs_PipeTarget(argsDef, "a=1, b=2", newIntList(1, 0, -1));
}
@Test
- public void PipeContext_match_ellipsisAtEnd() {
+ public void PipeTarget_match_ellipsisAtEnd() {
final ArgsDefinition argsDef = new ArgsDefinition("a", "b", "...");
- assertArgsPipeTarget(argsDef, "a=1, b=2, 3", newIntList(2, 0, 1, 2), newIntList(E, D, D, E));
- assertArgsPipeTarget(argsDef, "a=1, b=2, 3, 4", newIntList(2, 0, 1, 2, 2), newIntList(E, D, D, E, E));
- assertArgsPipeTarget(argsDef, "a=1, 2, 3", newIntList(1, 0, 2, 2), newIntList(D, D, E, E));
- assertArgsPipeTarget(argsDef, "1, b=2, 3", newIntList(0, 2, 1, 2), newIntList(D, E, D, E));
- assertArgsPipeTarget(argsDef, "", newIntList(0), newIntList(D));
- assertArgsPipeTarget(argsDef, "a=1", newIntList(1, 0), newIntList(D, D));
- assertArgsPipeTarget(argsDef, "x=1, y=2", newIntList(0, 2, 2), newIntList(D, E, E));
+ assertArgs_PipeTarget(argsDef, "a=1, b=2, 3", newIntList(2, 0, 1, 2), newIntList(E, D, D, E));
+ assertArgs_PipeTarget(argsDef, "a=1, b=2, 3, 4", newIntList(2, 0, 1, 2, 2), newIntList(E, D, D, E, E));
+ assertArgs_PipeTarget(argsDef, "a=1, 2, 3", newIntList(1, 0, 2, 2), newIntList(D, D, E, E));
+ assertArgs_PipeTarget(argsDef, "1, b=2, 3", newIntList(0, 2, 1, 2), newIntList(D, E, D, E));
+ assertArgs_PipeTarget(argsDef, "", newIntList(0), newIntList(D));
+ assertArgs_PipeTarget(argsDef, "a=1", newIntList(1, 0), newIntList(D, D));
+ assertArgs_PipeTarget(argsDef, "x=1, y=2", newIntList(0, 2, 2), newIntList(D, E, E));
}
@Test
- public void AssignContext_match_simple() {
+ public void ReplCall_match_simple() {
final ArgsDefinition argsDef = new ArgsDefinition("a", "value", "b");
- assertArgsAssign(argsDef, "1, 2", newIntList(0, 2));
- assertArgsAssign(argsDef, "a=1, 2", newIntList(0, 2));
- assertArgsAssign(argsDef, "1, a=2", newIntList(2, 0));
- assertArgsAssign(argsDef, "b=1, 2", newIntList(0, 2));
- assertArgsAssign(argsDef, "a=1, b=2", newIntList(0, 2));
- assertArgsAssign(argsDef, "b=1, a=2", newIntList(2, 0));
+ assertArgs_ReplCall(argsDef, "1, 2", newIntList(0, 2));
+ assertArgs_ReplCall(argsDef, "a=1, 2", newIntList(0, 2));
+ assertArgs_ReplCall(argsDef, "1, a=2", newIntList(2, 0));
+ assertArgs_ReplCall(argsDef, "b=1, 2", newIntList(0, 2));
+ assertArgs_ReplCall(argsDef, "a=1, b=2", newIntList(0, 2));
+ assertArgs_ReplCall(argsDef, "b=1, a=2", newIntList(2, 0));
}
@Test
- public void AssignContext_match_lessThanDef() {
+ public void ReplCall_match_noValueArg() {
+ final ArgsDefinition argsDef = new ArgsDefinition("a", "b");
+
+ assertArgs_ReplCall(argsDef, "1, 2", newIntList(0, 1), N);
+ assertArgs_ReplCall(argsDef, "a=1, 2", newIntList(0, 1), N);
+ assertArgs_ReplCall(argsDef, "1, a=2", newIntList(1, 0), N);
+ assertArgs_ReplCall(argsDef, "b=1, 2", newIntList(0, 1), N);
+ assertArgs_ReplCall(argsDef, "a=1, b=2", newIntList(0, 1), N);
+ assertArgs_ReplCall(argsDef, "b=1, a=2", newIntList(1, 0), N);
+ }
+
+ @Test
+ public void ReplCall_match_lessThanDef() {
final ArgsDefinition argsDef = new ArgsDefinition("a", "b", "value");
- assertArgsAssign(argsDef, "1", newIntList(0));
- assertArgsAssign(argsDef, "a=1", newIntList(0));
- assertArgsAssign(argsDef, "b=2", newIntList(0));
+ assertArgs_ReplCall(argsDef, "1", newIntList(0));
+ assertArgs_ReplCall(argsDef, "a=1", newIntList(0));
+ assertArgs_ReplCall(argsDef, "b=2", newIntList(0));
}
@Test
- public void AssignContext_match_moreThanDef() {
+ public void ReplCall_match_moreThanDef() {
final ArgsDefinition argsDef = new ArgsDefinition("a", "value");
- assertArgsAssign(argsDef, "1, 2", newIntList(0, -1), newIntList(D, N));
+ assertArgs_ReplCall(argsDef, "1, 2", newIntList(0, -1), newIntList(D, N));
}
@Test
- public void AssignContext_match_emptyArg1() {
+ public void ReplCall_match_emptyArg1() {
final ArgsDefinition argsDef = new ArgsDefinition("a", "b", "value");
- assertArgsAssign(argsDef, ", 2", newIntList(0, 1));
- assertArgsAssign(argsDef, "a=, 2", newIntList(0, 1));
- assertArgsAssign(argsDef, ", a=2", newIntList(1, 0));
- assertArgsAssign(argsDef, "b=, 2", newIntList(0, 1));
- assertArgsAssign(argsDef, "a=, b=2", newIntList(0, 1));
- assertArgsAssign(argsDef, "b=, a=2", newIntList(1, 0));
+ assertArgs_ReplCall(argsDef, ", 2", newIntList(0, 1));
+ assertArgs_ReplCall(argsDef, "a=, 2", newIntList(0, 1));
+ assertArgs_ReplCall(argsDef, ", a=2", newIntList(1, 0));
+ assertArgs_ReplCall(argsDef, "b=, 2", newIntList(0, 1));
+ assertArgs_ReplCall(argsDef, "a=, b=2", newIntList(0, 1));
+ assertArgs_ReplCall(argsDef, "b=, a=2", newIntList(1, 0));
}
@Test
- public void AssignContext_match_emptyArg2() {
+ public void ReplCall_match_emptyArg2() {
final ArgsDefinition argsDef = new ArgsDefinition("a", "b", "value");
- assertArgsAssign(argsDef, "1, ", newIntList(0, 1));
- assertArgsAssign(argsDef, "a=1, ", newIntList(0, 1));
- assertArgsAssign(argsDef, "1, a=", newIntList(1, 0));
- assertArgsAssign(argsDef, "b=1, ", newIntList(0, 1));
- assertArgsAssign(argsDef, "a=1, b=", newIntList(0, 1));
- assertArgsAssign(argsDef, "b=1, a=", newIntList(1, 0));
+ assertArgs_ReplCall(argsDef, "1, ", newIntList(0, 1));
+ assertArgs_ReplCall(argsDef, "a=1, ", newIntList(0, 1));
+ assertArgs_ReplCall(argsDef, "1, a=", newIntList(1, 0));
+ assertArgs_ReplCall(argsDef, "b=1, ", newIntList(0, 1));
+ assertArgs_ReplCall(argsDef, "a=1, b=", newIntList(0, 1));
+ assertArgs_ReplCall(argsDef, "b=1, a=", newIntList(1, 0));
}
@Test
- public void AssignContext_match_partialMatch() {
+ public void ReplCall_match_partialMatch() {
final ArgsDefinition argsDef = new ArgsDefinition("aaa", "a", "value", "b");
- assertArgsAssign(argsDef, "a=1, aa=2, 3", newIntList(1, 0, 3));
+ assertArgs_ReplCall(argsDef, "a=1, aa=2, 3", newIntList(1, 0, 3));
}
@Test
- public void AssignContext_match_ellipsisAtEnd() {
+ public void ReplCall_match_ellipsisAtEnd() {
final ArgsDefinition argsDef = new ArgsDefinition("a", "value", "b", "...");
- assertArgsAssign(argsDef, "a=1, b=2, 3", newIntList(0, 2, 3), newIntList(D, D, E));
- assertArgsAssign(argsDef, "a=1, b=2, 3, 4", newIntList(0, 2, 3, 3), newIntList(D, D, E, E));
- assertArgsAssign(argsDef, "a=1, 2, 3", newIntList(0, 2, 3), newIntList(D, D, E));
- assertArgsAssign(argsDef, "1, b=2, 3", newIntList(0, 2, 3), newIntList(D, D, E));
- assertArgsAssign(argsDef, "", newIntList(), newIntList());
- assertArgsAssign(argsDef, "a=1", newIntList(0), newIntList(D));
- assertArgsAssign(argsDef, "x=1, y=2", newIntList(0, 3), newIntList(D, E));
+ assertArgs_ReplCall(argsDef, "a=1, b=2, 3", newIntList(0, 2, 3), newIntList(D, D, E));
+ assertArgs_ReplCall(argsDef, "a=1, b=2, 3, 4", newIntList(0, 2, 3, 3), newIntList(D, D, E, E));
+ assertArgs_ReplCall(argsDef, "a=1, 2, 3", newIntList(0, 2, 3), newIntList(D, D, E));
+ assertArgs_ReplCall(argsDef, "1, b=2, 3", newIntList(0, 2, 3), newIntList(D, D, E));
+ assertArgs_ReplCall(argsDef, "", newIntList(), newIntList());
+ assertArgs_ReplCall(argsDef, "a=1", newIntList(0), newIntList(D));
+ assertArgs_ReplCall(argsDef, "x=1, y=2", newIntList(0, 3), newIntList(D, E));
+ }
+
+ @Test
+ public void ReplCall_match_ellipsisAtEnd_noValueArg() {
+ final ArgsDefinition argsDef = new ArgsDefinition("a", "b", "...");
+
+ assertArgs_ReplCall(argsDef, "a=1, b=2, 3", newIntList(0, 1, 2), newIntList(D, D, E), E);
+ assertArgs_ReplCall(argsDef, "a=1, b=2, 3, 4", newIntList(0, 1, 2, 2), newIntList(D, D, E, E), E);
+ assertArgs_ReplCall(argsDef, "a=1, 2, 3", newIntList(0, 1, 2), newIntList(D, D, E), E);
+ assertArgs_ReplCall(argsDef, "1, b=2, 3", newIntList(0, 1, 2), newIntList(D, D, E), E);
+ assertArgs_ReplCall(argsDef, "", newIntList(), newIntList(), E);
+ assertArgs_ReplCall(argsDef, "a=1", newIntList(0), newIntList(D), E);
+ assertArgs_ReplCall(argsDef, "x=1, y=2", newIntList(0, 2), newIntList(D, E), E);
}
@@ -301,16 +326,16 @@
final ArgsDefinition argsDef= new ArgsDefinition("a", "b", "...");
final ArgsDefinition argsAssignDef = new ArgsDefinition("a", "b", "value", "...");
- assertArgs(argsDef, (FCall)parseExpr("f(c= 3, 1)"), newIntList(2, 0));
- assertArgs(argsDef, (FCall)parseExpr("x <- f(c= 3, 1)").getChild(1), newIntList(2, 0));
+ assertArgs_AutoContext(argsDef, (FCall)parseExpr("f(c= 3, 1)"), newIntList(2, 0));
+ assertArgs_AutoContext(argsDef, (FCall)parseExpr("x <- f(c= 3, 1)").getChild(1), newIntList(2, 0));
- assertArgs(argsDef, (FCall)parseExpr("0 |> f(c= 3, 1)").getChild(1), newIntList(0, 2, 1));
- assertArgs(argsDef, (FCall)parseExpr("0 |> (\\(a, b, ...){})(c= 3, 1)").getChild(1), newIntList(0, 2, 1));
+ assertArgs_AutoContext(argsDef, (FCall)parseExpr("0 |> f(c= 3, 1)").getChild(1), newIntList(0, 2, 1));
+ assertArgs_AutoContext(argsDef, (FCall)parseExpr("0 |> (\\(a, b, ...){})(c= 3, 1)").getChild(1), newIntList(0, 2, 1));
- assertArgs(argsDef, (FCall)parseExpr("f(x, c= 3, 1) <- 1").getChild(0), newIntList(0, 2, 1));
- assertArgs(argsAssignDef, (FCall)parseExpr("f(x, c= 3, 1) <- 1").getChild(0), newIntList(0, 3, 1));
- assertArgs(argsAssignDef, (FCall)parseExpr("f(x, c= 3, 1) = 1").getChild(0), newIntList(0, 3, 1));
- assertArgs(argsAssignDef, (FCall)parseExpr("1 -> f(x, c= 3, 1)").getChild(1), newIntList(0, 3, 1));
+ assertArgs_AutoContext(argsDef, (FCall)parseExpr("f(x, c= 3, 1) <- 1").getChild(0), newIntList(0, 2, 1));
+ assertArgs_AutoContext(argsAssignDef, (FCall)parseExpr("f(x, c= 3, 1) <- 1").getChild(0), newIntList(0, 3, 1));
+ assertArgs_AutoContext(argsAssignDef, (FCall)parseExpr("f(x, c= 3, 1) = 1").getChild(0), newIntList(0, 3, 1));
+ assertArgs_AutoContext(argsAssignDef, (FCall)parseExpr("1 -> f(x, c= 3, 1)").getChild(1), newIntList(0, 3, 1));
}
@@ -414,7 +439,7 @@
assertArgs(argsDef, code, expectedDefIdxs, createMatchTypes(expectedDefIdxs));
}
- private void assertArgsPipeTarget(final ArgsDefinition argsDef, final String code,
+ private void assertArgs_PipeTarget(final ArgsDefinition argsDef, final String code,
final ImIntList expectedDefIdxs, final ImIntList expectedMatchTypes) {
final FCall.Args callArgs= parseArgs(code);
final RAstNode sourceNode= new NumberConst(RTerminal.NUM_INT);
@@ -538,17 +563,17 @@
assertNull(matchedArgs.getArgValueNode(-1));
}
- private void assertArgsPipeTarget(final ArgsDefinition argsDef, final String code,
+ private void assertArgs_PipeTarget(final ArgsDefinition argsDef, final String code,
final ImIntList expectedDefIdxs) {
- assertArgsPipeTarget(argsDef, code, expectedDefIdxs, createMatchTypes(expectedDefIdxs));
+ assertArgs_PipeTarget(argsDef, code, expectedDefIdxs, createMatchTypes(expectedDefIdxs));
}
- private void assertArgsAssign(final ArgsDefinition argsDef, final String code,
- final ImIntList expectedDefIdxs, final ImIntList expectedMatchTypes) {
+ private void assertArgs_ReplCall(final ArgsDefinition argsDef, final String code,
+ final ImIntList expectedDefIdxs, final ImIntList expectedMatchTypes, final int expectedValueType) {
final FCall.Args callArgs= parseArgs(code);
- final RAstNode sourceNode= new NumberConst(RTerminal.NUM_INT);
+ final RAstNode replValueNode= new NumberConst(RTerminal.NUM_INT);
final FCallArgMatch matchedArgs= RAsts.matchArgs(callArgs, argsDef,
- sourceNode, ImCollections.emptyList() );
+ replValueNode, ImCollections.emptyList() );
final int valueDefIdx= argsDef.indexOf("value");
assertEquals(argsDef, matchedArgs.getArgsDefinition());
@@ -588,12 +613,20 @@
}
}
}
+ switch (expectedValueType) {
+ case E:
+ ellipsisCount++;
+ break;
+ case N:
+ nonmatchingCount++;
+ break;
+ }
assertNull(matchedArgs.getArgDefinitionForInject(-1));
assertNull(matchedArgs.getArgDefinitionForFCall(-1));
- assertEquals(ellipsisCount, matchedArgs.ellipsisArgs.length);
- assertEquals(nonmatchingCount, matchedArgs.otherArgs.length);
+ assertEquals(ellipsisCount, matchedArgs.ellipsisArgs.length, "ellipsisCount");
+ assertEquals(nonmatchingCount, matchedArgs.otherArgs.length, "failCount");
// methods by defArgIdx
for (int defArgIdx= 0; defArgIdx < argsDef.size(); defArgIdx++) {
@@ -615,7 +648,7 @@
}
}
else if (defArgIdx == valueDefIdx) {
- assertEquals(sourceNode, matchedArgs.getArgValueNode(defArgIdx));
+ assertEquals(replValueNode, matchedArgs.getArgValueNode(defArgIdx));
}
else {
assertNull(matchedArgs.getArgNode(defArgIdx));
@@ -623,16 +656,37 @@
}
}
+ switch (expectedValueType) {
+ case E:
+ assertEquals(replValueNode, matchedArgs.ellipsisArgs[ellipsisCount - 1].getValueChild());
+ break;
+ case N:
+ assertEquals(replValueNode, matchedArgs.otherArgs[nonmatchingCount - 1].getValueChild());
+ break;
+ default:
+ break;
+ }
+
assertNull(matchedArgs.getArgNode(-1));
assertNull(matchedArgs.getArgValueNode(-1));
}
- private void assertArgsAssign(final ArgsDefinition argsDef, final String code,
- final ImIntList expectedDefIdxs) {
- assertArgsAssign(argsDef, code, expectedDefIdxs, createMatchTypes(expectedDefIdxs));
+ private void assertArgs_ReplCall(final ArgsDefinition argsDef, final String code,
+ final ImIntList expectedDefIdxs, final ImIntList expectedMatchTypes) {
+ assertArgs_ReplCall(argsDef, code, expectedDefIdxs, expectedMatchTypes, D);
}
- private void assertArgs(final ArgsDefinition argsDef, final FCall fCallNode,
+ private void assertArgs_ReplCall(final ArgsDefinition argsDef, final String code,
+ final ImIntList expectedDefIdxs, final int expectedValueType) {
+ assertArgs_ReplCall(argsDef, code, expectedDefIdxs, createMatchTypes(expectedDefIdxs), expectedValueType);
+ }
+
+ private void assertArgs_ReplCall(final ArgsDefinition argsDef, final String code,
+ final ImIntList expectedDefIdxs) {
+ assertArgs_ReplCall(argsDef, code, expectedDefIdxs, createMatchTypes(expectedDefIdxs), D);
+ }
+
+ private void assertArgs_AutoContext(final ArgsDefinition argsDef, final FCall fCallNode,
final ImIntList expectedDefIdxs) {
final FCallArgMatch matchedArgs= RAsts.matchArgs(fCallNode, argsDef);
diff --git a/r/org.eclipse.statet.r.core/src/org/eclipse/statet/r/core/rsource/ast/RAsts.java b/r/org.eclipse.statet.r.core/src/org/eclipse/statet/r/core/rsource/ast/RAsts.java
index b09295e..d71a769 100644
--- a/r/org.eclipse.statet.r.core/src/org/eclipse/statet/r/core/rsource/ast/RAsts.java
+++ b/r/org.eclipse.statet.r.core/src/org/eclipse/statet/r/core/rsource/ast/RAsts.java
@@ -523,13 +523,14 @@
private static final int ELLIPSIS= -2;
private static final int TEST_PARTIAL= -3;
private static final int TEST_POSITION= -4;
+ private static final int NA= -5;
/**
* Reads the arguments of a function call for the given function definition
*
* If follows mainly the R rules expect if R would fail.
*
- * 1) Exact matching on tags.
+ * 1) Exact matching on tags.
* a) First supplied named argument matching exactly a formal name
* is assigned to its formal arguments (position) in <code>argsNode</code>
* b) Additional supplied arguments matching exactly the formal name
@@ -554,14 +555,15 @@
*
* @param fCallArgs the arguments of the function call
* @param argsDefinition the arguments definition
- * @param inject0Args the injected arguments inserted at index 0
+ * @param replValueArg the value node of the 'value' argument of a replacement function
+ * @param inject0Args the value nodes of injected arguments inserted at index 0
* @return the match
*/
public static FCallArgMatch matchArgs(final FCall.Args fCallArgs,
final ArgsDefinition argsDefinition,
- final @Nullable RAstNode assignmentValueArg,
+ final @Nullable RAstNode replValueArg,
final ImList<? extends @Nullable RAstNode> inject0Args) {
- if (assignmentValueArg != null && !inject0Args.isEmpty()) {
+ if (replValueArg != null && !inject0Args.isEmpty()) {
throw new IllegalArgumentException();
}
final int fCallArgStartIdx= inject0Args.size();
@@ -570,15 +572,30 @@
final FCall. @Nullable Arg[] allocatedArgs= (defArgsCount > 0) ?
new FCall. @Nullable Arg[defArgsCount] : Nullable_NO_ARGS;
final int ellipsisDefIdx= argsDefinition.indexOf("..."); //$NON-NLS-1$
- final int assignmentValueDefIdx= (assignmentValueArg != null) ? argsDefinition.indexOf("value") : -1; //$NON-NLS-1$
+ final int replValueDefIdx= (replValueArg != null) ? argsDefinition.indexOf("value") : -1; //$NON-NLS-1$
final int[] argsNode2argsDef= new int[nodeArgsCount];
+ int replValue2ArgsDef;
int ellipsisCount= 0;
int failCount= 0;
boolean testPartial= false;
- if (assignmentValueDefIdx > 0) {
- allocatedArgs[assignmentValueDefIdx]= createInjectArg(fCallArgs, assignmentValueArg);
+ if (replValueArg != null) {
+ if (replValueDefIdx > 0) {
+ allocatedArgs[replValueDefIdx]= createInjectArg(fCallArgs, replValueArg);
+ replValue2ArgsDef= replValueDefIdx;
+ }
+ else if (replValueDefIdx == 0) {
+ replValue2ArgsDef= FAIL;
+ failCount++;
+ }
+ else {
+ replValue2ArgsDef= ELLIPSIS;
+ ellipsisCount++;
+ }
+ }
+ else {
+ replValue2ArgsDef= NA;
}
for (int nodeIdx= 0; nodeIdx < fCallArgStartIdx; nodeIdx++) {
argsNode2argsDef[nodeIdx]= TEST_POSITION;
@@ -654,7 +671,8 @@
}
}
- if (assignmentValueDefIdx > 0 && allocatedArgs[0] == null && nodeArgsCount > 0) {
+ if (replValueArg != null && replValueDefIdx != 0
+ && allocatedArgs[0] == null && nodeArgsCount > 0) {
switch (argsNode2argsDef[0]) {
case FAIL:
break;
@@ -704,6 +722,9 @@
argsNode2argsDef[nodeIdx]= FAIL;
}
}
+ if (replValue2ArgsDef == ELLIPSIS) {
+ replValue2ArgsDef= FAIL;
+ }
failCount+= ellipsisCount;
ellipsisCount= 0;
}
@@ -727,6 +748,16 @@
continue ITER_ARGS;
}
}
+ switch (replValue2ArgsDef) {
+ case ELLIPSIS:
+ ellipsisArgs[ellipsisIdx++]= createInjectArg(fCallArgs, replValueArg);
+ break;
+ case FAIL:
+ otherArgs[otherIdx++]= createInjectArg(fCallArgs, replValueArg);
+ break;
+ default:
+ break;
+ }
}
return new FCallArgMatch(argsDefinition, fCallArgs, fCallArgStartIdx,
allocatedArgs, ellipsisArgs, otherArgs,
@@ -742,7 +773,7 @@
}
public static FCallArgMatch matchArgs(final FCall fCallNode, final ArgsDefinition argsDef) {
- @Nullable RAstNode assignmentValueArg= null;
+ @Nullable RAstNode replValueArg= null;
ImList<@Nullable RAstNode> inject0Args= ImCollections.emptyList();
final RAstNode parentNode= fCallNode.getRParent();
if (parentNode != null) {
@@ -759,7 +790,7 @@
case A_RIGHT:
{ final Assignment assignNode= (Assignment)parentNode;
if (assignNode.getTargetChild() == fCallNode) {
- assignmentValueArg= assignNode.getSourceChild();
+ replValueArg= assignNode.getSourceChild();
}
break;
}
@@ -767,7 +798,7 @@
break;
}
}
- return matchArgs(fCallNode.getArgsChild(), argsDef, assignmentValueArg, inject0Args);
+ return matchArgs(fCallNode.getArgsChild(), argsDef, replValueArg, inject0Args);
}
diff --git a/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/editors/RContextInformationValidator.java b/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/editors/RContextInformationValidator.java
index a020f50..026d905 100644
--- a/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/editors/RContextInformationValidator.java
+++ b/r/org.eclipse.statet.r.ui/src/org/eclipse/statet/internal/r/ui/editors/RContextInformationValidator.java
@@ -195,7 +195,7 @@
final FCall fCallNode= info.getFCallNode();
// like org.eclipse.statet.r.core.rsource.ast.RAsts#matchArgs(FCall, ArgsDefinition)
- @Nullable RAstNode assignmentValueArg= null;
+ @Nullable RAstNode replValueArg= null;
ImList<@Nullable RAstNode> inject0Args= ImCollections.emptyList();
final RAstNode parentNode= fCallNode.getRParent();
if (parentNode != null) {
@@ -212,7 +212,7 @@
case A_RIGHT:
{ final Assignment assignNode= (Assignment)parentNode;
if (assignNode.getTargetChild() == fCallNode) {
- assignmentValueArg= assignNode.getSourceChild();
+ replValueArg= assignNode.getSourceChild();
}
break;
}
@@ -220,7 +220,7 @@
break;
}
}
- return RAsts.matchArgs(argsNode, info.getArgsDefinition(), assignmentValueArg, inject0Args);
+ return RAsts.matchArgs(argsNode, info.getArgsDefinition(), replValueArg, inject0Args);
}