コード例 #1
0
            public ProcessingContext(Generator.Ctx parent, IReadFiles metaStorage)
            {
                ctxFile = new Generator.Ctx(parent);
                ctxFile.CreateValue(sFileDir);
                ctxFile.CreateValue(sFileName);
                ctxFile.CreateValue(sSheetName);

                var metaFiles = metaStorage.EnumerateFiles("").Where(fn => fn.EndsWith(".src.ini"));

                metas = Metadata.Load(metaStorage, metaFiles, ctxFile).ToArray();

                dictExt2Kind = new Dictionary <string, string>();
                foreach (var m in metas)
                {
                    foreach (var Ext in m.FileNameExtension)
                    {
                        var ext = '.' + Ext.ToLowerInvariant();
                        if (!dictExt2Kind.TryGetValue(ext, out var kind))
                        {
                            dictExt2Kind[ext] = m.FileContentKind;
                        }
                        else if (kind != m.FileContentKind)
                        {
                            throw new Exception($"Can't associate extension '{ext}' with two kinds of content ('{kind}' and '{m.FileContentKind}')");
                        }
                    }
                }
            }
コード例 #2
0
ファイル: Aggregation.cs プロジェクト: WVitek/DotGlue
            public static object AGGR(CallExpr call, Generator.Ctx ctx)
            {
                CallExpr ce;
                {
                    var dict = new Dictionary <string, object>(StringComparer.OrdinalIgnoreCase);
                    ce = Filter.ReplaceValueInfoRefsWithData(call, DataLoader.sData, dict);
                    ctx.CreateValue(DataLoader.sUsedParamsDict, dict);
                }

                var args = new List <Expr>();

                args.Add(CallExpr.let(new ReferenceExpr(sFactory),
                                      new CallExpr(FuncDefs_Solver.SolverWeightedSumsFactory, ce.args[0], new ReferenceExpr(sTimeA), new ReferenceExpr(sTimeB))));
                args.Add(CallExpr.let(new ReferenceExpr(sWithKey), ce.args[1]));

                for (int i = 2; i < ce.args.Count; i++)
                {
                    args.Add(ce.args[i]);
                }
                var exprAgg = CallExpr.Eval(args.ToArray());

                var expr = new CallExpr(FuncDefs_Solver.SolverTimedObjects,
                                        new CallExpr((Fx)FuncDefs_Solver.SolverWeightedSumsFactoryTimes, new ReferenceExpr(sFactory)), exprAgg);

                return(Generator.Generate(expr, ctx));
            }
コード例 #3
0
        public static object WRptGenerateReportExpr(CallExpr ce, Generator.Ctx callerCtx)//(object tmplFileName, Expr outputFilesExpr)
        {
            var ctx = new Generator.Ctx(callerCtx);

            ctx.CreateValue(FuncDefs_Core.stateTryGetConst, string.Empty);
            var templateFileName = Convert.ToString(Generator.Generate(ce.args[0], ctx));
            var outputFilesExpr  = ce.args[1];
            var sheetExprs       = new List <Expr>();
            int iSheet           = 0;
            int blockNum         = 0;

            var xr = new Xlsx.Reader(templateFileName);

            var lstStrTbl = new OPs.ListOfConst(xr.stringTable);

            ctx.CreateValue(XlsxR.Sheet.sStrTbl, lstStrTbl);

            foreach (var s in xr.EnumSheetInfos())
            {
                var cells     = new XlsxR.Sheet(s.sheetCells.ToArray(), xr.styles);
                var sheetExpr = cells.GetSheetExpr(s.sheetFile, ctx, outputFilesExpr, ref blockNum);
                sheetExprs.Add(new CallExpr(FuncDefs_Core._block,
                                            sheetExpr,
                                            XlsxR.PROGRESS("sheet", new ConstExpr(xr.sheetNames[iSheet]))
                                            ));
                iSheet++;
            }
            ;

            var loopRef = new ReferenceExpr("sheet");

            var res = CallExpr.Eval(
                CallExpr.let(new ConstExpr(XlsxR.Sheet.sTmplFiles), new ConstExpr(xr.xmlFiles)),
                CallExpr.let(new ConstExpr(XlsxR.Sheet.sStrTbl), new ConstExpr(lstStrTbl)),
                XlsxR.PROGRESS("sheets", new ConstExpr(new OPs.ListOfConst(xr.sheetNames))),
                new CallExpr(FuncDefs_Core._ForEach, loopRef, new ArrayExpr(sheetExprs), loopRef),
                new CallExpr((Fxy)WRptCopyFiles, new ConstExpr(xr.xmlFiles), outputFilesExpr),
                new CallExpr((Fx)WRptWriterDone, outputFilesExpr)
                );

            return(res);
        }
コード例 #4
0
ファイル: Aggregation.cs プロジェクト: WVitek/DotGlue
            public Task LoadData(AsyncExprCtx rootAec, Expr loadingExpr, CancellationToken ct)
            {
                int i = aggCtx.IndexOf(sFactory);

                if (i >= 0)
                {
                    var f = (WeightedSums.Factory)aggCtx[i];
                    foreach (var n2i in aggCtx.name2ndx)
                    {
                        if (n2i.Key.StartsWith(sAkk))
                        {
                            aggCtx[n2i.Value] = f.NewSums();
                        }
                    }
                }
                var loadingCtx = new Generator.Ctx(aggCtx.parent);

                loadingCtx.CreateValue(sUsedParamsDict, aggCtx[aggCtx.IndexOf(sUsedParamsDict)]);
                loadingCtx.CreateValue(sLoadingInfo, this);
                var loadingCode = Generator.Generate(loadingExpr, loadingCtx);
                var ae          = new AsyncExprCtx(loadingCtx, loadingCtx.values, rootAec);

                return(OPs.ConstValueOf(ae, loadingCode));
            }
コード例 #5
0
ファイル: Aggregation.cs プロジェクト: WVitek/DotGlue
            public static object AGGR(CallExpr call, Generator.Ctx ctx)
            {
                var dictUsedValues = new Dictionary <string, object>(StringComparer.OrdinalIgnoreCase);
                //var timeSpanExpr = ce.args[0];

                var ce = Filter.ReplaceValueInfoRefsWithData(call, DataLoader.sData, dictUsedValues);

                ctx.CreateValue(DataLoader.sUsedParamsDict, dictUsedValues);
                var expr = new CallExpr(FuncDefs_Solver.SolverTimedObjects,
                                        new CallExpr((Fx)FuncDefs_Solver.SolverTimesOfIDicts, new ReferenceExpr(DataLoader.sData)),
                                        ce.args[ce.args.Count - 1]
                                        );

                return(Generator.Generate(expr, ctx));
            }
コード例 #6
0
 public static IEnumerable <Metadata> Load(IReadFiles storage, IEnumerable <string> files, Generator.Ctx parent)
 {
     foreach (var fname in files)
     {
         using (var stream = storage.OpenReadFile(fname))
             using (var reader = new StreamReader(stream))
             {
                 var ctx = new Generator.Ctx(parent);
                 ctx.CreateValue(sMetadataFile, fname);
                 foreach (var m in Metadata.Create(reader, ctx))
                 {
                     yield return(m);
                 }
             }
     }
 }
コード例 #7
0
        public static object WRptExploreDependencies(CallExpr ce, Generator.Ctx callerCtx)//(object tmplFileName, string[] forCells)
        {
            var ctx = new Generator.Ctx(callerCtx);

            ctx.CreateValue(FuncDefs_Core.stateTryGetConst, string.Empty);
            var templateFileName = Convert.ToString(Generator.Generate(ce.args[0], ctx));
            var sheets           = new Dictionary <string, XlsxR.Sheet>();

            var xr = new Xlsx.Reader(templateFileName);

            foreach (var s in xr.EnumSheetInfos())
            {
                sheets.Add(s.sheetName, new XlsxR.Sheet(s.sheetCells.ToArray(), xr.styles));
            }

            var forCells = Utils.AsIList(Generator.Generate(ce.args[1], ctx))
                           .Cast <object>()
                           .Select(o => Convert.ToString(o))
                           .ToArray();

            var code = DepsHelper.DumpDeps(ctx, sheets, xr.stringTable, forCells);

            return(code);
        }
コード例 #8
0
            private Metadata(IEnumerable <NE> exprsHdr, IEnumerable <NE> exprsRow, IEnumerable <NE> exprsRes, Generator.Ctx parentCtx)
            {
                var sb = new StringBuilder();

                FixSheetExpr = Expr.RecursiveModifier(FixSheetImpl);
                FixRowExpr   = Expr.RecursiveModifier(FixRowImpl);

                #region generate header code
                ctxHdr = new Generator.Ctx(parentCtx);
                ctxHdr.CreateValue(HdrCellsRef.name, Generator.LazyDummy);
                ctxHdr.CreateValue(PrevValsRef.name, Generator.LazyDummy);

                foreach (var p in exprsHdr)
                {
                    FCurrName = p.name;
                    var expr = FixSheetExpr(p.expr);
                    var val  = Generator.Generate(expr, ctxHdr);
                    ctxHdr.CreateValue(p.name, val);
                    if (OPs.KindOf(val) == ValueKind.Const)
                    {
                        expr = new ConstExpr(val);
                    }
                    sb.AppendLine($"{p.name} = {expr}");
                }
                sb.AppendLine();

                RequiredInHdr(sSourceKey);
                RequiredInHdr(sSourceName);
                RequiredInHdr(sCondition);
                RequiredInHdr(sFirstDataRowNum);

                {
                    if (ctxHdr.name2ndx.TryGetValue(sFileContentKind, out int i))
                    {
                        FileContentKind = Convert.ToString(ctxHdr.GetConstant(sFileContentKind));
                    }
                    else
                    {
                        FileContentKind = "XLSX";
                    }
                }
                {
                    if (ctxHdr.name2ndx.TryGetValue(sFileNameExtension, out int i))
                    {
                        var val = ctxHdr.GetConstant(sFileNameExtension);
                        FileNameExtension = Utils.AsIList(val).Cast <object>().Select(Convert.ToString).ToArray();
                    }
                    else
                    {
                        FileNameExtension = new string[] { "xls", "xlsx", "xlsm" }
                    };
                }
                #endregion

                #region generate row code
                ctxRow = new Generator.Ctx(ctxHdr);
                ctxRow.CreateValue(sDataKey, Generator.LazyDummy);         // [0] - iKey
                ctxRow.CreateValue(sDataSubkey, Generator.LazyDummy);      // [1] - iSubkey
                ctxRow.CreateValue(CellValsRef.name, Generator.LazyDummy); // [2] - iRowVals

                foreach (var p in exprsRow)
                {
                    string name;
                    if (p.name.StartsWith("~"))
                    {
                        // calculated name
                        name = OPs.TryAsString(Parser.ParseToExpr(p.name.Substring(1)), ctxHdr) ?? p.name;
                    }
                    else
                    {
                        name = p.name;
                    }
                    FCurrName = name;
                    int i    = ctxRow.GetOrCreateIndexOf(name);
                    var expr = FixRowExpr(p.expr);
                    var val  = Generator.Generate(expr, ctxRow);
                    ctxRow.values[i] = val;
                    if (OPs.KindOf(val) == ValueKind.Const)
                    {
                        expr = new ConstExpr(val);
                    }
                    sb.AppendLine($"{name} = {expr}");
                }

                RequiredInRow(sDataKey);
                RequiredInRow(sDataSubkey);

                ctxRow.values[iRowVals] = null;
                ctxRow.CheckUndefinedValues();

                #endregion

                #region generate res code
                if (exprsRes != null)
                {
                    // copy all code from row to res
                    ctxRes = new Generator.Ctx(ctxHdr);
                    foreach (var p in ctxRow.name2ndx.OrderBy(p => p.Value))
                    {
                        ctxRes.values[ctxRes.CreateValue(p.Key)] = ctxRow.values[p.Value];
                    }

                    foreach (var p in exprsRes)
                    {
                        string name;
                        if (p.name.StartsWith("~"))
                        {
                            // calculated name
                            name = OPs.TryAsString(Parser.ParseToExpr(p.name.Substring(1)), ctxHdr) ?? p.name;
                        }
                        else
                        {
                            name = p.name;
                        }
                        FCurrName = name;
                        int i    = ctxRes.GetOrCreateIndexOf(name);
                        var expr = FixRowExpr(p.expr);
                        var val  = Generator.Generate(expr, ctxRes);
                        ctxRes.values[i] = val;
                        if (OPs.KindOf(val) == ValueKind.Const)
                        {
                            expr = new ConstExpr(val);
                        }
                    }
                    ctxRes.values[iRowVals] = null;
                    ctxRes.CheckUndefinedValues();
                }
                #endregion

                ctxHdr[HdrCellsRef.name] = null;
                ctxHdr[PrevValsRef.name] = null;
                ctxHdr.CheckUndefinedValues();

                FCodeText = sb.ToString();

                if (iHdrMinUsedRow > iHdrMaxUsedRow)
                {
                    iHdrMinUsedRow = iHdrMaxUsedRow;
                }
            }
コード例 #9
0
            public static IEnumerable <Metadata> Create(TextReader txt, Generator.Ctx ctxParent)
            {
                var       exprsHdr      = new List <NE>();
                var       exprsRow      = new List <NE>();
                List <NE> exprsRes      = null;
                string    tmplParamName = null;

                bool withFileContentKind   = false;
                bool withFileNameExtension = false;

                foreach (var(Section, Key, Value) in Ini.Read(txt, true))
                {
                    var       expr     = Parser.ParseToExpr(Value);
                    List <NE> exprsLst = null;
                    switch (Section)
                    {
                    case sHdr:
                        if (Key.StartsWith(sTemplateParameterValuesPrefix))
                        {
                            if (tmplParamName != null)
                            {
                                throw new Exception($"Template parameter already defined as '{tmplParamName}'");
                            }
                            tmplParamName = Key;
                        }
                        else
                        {
                            switch (Key)
                            {
                            case sFileContentKind: withFileContentKind = true; break;

                            case sFileNameExtension: withFileNameExtension = true; break;
                            }
                        }
                        exprsLst = exprsHdr;
                        break;

                    case sRow:
                        exprsLst = exprsRow; break;

                    case sRes:
                        if (exprsRes == null)
                        {
                            exprsRes = new List <NE>();
                        }
                        exprsLst = exprsRes;
                        break;

                    default:
                        throw new Exception($"Unknown section '{Section}' in source metadata. Expected '{sHdr}' or '{sRow}' sections.");
                    }
                    exprsLst.Add(new NE(Key ?? $".{exprsLst.Count}", expr));
                }

                if (withFileContentKind && !withFileNameExtension)
                {
                    throw new Exception($"{ctxParent.GetConstant(sMetadataFile)} : specified FileContentKind also requires FileNameExtension specification");
                }


                if (tmplParamName != null)
                {
                    var    ctx      = new Generator.Ctx(ctxParent);
                    object tmplVals = null;
                    Expr   tmplExpr = null;
                    for (int i = 0; i < exprsHdr.Count; i++)
                    {
                        var p   = exprsHdr[i];
                        var val = Generator.Generate(p.expr, ctx);
                        if (p.name == tmplParamName)
                        {
                            tmplVals = val;
                            exprsHdr.RemoveAt(i);
                            break;
                        }
                        ctx.CreateValue(p.name, val);
                    }
                    var tmplParamVals = tmplVals as IList;
                    if (OPs.KindOf(tmplVals) != ValueKind.Const || tmplParamVals == null)
                    {
                        throw new Exception($"Can't interpret template parameter as list of constants //{tmplParamName}={tmplExpr}={tmplVals}");
                    }
                    tmplParamName = tmplParamName.Substring(sTemplateParameterValuesPrefix.Length);
                    foreach (var tmplVal in tmplParamVals)
                    {
                        exprsHdr.Insert(0, new NE(tmplParamName, new ConstExpr(tmplVal)));
                        yield return(new Metadata(exprsHdr, exprsRow, exprsRes, ctxParent));

                        exprsHdr.RemoveAt(0);
                    }
                }
                else
                {
                    yield return(new Metadata(exprsHdr, exprsRow, exprsRes, ctxParent));
                }
            }
コード例 #10
0
        public static object Filtering(Generator.Ctx ctx, string inputParam, string sourceData, IList <Expr> filterConditions, string[] outputParams)
        {
            var aliasOf = FuncDefs_Solver.GetAliases(ctx);

            // количество стадий = количество условий фильтрации + 1 стадия подготовки выходных данных
            int nStages = filterConditions.Count + 1;

            // для каждой стадии перечень параметров, необходимых для её обработки
            var stage = new StageInfo[nStages];

            // перечень всех параметров всех стадий
            var usedParamsDict = new Dictionary <string, bool>(StringComparer.OrdinalIgnoreCase);

            #region Определяем используемые на стадиях обработки данных показатели (стадии фильтрации + стадия подготовки выходных данных)

            // проход по стадиям фильтрации с формированием перечней используемых параметров
            for (int i = 0; i < nStages - 1; i++)
            {
                var prmsDict = new Dictionary <string, bool>(StringComparer.OrdinalIgnoreCase);
                foreach (var paramName in filterConditions[i].EnumerateReferences().Where(ValueInfo.IsDescriptor))
                {
                    prmsDict[aliasOf.GetRealName(paramName)] = true;
                }
                var ownParams = prmsDict.Keys.ToArray <string>();
                stage[i].ownParams = ownParams;
                stage[i].Cond      = filterConditions[i];
                foreach (var s in ownParams)
                {
                    usedParamsDict[aliasOf.GetRealName(s)] = true;
                }
            }

            string[] outputParamsRealNames = outputParams.Select(s => aliasOf.GetRealName(s)).ToArray();

            // стадия выходных данных
            stage[nStages - 1].ownParams = outputParamsRealNames;
            foreach (var s in outputParamsRealNames)
            {
                usedParamsDict[s] = true;
            }
            #endregion

            // справочник "параметр -> оценка сложности"
            var funcComplexity = new Dictionary <string, int>();

            //// справочник "параметр -> влияющие на него параметры"
            //IDictionary<string, string[]> dependencies;

            // справочник "параметр -> имя вычисляющей его функции"
            IDictionary <string, string> param2func;

            // справочник "функция -> входы / выходы"
            var funcInpsOuts = new Dictionary <string, Tuple <string[], List <string> > >();

            #region Определяем зависимости и "сложность" параметров
            {
                var localCtx = new Generator.Ctx(ctx);
                localCtx.GetOrCreateIndexOf(FuncDefs_Solver.optionSolverDependencies);
                var res = Generator.Generate(
                    // вызываем функцию поиска решения,
                    // которая при наличии optionSolverDependencies возвращает также справочник зависимостей
                    new CallExpr(FuncDefs_Solver.FindSolutionExpr
                                 // перечень дополнительных входных параметров (которые в месте этого вызова не определены)
                                 , new ArrayExpr(new ConstExpr(inputParam))
                                 // перечень выходных параметров, решение для которых (последовательность вызовов известных функций) надо найти
                                 , new ArrayExpr(usedParamsDict.Keys.Select(s => new ConstExpr(s)).ToArray())
                                 )
                    // контекст кодогенератора для поиска решения (содержит перечень имён известных значений и описаний функций)
                    , localCtx
                    );
                var deps = (IDictionary <string, object>)localCtx.values[localCtx.IndexOf(FuncDefs_Solver.optionSolverDependencies)];

                //dependencies = deps.ToDictionary(p => p.Key, p => (p.Value == null) ? new string[0] : ((IList)p.Value).Cast<string>().Where(s => !s.StartsWith("#")).ToArray());
                param2func = deps.ToDictionary(
                    p => p.Key,
                    p => (p.Value == null) ? string.Empty
                        : ((IList)p.Value).Cast <string>().Where(s => s.StartsWith(FuncDefs_Solver.sDepsFuncNamePrefix)).First()
                    ,
                    StringComparer.OrdinalIgnoreCase
                    );

                foreach (var d in deps)
                {
                    var prm       = d.Key;
                    var arguments = (IList)d.Value;
                    if (arguments == null)
                    {
                        arguments = new string[] { string.Empty }
                    }
                    ;
                    Tuple <string[], List <string> > fInpsOuts;
                    var sFunc = arguments[0].ToString();
                    if (!funcInpsOuts.TryGetValue(sFunc, out fInpsOuts))
                    {
                        var inpFuncs = arguments.Cast <string>()
                                       .Skip(1)                    // first arg is function name
                                       .Select(s => param2func[s]) // get function name by her output parameter name
                                       .Where(f => f != null)
                                       .Distinct().ToArray();
                        fInpsOuts           = new Tuple <string[], List <string> >(inpFuncs, new List <string>());
                        funcInpsOuts[sFunc] = fInpsOuts;
                    }
                    fInpsOuts.Item2.Add(prm);
                }

                var lstAllFuncs = funcInpsOuts.Keys.ToList();

                bool someToDo = true;
                while (someToDo)
                {
                    someToDo = false;
                    for (int i = lstAllFuncs.Count - 1; i >= 0; --i)
                    {
                        var func = lstAllFuncs[i];
                        int cmpl = 0;
                        foreach (var s in funcInpsOuts[func].Item1)
                        {
                            int c;
                            if (!funcComplexity.TryGetValue(s, out c))
                            {
                                cmpl = -1; break;
                            }
                            else
                            {
                                cmpl += c;
                            }
                        }
                        if (cmpl >= 0)
                        {
                            funcComplexity.Add(func, cmpl + 1);
                            lstAllFuncs.RemoveAt(i);
                            someToDo = true;
                        }
                    }
                }
                System.Diagnostics.Trace.Assert(lstAllFuncs.Count == 0, "Filtering: lstAllFuncs.Count == 0");
            }
            #endregion


            {   // сортировка стадий по возрастанию "сложности" параметров
                int[] reorder = Enumerable.Range(0, nStages - 1)
                                .OrderBy(i => (stage[i].ownParams.Length == 0)
                        ? 0
                        : stage[i].ownParams.Select(s => param2func[s]).Distinct().Select(f => funcComplexity[f]).Sum())
                                .Concat(new int[] { nStages - 1 })
                                .ToArray();
                Array.Sort(reorder, stage);
            }

            #region Проход по стадиям
            {
#if SAFE_PARALLELIZATION
                bool inParallel = ctx.IndexOf(FuncDefs_Core.stateParallelizationAlreadyInvolved) < 0;
#else
                const bool inParallel = true;
#endif
                if (ctx.IndexOf(FuncDefs_Core.optionMinPartSize) < 0)
                {
                    ctx.CreateValue(FuncDefs_Core.optionMinPartSize, defaultMinPartSize);
                }

                if (ctx.IndexOf(FuncDefs_Core.optionMaxPartSize) < 0)
                {
                    ctx.CreateValue(FuncDefs_Core.optionMaxPartSize, defaultMaxPartSize);
                }

                var readyFuncs = new Dictionary <string, bool>();
                readyFuncs.Add(string.Empty, true);
                var prevDataName     = sourceData;
                var interstageParams = new string[] { inputParam };
                var lstStages        = new List <StageInfo>(stage);
                var readyStages      = new List <StageInfo>();
                var mergedStagesCode = new List <string>();
                int iMergedStage     = 0;
                while (lstStages.Count > 0 || readyStages.Count > 0)
                {
                    for (int i = lstStages.Count - 1; i >= 0; i--)
                    {
                        if (lstStages[i].ownParams.All(prm => readyFuncs.ContainsKey(param2func[prm])))
                        {
                            readyStages.Add(lstStages[i]);
                            lstStages.RemoveAt(i);
                        }
                    }
                    if (readyStages.Count > 0)
                    {
                        var conds = readyStages.Select(stg => stg.Cond)
                                    .Where(cond => cond != null)
                                    .OrderBy(cond => cond.Traverse(e => (e is CallExpr || e is ReferenceExpr) ? 1 : 0).Sum())
                                    .ToArray();
                        bool lastStage = conds.Length == 0;
                        Dictionary <string, bool> flowOfParams = readyStages.Concat(lstStages).SelectMany(si => si.ownParams).Distinct()
                                                                 .ToDictionary(s => s, s => true, StringComparer.OrdinalIgnoreCase);
                        var ownParamsFuncs = readyStages
                                             .SelectMany(stg => stg.ownParams.Select(prm => param2func[prm])
                                                         .Where(func => !readyFuncs.ContainsKey(func)))
                                             .Distinct().ToArray();
                        var paramsToGetEnum =
                            // все выходные параметры готовых функций (источников данных)
                            readyFuncs.Keys.SelectMany(f => funcInpsOuts[f].Item2).Distinct()
                            // оставляем только те, что нужны на этой и последующих стадиях, а также ID
                            .Where(s => s.EndsWith("_ID") || s.Contains("_ID_") || flowOfParams.ContainsKey(s))
                            //// показатели оставляем в той форме, которая запрошена (например, в списке есть LIQUID_WATERCUT_OISP и его алиас LIQUID_WATERCUT, а запрошен именно LIQUID_WATERCUT)
                            //.Select(s => aliasOf.AsIn(flowOfParams, s))
                        ;
                        //if (lastStage)
                        paramsToGetEnum = paramsToGetEnum.Distinct();
                        //else
                        //	paramsToGetEnum = paramsToGetEnum.Distinct(aliasOf);
                        var paramsToGet = paramsToGetEnum.ToArray();
                        var condExpr    = lastStage ? null : (conds.Length == 1) ? conds[0] : new CallExpr("AND", conds);
                        var code        = GetConditionStageText(prevDataName,
                                                                lastStage ? interstageParams : interstageParams.Distinct(),
                                                                paramsToGet, condExpr, (iMergedStage == 0), inParallel);
                        prevDataName = "stgRows_" + iMergedStage.ToString();
                        code         = string.Format("{0}\r\n..let({1}),", code, prevDataName);
                        if (lastStage)
                        {
                            code += string.Format("\r\nPROGRESS('FilteringItemsList',{0}),\r\n", prevDataName);
                        }
                        mergedStagesCode.Add(code);
                        iMergedStage++;
                        interstageParams = paramsToGet.Distinct().ToArray();
                        readyStages.Clear();
                    }
                    else
                    {
                        var stg = lstStages[0];
                        lstStages.RemoveAt(0);
                        readyStages.Add(stg);
                        AllSrcFuncs(
                            stg.ownParams.Select(prm => param2func[prm]).Where(func => !readyFuncs.ContainsKey(func)).Distinct()
                            , funcInpsOuts, readyFuncs);
                    }
                }
                var sbCode = new StringBuilder();
                sbCode.AppendLine("(");
                sbCode.AppendFormat("PROGRESS('FilteringStagesCount',{0}),", mergedStagesCode.Count);
                sbCode.AppendLine();
                foreach (var code in mergedStagesCode)
                {
                    sbCode.AppendLine(code);
                }
                sbCode.AppendFormat("PROGRESS('FilteringComplete',{0}.COLUMNS()),", prevDataName);
                sbCode.AppendLine();
                sbCode.AppendLine(prevDataName);
                sbCode.AppendLine(")");
                var sCode = sbCode.ToString();
                return(Parser.ParseToExpr(sCode));
            }
            #endregion
        }