Ejemplo n.º 1
0
        public static PHP.Core.AST.DirectFcnCall.EvaluateInfo CreateFunction_Analyze(
            Analyzer analyzer,
            PHP.Core.AST.CallSignature callSignature,
            string args, string body)
        {
            if (analyzer.IsInsideIncompleteClass())
            {
                return(null);  // in this case, the DirectFnCall will not be Emitted. Therefore the lambda routine will not be declared and compilation will fail when emitting not fully declared lambda FunctionDecl.
            }
            // has to be a valid identifier:
            // actually this name is never used then
            string function_name = "__" + Guid.NewGuid().ToString().Replace('-', '_'); //DynamicCode.GenerateLambdaName(args, body);

            string prefix1, prefix2;

            DynamicCode.GetLamdaFunctionCodePrefixes(function_name, args, out prefix1, out prefix2);

            PHP.Core.Parsers.Position pos_args = callSignature.Parameters[0].Position;
            PHP.Core.Parsers.Position pos_body = callSignature.Parameters[1].Position;

            // function __XXXXXX(<args>){<fill><body>}
            string fill = GetInlinedLambdaCodeFill(pos_args, pos_body);
            string code = String.Concat(prefix2, fill, body, "}");

            // the position of the first character of the parsed code:
            // (note that escaped characters distort position a little bit, which cannot be eliminated so easily)
            PHP.Core.Parsers.Position pos = PHP.Core.Parsers.Position.Initial;
            pos.FirstOffset = pos_args.FirstOffset - prefix1.Length + 1;
            pos.FirstColumn = pos_args.FirstColumn - prefix1.Length + 1;
            pos.FirstLine   = pos_args.FirstLine;

            // parses function source code:
            var counter = new PHP.Core.Parsers.Parser.ReductionsCounter();
            var ast     = analyzer.BuildAst(pos, code, counter);

            if (ast == null || ast.Statements == null)
            {
                return(null);   // the function cannot be parsed
            }
            Debug.Assert(counter.FunctionCount == 1);

            var decl_node = (PHP.Core.AST.FunctionDecl)ast.Statements[0];

            // adds declaration to the end of the global code statement list:
            analyzer.AddLambdaFcnDeclaration(decl_node);

            //
            return(new PHP.Core.AST.DirectFcnCall.EvaluateInfo()
            {
                //.inlined = InlinedFunction.CreateFunction;
                emitDeclareLamdaFunction = true,

                // modify declaration:
                newRoutine = decl_node.ConvertToLambda(analyzer),
            });
        }