示例#1
0
        public static IEnumerable <Diagnostic> BindAndAnalyze(PhpCompilation compilation, CancellationToken cancellationToken)
        {
            var manager = compilation.GetBoundReferenceManager();   // ensure the references are resolved! (binds ReferenceManager)

            var diagnostics = new DiagnosticBag();
            var compiler    = new SourceCompiler(compilation, null, true, diagnostics, cancellationToken);

            using (compilation.StartMetric("bind"))
            {
                // 1. Bind Syntax & Symbols to Operations (CFG)
                //   a. construct CFG, bind AST to Operation
                //   b. declare table of local variables
                compiler.WalkMethods(compiler.EnqueueRoutine, allowParallel: true);
                compiler.WalkTypes(compiler.EnqueueType, allowParallel: true);
            }

            // Repeat analysis and transformation until either the limit is met or there are no more changes
            int transformation = 0;

            do
            {
                using (compilation.StartMetric("analysis"))
                {
                    // 2. Analyze Operations
                    //   a. type analysis (converge type - mask), resolve symbols
                    //   b. lower semantics, update bound tree, repeat
                    compiler.AnalyzeMethods();
                }

                using (compilation.StartMetric("bind types"))
                {
                    // 3. Resolve operators and types
                    compiler.BindTypes();
                }

                using (compilation.StartMetric(nameof(ForwardLateStaticBindings)))
                {
                    // 4. forward the late static type if needed
                    compiler.ForwardLateStaticBindings();
                }

                // 5. Transform Semantic Trees for Runtime Optimization
            } while (
                transformation++ < compiler.MaxTransformCount && // limit number of lowering cycles
                !cancellationToken.IsCancellationRequested &&    // user canceled ?
                compiler.RewriteMethods());                      // try lower the semantics

            // Track the number of actually performed transformations
            compilation.TrackMetric("transformations", transformation - 1);

            using (compilation.StartMetric("diagnostic"))
            {
                // 6. Collect diagnostics
                compiler.DiagnoseMethods();
                compiler.DiagnoseTypes();
                compiler.DiagnoseFiles();
            }

            //
            return(diagnostics.AsEnumerable());
        }