protected override Expression VisitMethodCall(MethodCallExpression node) { if (IsEachOrCurrentCall(node)) { var chain = node; var chainShards = chain.SmashToSmithereens(); int i, l; if (chainShards[0].NodeType == ExpressionType.Call || chainShards[0].NodeType == ExpressionType.Invoke || chainShards[0].NodeType == ExpressionType.Constant) { i = chainShards[0].NodeType == ExpressionType.Call || chainShards[0].NodeType == ExpressionType.Invoke ? 0 : 1; Type subType; var subMaxLevel = new ArraysExtractorVisitor(list, paramTypeMustBeUnique: true).GetArrays(chainShards[i], out subType); if (paramTypeMustBeUnique && rootParamType != null && rootParamType != subType) { throw new InvalidOperationException("Type '" + subType + "' is not valid at this point"); } rootParamType = subType; l = subMaxLevel; } else { if (paramTypeMustBeUnique && rootParamType != null && rootParamType != chainShards[0].Type) { throw new InvalidOperationException("Type '" + chainShards[0].Type + "' is not valid at this point"); } rootParamType = chainShards[0].Type; l = 0; i = 0; } for (++i; i < chainShards.Length; ++i) { if (!IsEachOrCurrentCall(chainShards[i])) { continue; } ++l; if (l > maxLevel) { maxLevel = l; } while (list.Count <= l) { list.Add(new Dictionary <Type, List <Expression> >()); } List <Expression> arrays; if (!list[l].TryGetValue(rootParamType, out arrays)) { list[l].Add(rootParamType, arrays = new List <Expression>()); } arrays.Add(chainShards[i]); } return(node); } return(base.VisitMethodCall(node)); }
private int ProcessFirstShard(Expression shard) { var(level, subType) = new ArraysExtractorVisitor(arrayLevels, paramTypeMustBeUnique: true).GetArrays(shard); SaveParameterType(subType); return(level); }