Bug 570738: [R-Model] Add support for pipe operator to SourceAnalyzer

Change-Id: I5aca52e848b86bc97a995141fce2eb4f55ef89a7
diff --git a/r/org.eclipse.statet.r.core/src/org/eclipse/statet/internal/r/core/sourcemodel/SourceAnalyzer.java b/r/org.eclipse.statet.r.core/src/org/eclipse/statet/internal/r/core/sourcemodel/SourceAnalyzer.java
index 988d31e..f208eb8 100644
--- a/r/org.eclipse.statet.r.core/src/org/eclipse/statet/internal/r/core/sourcemodel/SourceAnalyzer.java
+++ b/r/org.eclipse.statet.r.core/src/org/eclipse/statet/internal/r/core/sourcemodel/SourceAnalyzer.java
@@ -32,6 +32,7 @@
 import org.eclipse.core.runtime.OperationCanceledException;
 
 import org.eclipse.statet.jcommons.collections.ImCollections;
+import org.eclipse.statet.jcommons.collections.ImList;
 import org.eclipse.statet.jcommons.lang.NonNull;
 import org.eclipse.statet.jcommons.lang.NonNullByDefault;
 import org.eclipse.statet.jcommons.lang.Nullable;
@@ -77,6 +78,7 @@
 import org.eclipse.statet.r.core.rsource.ast.NodeType;
 import org.eclipse.statet.r.core.rsource.ast.NullConst;
 import org.eclipse.statet.r.core.rsource.ast.NumberConst;
+import org.eclipse.statet.r.core.rsource.ast.Pipe;
 import org.eclipse.statet.r.core.rsource.ast.Power;
 import org.eclipse.statet.r.core.rsource.ast.RAstNode;
 import org.eclipse.statet.r.core.rsource.ast.RAstVisitor;
@@ -397,9 +399,9 @@
 	private FCallAnalyzer fCallFallback;
 	private final FCallAnalyzer fCallNoAnalysis= new FCallAnalyzer() {
 		@Override
-		public void visit(final FCall node, final boolean assignment) throws InvocationTargetException {
+		public void visit(final FCall node, final boolean assignment, final ImList<RAstNode> inject0ArgValues) throws InvocationTargetException {
 			SourceAnalyzer.this.request= NO_REQUESTS;
-			node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+			visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 			SourceAnalyzer.this.returnValue= null;
 		}
 	};
@@ -1020,6 +1022,19 @@
 	}
 	
 	@Override
+	public void visit(final Pipe node) throws InvocationTargetException {
+		if (node.getTargetChild().getNodeType() == NodeType.F_CALL) {
+			visit((FCall)node.getTargetChild(), ImCollections.newList(node.getSourceChild()));
+		}
+		else {
+			this.request= NO_REQUESTS;
+			node.acceptInRChildren(this);
+			
+			this.returnValue= null;
+		}
+	}
+	
+	@Override
 	public void visit(final CForLoop node) throws InvocationTargetException {
 		final Symbol symbol= node.getVarChild();
 		final ElementAccess access= new ElementAccess.Default(symbol);
@@ -1093,6 +1108,10 @@
 	
 	@Override
 	public void visit(final FCall node) throws InvocationTargetException {
+		visit(node, ImCollections.emptyList());
+	}
+	
+	private void visit(final FCall node, final ImList<RAstNode> inject0Args) throws InvocationTargetException {
 		// Resolve
 		final RAstNode ref= node.getRefChild();
 		final ElementAccess access= new ElementAccess.Default(node, ref);
@@ -1122,22 +1141,34 @@
 		if (specialist == null) {
 			specialist= this.fCallFallback;
 		}
-		specialist.visit(node, write);
+		specialist.visit(node, write, inject0Args);
 	}
 	
 	@Override
 	public void visit(final FCall.Arg node) throws InvocationTargetException {
-		final RAstNode valueNode= node.getValueChild();
-		if (valueNode != null) {
-			if (!this.argValueToIgnore.remove(valueNode)) {
-				valueNode.acceptInR(this);
+		visitFCallArgValue(node.getValueChild());
+	}
+	
+	private void visitFCallArgs(final FCall.Args argsNode, final ImList<RAstNode> inject0ArgValues) throws InvocationTargetException {
+		for (final RAstNode valueNode : inject0ArgValues) {
+			visitFCallArgValue(valueNode);
+		}
+		for (final FCall.Arg argNode : argsNode.getArgChildren()) {
+			visitFCallArgValue(argNode.getValueChild());
+		}
+	}
+	
+	private void visitFCallArgValue(final @Nullable RAstNode node) throws InvocationTargetException {
+		if (node != null) {
+			if (!this.argValueToIgnore.remove(node)) {
+				node.acceptInR(this);
 			}
 		}
 		
 		this.returnValue= null;
 	}
 	
-	public @Nullable RMethod visitAndCheckValue(final FCall. @Nullable Arg node, final String name) throws InvocationTargetException {
+	private @Nullable RMethod visitAndCheckValue(final FCall. @Nullable Arg node, final String name) throws InvocationTargetException {
 		if (node != null) {
 			final RAstNode valueNode= node.getValueChild();
 			if (valueNode != null) {
@@ -1479,9 +1510,9 @@
 	}
 	
 	
-	protected static interface FCallAnalyzer {
+	protected interface FCallAnalyzer {
 		
-		public void visit(FCall node, boolean assignment) throws InvocationTargetException;
+		void visit(FCall node, boolean assignment, ImList<RAstNode> inject0ArgValues) throws InvocationTargetException;
 		
 	}
 	
@@ -1498,9 +1529,9 @@
 		}
 		
 		@Override
-		public final void visit(final FCall node, final boolean assignment) throws InvocationTargetException {
+		public final void visit(final FCall node, final boolean assignment, final ImList<RAstNode> inject0ArgValues) throws InvocationTargetException {
 			SourceAnalyzer.this.request= NO_REQUESTS;
-			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef);
+			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef, inject0ArgValues);
 			final RAstNode nameValue= args.getArgValueNode(this.argIdx_name);
 			
 			if (nameValue != null && nameValue.getNodeType() == NodeType.STRING_CONST) {
@@ -1518,7 +1549,7 @@
 				SourceAnalyzer.this.argValueToIgnore.add(nameValue);
 			}
 			
-			node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+			visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 			SourceAnalyzer.this.returnValue= null;
 		}
 		
@@ -1543,9 +1574,9 @@
 		}
 		
 		@Override
-		public final void visit(final FCall node, final boolean assignment) throws InvocationTargetException {
+		public final void visit(final FCall node, final boolean assignment, final ImList<RAstNode> inject0ArgValues) throws InvocationTargetException {
 			SourceAnalyzer.this.request= NO_REQUESTS;
-			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef);
+			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef, inject0ArgValues);
 			
 			ITER_ARGS: for (int i= 0; i < args.allocatedArgs.length; i++) {
 				final RAstNode argValue= args.getArgValueNode(i);
@@ -1594,7 +1625,7 @@
 				}
 			}
 			
-			node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+			visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 			SourceAnalyzer.this.returnValue= null;
 		}
 		
@@ -1615,9 +1646,9 @@
 		}
 		
 		@Override
-		public void visit(final FCall node, final boolean assignment) throws InvocationTargetException {
+		public void visit(final FCall node, final boolean assignment, final ImList<RAstNode> inject0ArgValues) throws InvocationTargetException {
 			SourceAnalyzer.this.returnValue= null;
-			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef);
+			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef, inject0ArgValues);
 			final RAstNode xNode= args.getArgValueNode(this.argIdx_x);
 			final RAstNode valueNode= args.getArgValueNode(this.argIdx_value);
 			
@@ -1640,7 +1671,7 @@
 				
 				returnValue= registerSourceElement(returnValue, access);
 			}
-			node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+			visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 			SourceAnalyzer.this.returnValue= returnValue;
 		}
 		
@@ -1655,9 +1686,9 @@
 		}
 		
 		@Override
-		public void visit(final FCall node, final boolean assignment) throws InvocationTargetException {
+		public void visit(final FCall node, final boolean assignment, final ImList<RAstNode> inject0ArgValues) throws InvocationTargetException {
 			SourceAnalyzer.this.request= NO_REQUESTS;
-			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef);
+			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef, inject0ArgValues);
 			
 			if (args.ellipsisArgs.length > 0) {
 				for (int i= 0; i < args.ellipsisArgs.length; i++) {
@@ -1687,7 +1718,7 @@
 				}
 			}
 			
-			node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+			visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 			SourceAnalyzer.this.returnValue= null;
 		}
 		
@@ -1714,9 +1745,9 @@
 		}
 		
 		@Override
-		public void visit(final FCall node, final boolean assignment) throws InvocationTargetException {
+		public void visit(final FCall node, final boolean assignment, final ImList<RAstNode> inject0ArgValues) throws InvocationTargetException {
 			SourceAnalyzer.this.request= NO_REQUESTS;
-			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef);
+			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef, inject0ArgValues);
 			final RAstNode xNode= args.getArgValueNode(this.argIdx_x);
 			
 			if (xNode != null && xNode.getNodeType() == NodeType.STRING_CONST) {
@@ -1734,7 +1765,7 @@
 				SourceAnalyzer.this.argValueToIgnore.add(xNode);
 			}
 			
-			node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+			visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 			SourceAnalyzer.this.returnValue= null;
 		}
 		
@@ -1749,9 +1780,9 @@
 		}
 		
 		@Override
-		public void visit(final FCall node, final boolean assignment) throws InvocationTargetException {
+		public void visit(final FCall node, final boolean assignment, final ImList<RAstNode> inject0ArgValues) throws InvocationTargetException {
 			SourceAnalyzer.this.request= NO_REQUESTS;
-			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef);
+			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef, inject0ArgValues);
 			
 			if (args.ellipsisArgs.length > 0) {
 				for (int i= 0; i < args.ellipsisArgs.length; i++) {
@@ -1775,7 +1806,7 @@
 				}
 			}
 			
-			node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+			visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 			SourceAnalyzer.this.returnValue= null;
 		}
 		
@@ -1792,9 +1823,9 @@
 		}
 		
 		@Override
-		public void visit(final FCall node, final boolean assignment) throws InvocationTargetException {
+		public void visit(final FCall node, final boolean assignment, final ImList<RAstNode> inject0ArgValues) throws InvocationTargetException {
 			SourceAnalyzer.this.request= NO_REQUESTS;
-			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef);
+			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef, inject0ArgValues);
 			final RAstNode nameNode= args.getArgValueNode(this.argIdx_fName);
 			
 			if (nameNode != null && nameNode.getNodeType() == NodeType.STRING_CONST) {
@@ -1806,7 +1837,7 @@
 				SourceAnalyzer.this.argValueToIgnore.add(nameNode);
 			}
 			
-			node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+			visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 			SourceAnalyzer.this.returnValue= null;
 		}
 		
@@ -1823,9 +1854,9 @@
 		}
 		
 		@Override
-		public void visit(final FCall node, final boolean assignment) throws InvocationTargetException {
+		public void visit(final FCall node, final boolean assignment, final ImList<RAstNode> inject0ArgValues) throws InvocationTargetException {
 			SourceAnalyzer.this.request= NO_REQUESTS;
-			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef);
+			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef, inject0ArgValues);
 			final RAstNode nameNode= args.getArgValueNode(this.argIdx_fName);
 			
 			if (nameNode != null) {
@@ -1838,7 +1869,7 @@
 				SourceAnalyzer.this.argValueToIgnore.add(nameNode);
 			}
 			
-			node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+			visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 			SourceAnalyzer.this.returnValue= null;
 		}
 		
@@ -1857,10 +1888,10 @@
 		}
 		
 		@Override
-		public void visit(final FCall node, final boolean assignment) throws InvocationTargetException {
+		public void visit(final FCall node, final boolean assignment, final ImList<RAstNode> inject0ArgValues) throws InvocationTargetException {
 			SourceAnalyzer.this.request= NO_REQUESTS;
 			
-			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef);
+			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef, inject0ArgValues);
 			final RAstNode nameValue= args.getArgValueNode(this.argIdx_packageName);
 			if (nameValue != null 
 					&& (nameValue.getNodeType() == NodeType.STRING_CONST
@@ -1888,7 +1919,7 @@
 				SourceAnalyzer.this.argValueToIgnore.add(nameValue);
 			}
 			
-			node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+			visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 			SourceAnalyzer.this.returnValue= SourceAnalyzer.this.globalEnvir;
 		}
 		
@@ -1917,9 +1948,9 @@
 		}
 		
 		@Override
-		public void visit(final FCall node, final boolean assignment) throws InvocationTargetException {
+		public void visit(final FCall node, final boolean assignment, final ImList<RAstNode> inject0ArgValues) throws InvocationTargetException {
 			SourceAnalyzer.this.request= NO_REQUESTS;
-			node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+			visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 			SourceAnalyzer.this.returnValue= SourceAnalyzer.this.globalEnvir;
 		}
 		
@@ -1931,10 +1962,10 @@
 		}
 		
 		@Override
-		public void visit(final FCall node, final boolean assignment) throws InvocationTargetException {
+		public void visit(final FCall node, final boolean assignment, final ImList<RAstNode> inject0ArgValues) throws InvocationTargetException {
 			SourceAnalyzer.this.request= NO_REQUESTS;
 //			final RAstNode envir= resolveEnvir(argValues, this.argsDef);
-			node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+			visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 			SourceAnalyzer.this.returnValue= SourceAnalyzer.this.topLevelEnvir;
 		}
 		
@@ -1949,11 +1980,11 @@
 		}
 		
 		@Override
-		public void visit(final FCall node, final boolean assignment) throws InvocationTargetException {
+		public void visit(final FCall node, final boolean assignment, final ImList<RAstNode> inject0ArgValues) throws InvocationTargetException {
 			Object returnValue= null;
 			REQUEST: for (int i= 0; i < SourceAnalyzer.this.request.length; i++) {
 				if (SourceAnalyzer.this.request[i] == RETURN_STRING_ARRAY) {
-					final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef);
+					final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef, inject0ArgValues);
 					final RAstNode[] array= new @NonNull RAstNode[args.ellipsisArgs.length];
 					for (int j= 0; j < array.length; j++) {
 						final FCall.Arg argNode= args.ellipsisArgs[j];
@@ -1974,7 +2005,7 @@
 			}
 			SourceAnalyzer.this.request= NO_REQUESTS;
 			
-			node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+			visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 			SourceAnalyzer.this.returnValue= returnValue;
 		}
 		
@@ -1999,9 +2030,9 @@
 		}
 		
 		@Override
-		public final void visit(final FCall node, final boolean assignment) throws InvocationTargetException {
+		public final void visit(final FCall node, final boolean assignment, final ImList<RAstNode> inject0ArgValues) throws InvocationTargetException {
 			SourceAnalyzer.this.request= NO_REQUESTS;
-			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef);
+			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef, inject0ArgValues);
 			final RAstNode fNameNode= args.getArgValueNode(this.argIdx_fName);
 			
 			if (fNameNode != null && fNameNode.getNodeType() == NodeType.STRING_CONST) {
@@ -2087,18 +2118,18 @@
 					}
 					rMethod.complete(methodDef);
 					
-					node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+					visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 					
 					leaveElement();
 				}
 				else {
 					addEnvirInsteadOfElement(envir, node);
 					
-					node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+					visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 				}
 			}
 			else {
-				node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+				visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 			}
 			SourceAnalyzer.this.returnValue= null;
 		}
@@ -2132,9 +2163,9 @@
 		}
 		
 		@Override
-		public void visit(final FCall node, final boolean assignment) throws InvocationTargetException {
+		public void visit(final FCall node, final boolean assignment, final ImList<RAstNode> inject0ArgValues) throws InvocationTargetException {
 			SourceAnalyzer.this.request= NO_REQUESTS;
-			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef);
+			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef, inject0ArgValues);
 			final RAstNode fNameNode= args.getArgValueNode(this.argIdx_fName);
 			
 			if (fNameNode != null && fNameNode.getNodeType() == NodeType.STRING_CONST) {
@@ -2146,7 +2177,7 @@
 				SourceAnalyzer.this.argValueToIgnore.add(fNameNode);
 			}
 			
-			node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+			visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 			SourceAnalyzer.this.returnValue= null;
 		}
 		
@@ -2161,9 +2192,9 @@
 		}
 		
 		@Override
-		public void visit(final FCall node, final boolean assignment) throws InvocationTargetException {
+		public void visit(final FCall node, final boolean assignment, final ImList<RAstNode> inject0ArgValues) throws InvocationTargetException {
 			SourceAnalyzer.this.request= NO_REQUESTS;
-			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef);
+			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef, inject0ArgValues);
 			Object returnValue= null;
 			
 			if (args.ellipsisArgs.length > 0) {
@@ -2189,7 +2220,7 @@
 				returnValue= new Signature(argNameNodes, classNames);
 			}
 			
-			node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+			visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 			SourceAnalyzer.this.returnValue= returnValue;
 		}
 		
@@ -2212,9 +2243,9 @@
 		}
 		
 		@Override
-		public void visit(final FCall node, final boolean assignment) throws InvocationTargetException {
+		public void visit(final FCall node, final boolean assignment, final ImList<RAstNode> inject0ArgValues) throws InvocationTargetException {
 			SourceAnalyzer.this.request= NO_REQUESTS;
-			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef);
+			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef, inject0ArgValues);
 			
 			final ElementAccess access= new ElementAccess.Class(node);
 			access.flags= ElementAccess.A_WRITE;
@@ -2264,16 +2295,15 @@
 					evalArgValue(prototypeValue, PROTOTYPE_REQUEST);
 				}
 				
-				node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+				visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 				
 				leaveElement();
 			}
 			else {
 				addEnvirInsteadOfElement(envir, node);
 				
-				node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+				visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 			}
-			
 			SourceAnalyzer.this.returnValue= null;
 		}
 		
@@ -2292,9 +2322,9 @@
 		}
 		
 		@Override
-		public void visit(final FCall node, final boolean assignment) throws InvocationTargetException {
+		public void visit(final FCall node, final boolean assignment, final ImList<RAstNode> inject0ArgValues) throws InvocationTargetException {
 			SourceAnalyzer.this.request= NO_REQUESTS;
-			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef);
+			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef, inject0ArgValues);
 			final RAstNode classNameValue= args.getArgValueNode(this.argIdx_className);
 			final RAstNode superClassNamesValue= args.getArgValueNode(this.argIdx_superClassNames);
 			
@@ -2333,16 +2363,15 @@
 					}
 				}
 				
-				node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+				visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 				
 				leaveElement();
 			}
 			else {
 				addEnvirInsteadOfElement(envir, node);
 				
-				node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+				visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 			}
-			
 			SourceAnalyzer.this.returnValue= null;
 		}
 		
@@ -2357,10 +2386,10 @@
 		}
 		
 		@Override
-		public void visit(final FCall node, final boolean assignment) throws InvocationTargetException {
+		public void visit(final FCall node, final boolean assignment, final ImList<RAstNode> inject0ArgValues) throws InvocationTargetException {
 			final SourceElementBuilder containerBuilder= (SourceAnalyzer.this.request == REPRESENTATION_REQUEST) ?
 					getCurrentSourceContainerBuilder(RElement.R_S4CLASS) : null;
-			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef);
+			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef, inject0ArgValues);
 			
 			if (args.ellipsisArgs.length > 0) {
 				final RSourceElementByElementAccess.RClass rClass= (containerBuilder != null) ?
@@ -2409,7 +2438,7 @@
 				}
 			}
 			
-			node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+			visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 			SourceAnalyzer.this.returnValue= null;
 		}
 		
@@ -2424,10 +2453,10 @@
 		}
 		
 		@Override
-		public void visit(final FCall node, final boolean assignment) throws InvocationTargetException {
+		public void visit(final FCall node, final boolean assignment, final ImList<RAstNode> inject0ArgValues) throws InvocationTargetException {
 			final SourceElementBuilder containerBuilder= (SourceAnalyzer.this.request == PROTOTYPE_REQUEST) ?
 					getCurrentSourceContainerBuilder(RElement.R_S4CLASS) : null;
-			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef);
+			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef, inject0ArgValues);
 			
 			if (args.ellipsisArgs.length > 0) {
 //				final RSourceElementByElementAccess.RClass classDef= (containerBuilder != null) ?
@@ -2463,7 +2492,7 @@
 				}
 			}
 			
-			node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+			visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 			SourceAnalyzer.this.returnValue= null;
 		}
 		
@@ -2488,9 +2517,9 @@
 		}
 		
 		@Override
-		public void visit(final FCall node, final boolean assignment) throws InvocationTargetException {
+		public void visit(final FCall node, final boolean assignment, final ImList<RAstNode> inject0ArgValues) throws InvocationTargetException {
 			SourceAnalyzer.this.request= NO_REQUESTS;
-			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef);
+			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef, inject0ArgValues);
 			final RAstNode classNameNode= args.getArgValueNode(this.argIdx_className);
 			final RAstNode cToExtendNameNode= args.getArgValueNode(this.argIdx_classToExtendName);
 			RClassExt rClassExt= null;
@@ -2538,12 +2567,12 @@
 				visitAndCheckValue(args.allocatedArgs[this.argIdx_coerceF], "coerce");
 				visitAndCheckValue(args.allocatedArgs[this.argIdx_replaceF], "replace");
 				
-				node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+				visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 				
 				leaveElement();
 			}
 			else {
-				node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+				visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 			}
 			SourceAnalyzer.this.returnValue= null;
 			return;
@@ -2563,9 +2592,9 @@
 		}
 		
 		@Override
-		public void visit(final FCall node, final boolean assignment) throws InvocationTargetException {
+		public void visit(final FCall node, final boolean assignment, final ImList<RAstNode> inject0ArgValues) throws InvocationTargetException {
 			SourceAnalyzer.this.request= NO_REQUESTS;
-			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef);
+			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef, inject0ArgValues);
 			final RAstNode classNameNode= args.getArgValueNode(this.argIdx_className);
 			
 			if (classNameNode != null && classNameNode.getNodeType() == NodeType.STRING_CONST) {
@@ -2577,7 +2606,7 @@
 				SourceAnalyzer.this.argValueToIgnore.add(classNameNode);
 			}
 			
-			node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+			visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 			SourceAnalyzer.this.returnValue= null;
 			return;
 		}
@@ -2597,9 +2626,9 @@
 		}
 		
 		@Override
-		public void visit(final FCall node, final boolean assignment) throws InvocationTargetException {
+		public void visit(final FCall node, final boolean assignment, final ImList<RAstNode> inject0ArgValues) throws InvocationTargetException {
 			SourceAnalyzer.this.request= NO_REQUESTS;
-			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef);
+			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef, inject0ArgValues);
 			final RAstNode classNameNode= args.getArgValueNode(this.argIdx_className);
 			final RAstNode toClassNode= args.getArgValueNode(this.argIdx_toClass);
 			
@@ -2620,7 +2649,7 @@
 				SourceAnalyzer.this.argValueToIgnore.add(toClassNode);
 			}
 			
-			node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+			visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 			SourceAnalyzer.this.returnValue= null;
 			return;
 		}
@@ -2638,9 +2667,9 @@
 		}
 		
 		@Override
-		public void visit(final FCall node, final boolean assignment) throws InvocationTargetException {
+		public void visit(final FCall node, final boolean assignment, final ImList<RAstNode> inject0ArgValues) throws InvocationTargetException {
 			SourceAnalyzer.this.request= NO_REQUESTS;
-			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef);
+			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef, inject0ArgValues);
 			final RAstNode classNameNode= args.getArgValueNode(this.argIdx_className);
 			
 			if (classNameNode != null && classNameNode.getNodeType() == NodeType.STRING_CONST) {
@@ -2652,7 +2681,7 @@
 				SourceAnalyzer.this.argValueToIgnore.add(classNameNode);
 			}
 			
-			node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+			visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 			SourceAnalyzer.this.returnValue= null;
 			return;
 		}
@@ -2670,9 +2699,9 @@
 		}
 		
 		@Override
-		public final void visit(final FCall node, final boolean assignment) throws InvocationTargetException {
+		public final void visit(final FCall node, final boolean assignment, final ImList<RAstNode> inject0ArgValues) throws InvocationTargetException {
 			SourceAnalyzer.this.request= NO_REQUESTS;
-			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef);
+			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef, inject0ArgValues);
 			final RAstNode classNameNode= args.getArgValueNode(this.argIdx_className);
 			
 			if (classNameNode != null && classNameNode.getNodeType() == NodeType.STRING_CONST) {
@@ -2680,7 +2709,7 @@
 				SourceAnalyzer.this.argValueToIgnore.add(classNameNode);
 			}
 			
-			node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+			visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 			SourceAnalyzer.this.returnValue= null;
 		}
 		
@@ -2741,9 +2770,9 @@
 		}
 		
 		@Override
-		public void visit(final FCall node, final boolean assignment) throws InvocationTargetException {
+		public void visit(final FCall node, final boolean assignment, final ImList<RAstNode> inject0ArgValues) throws InvocationTargetException {
 			SourceAnalyzer.this.request= NO_REQUESTS;
-			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef);
+			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef, inject0ArgValues);
 			final RAstNode fNameValue= args.getArgValueNode(this.argIdx_fName);
 			final RAstNode fDefValue= args.getArgValueNode(this.argIdx_fDef);
 			
@@ -2779,7 +2808,7 @@
 				}
 			}
 			
-			node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+			visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 			SourceAnalyzer.this.returnValue= null;
 		}
 		
@@ -2798,9 +2827,9 @@
 		}
 		
 		@Override
-		public void visit(final FCall node, final boolean assignment) throws InvocationTargetException {
+		public void visit(final FCall node, final boolean assignment, final ImList<RAstNode> inject0ArgValues) throws InvocationTargetException {
 			SourceAnalyzer.this.request= NO_REQUESTS;
-			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef);
+			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef, inject0ArgValues);
 			final RAstNode fNameArg= args.getArgValueNode(this.argIdx_fName);
 			
 			if (fNameArg != null && fNameArg.getNodeType() == NodeType.STRING_CONST) {
@@ -2815,7 +2844,7 @@
 //				this.returnValue= null;
 			}
 			
-			node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+			visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 			SourceAnalyzer.this.returnValue= null;
 		}
 		
@@ -2832,9 +2861,9 @@
 		}
 		
 		@Override
-		public void visit(final FCall node, final boolean assignment) throws InvocationTargetException {
+		public void visit(final FCall node, final boolean assignment, final ImList<RAstNode> inject0ArgValues) throws InvocationTargetException {
 			SourceAnalyzer.this.request= NO_REQUESTS;
-			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef);
+			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef, inject0ArgValues);
 			final RAstNode fNameArg= args.getArgValueNode(this.argIdx_fName);
 			
 			if (fNameArg != null && fNameArg.getNodeType() == NodeType.STRING_CONST) {
@@ -2846,7 +2875,7 @@
 				SourceAnalyzer.this.argValueToIgnore.add(fNameArg);
 			}
 			
-			node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+			visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 			SourceAnalyzer.this.returnValue= null;
 		}
 		
@@ -2863,9 +2892,9 @@
 		}
 		
 		@Override
-		public final void visit(final FCall node, final boolean assignment) throws InvocationTargetException {
+		public final void visit(final FCall node, final boolean assignment, final ImList<RAstNode> inject0ArgValues) throws InvocationTargetException {
 			SourceAnalyzer.this.request= NO_REQUESTS;
-			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef);
+			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef, inject0ArgValues);
 			final RAstNode fNameNode= args.getArgValueNode(this.argIdx_fName);
 			
 			if (fNameNode != null && fNameNode.getNodeType() == NodeType.STRING_CONST) {
@@ -2876,7 +2905,7 @@
 				SourceAnalyzer.this.argValueToIgnore.add(fNameNode);
 			}
 			
-			node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+			visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 			SourceAnalyzer.this.returnValue= null;
 		}
 		
@@ -2928,9 +2957,9 @@
 		}
 		
 		@Override
-		public void visit(final FCall node, final boolean assignment) throws InvocationTargetException {
+		public void visit(final FCall node, final boolean assignment, final ImList<RAstNode> inject0ArgValues) throws InvocationTargetException {
 			SourceAnalyzer.this.request= NO_REQUESTS;
-			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef);
+			final FCallArgMatch args= RAsts.matchArgs(node.getArgsChild(), this.argsDef, inject0ArgValues);
 			final RAstNode objectArg= args.getArgValueNode(this.argIdx_object);
 			final RAstNode slotArg= args.getArgValueNode(this.argIdx_slotName);
 			
@@ -2950,7 +2979,7 @@
 				SourceAnalyzer.this.topScope.addLateResolve(objectArg.getText(), access);
 			}
 			
-			node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+			visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 			SourceAnalyzer.this.returnValue= null;
 		}
 		
@@ -2963,7 +2992,7 @@
 		}
 		
 		@Override
-		public void visit(final FCall node, final boolean assignment) throws InvocationTargetException {
+		public void visit(final FCall node, final boolean assignment, final ImList<RAstNode> inject0ArgValues) throws InvocationTargetException {
 			SourceAnalyzer.this.request= NO_REQUESTS;
 			
 			final FCall.Args args= node.getArgsChild();
@@ -2983,7 +3012,7 @@
 				}
 			}
 			
-			node.getArgsChild().acceptInRChildren(SourceAnalyzer.this);
+			visitFCallArgs(node.getArgsChild(), inject0ArgValues);
 			SourceAnalyzer.this.returnValue= null;
 		}
 		
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 579b32b..21c55f8 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
@@ -722,15 +722,6 @@
 		return matchArgs(fCallNode.getArgsChild(), argsDef, inject0Args);
 	}
 	
-	@Deprecated
-	public static FCallArgMatch matchArgs(final FCall.Args argsNode, final ArgsDefinition argsDef) {
-		final FCall parent= argsNode.getRParent();
-		if (parent != null) {
-			return matchArgs(parent, argsDef);
-		}
-		return matchArgs(argsNode, argsDef, ImCollections.emptyList());
-	}
-	
 	
 	/**
 	 * @return position of the element name, if possible (symbol or strings), otherwise <code>null</code>.