public void Analyze(Engine engine)
        {
            HasDynamicReturns = false;

            if (!(MapFunc is ScriptFunctionInstance sfi))
            {
                return;
            }

            var theFuncAst = sfi.GetFunctionAst();

            var res = CheckIfSimpleMapExpression(engine, theFuncAst);

            if (res != null)
            {
                MapFunc    = res.Value.Function;
                theFuncAst = res.Value.FunctionAst;
            }
            var loadSearcher = new EsprimaReferencedCollectionVisitor();

            loadSearcher.VisitFunctionExpression(theFuncAst);
            ReferencedCollections.UnionWith(loadSearcher.ReferencedCollection);

            foreach (var returnStatement in JavaScriptIndexUtils.GetReturnStatements(theFuncAst.Body))
            {
                if (returnStatement.Argument == null) // return;
                {
                    continue;
                }

                if (!(returnStatement.Argument is ObjectExpression oe))
                {
                    HasDynamicReturns = true;
                    continue;
                }
                //If we got here we must validate that all return statements have the same structure.
                //Having zero fields means its the first return statements we encounter that has a structure.
                if (Fields.Count == 0)
                {
                    foreach (var prop in oe.Properties)
                    {
                        var fieldName = prop.Key.GetKey();
                        if (fieldName == "_")
                        {
                            HasDynamicReturns = true;
                        }

                        Fields.Add(fieldName);
                    }
                }
                else if (CompareFields(oe) == false)
                {
                    throw new InvalidOperationException($"Index {IndexName} contains different return structure from different code paths," +
                                                        $" expected properties: {string.Join(", ", Fields)} but also got:{string.Join(", ", oe.Properties.Select(x => x.Key.GetKey()))}");
                }
            }
        }
Esempio n. 2
0
        public void Analyze(Engine engine)
        {
            HasDynamicReturns = false;
            HasBoostedFields  = false;

            IFunction theFuncAst;

            switch (MapFunc)
            {
            case ArrowFunctionInstance afi:
                theFuncAst = afi.FunctionDeclaration;
                break;

            case ScriptFunctionInstance sfi:
                theFuncAst = sfi.FunctionDeclaration;
                break;

            default:
                return;
            }

            var res = CheckIfSimpleMapExpression(engine, theFuncAst);

            if (res != null)
            {
                MapFunc    = res.Value.Function;
                theFuncAst = res.Value.FunctionAst;
            }

            foreach (var returnStatement in JavaScriptIndexUtils.GetReturnStatements(theFuncAst))
            {
                if (returnStatement.Argument == null) // return;
                {
                    continue;
                }

                switch (returnStatement.Argument)
                {
                case ObjectExpression oe:

                    //If we got here we must validate that all return statements have the same structure.
                    //Having zero fields means its the first return statements we encounter that has a structure.
                    if (Fields.Count == 0)
                    {
                        foreach (var prop in oe.Properties)
                        {
                            if (prop is Property property)
                            {
                                var fieldName         = property.GetKey(engine);
                                var fieldNameAsString = fieldName.AsString();
                                if (fieldName == "_")
                                {
                                    HasDynamicReturns = true;
                                }

                                Fields.Add(fieldNameAsString);

                                var fieldValue = property.Value;
                                if (IsBoostExpression(fieldValue))
                                {
                                    HasBoostedFields = true;
                                }
                            }
                        }
                    }
                    else if (CompareFields(oe) == false)
                    {
                        throw new InvalidOperationException($"Index {IndexName} contains different return structure from different code paths," +
                                                            $" expected properties: {string.Join(", ", Fields)} but also got:{string.Join(", ", oe.Properties.Select(x => x.GetKey(engine)))}");
                    }

                    break;

                case CallExpression ce:

                    if (IsBoostExpression(ce))
                    {
                        HasBoostedFields = true;
                    }
                    else
                    {
                        HasDynamicReturns = true;
                    }

                    break;

                default:
                    HasDynamicReturns = true;
                    break;
                }
            }