Performs compilation of all source methods.
示例#1
0
        public static void CompileSources(
            PhpCompilation compilation,
            PEModuleBuilder moduleBuilder,
            bool emittingPdb,
            bool hasDeclarationErrors,
            DiagnosticBag diagnostics,
            CancellationToken cancellationToken)
        {
            Debug.Assert(moduleBuilder != null);

            // ensure flow analysis and collect diagnostics
            var declarationDiagnostics = compilation.GetDeclarationDiagnostics(cancellationToken);

            diagnostics.AddRange(declarationDiagnostics);

            // cancel the operation if there are errors
            if (hasDeclarationErrors |= declarationDiagnostics.HasAnyErrors() || cancellationToken.IsCancellationRequested)
            {
                return;
            }

            //
            var compiler = new SourceCompiler(compilation, moduleBuilder, emittingPdb, diagnostics, cancellationToken);

            // Emit method bodies
            //   a. declared routines
            //   b. synthesized symbols
            compiler.EmitMethodBodies();
            compiler.EmitSynthesized();
            compiler.CompileReflectionEnumerators();

            // Entry Point (.exe)
            compiler.CompileEntryPoint();
        }
示例#2
0
        public static IEnumerable <Diagnostic> BindAndAnalyze(PhpCompilation compilation)
        {
            var manager = compilation.GetBoundReferenceManager();   // ensure the references are resolved! (binds ReferenceManager)

            var diagnostics = new DiagnosticBag();
            var compiler    = new SourceCompiler(compilation, null, true, diagnostics, CancellationToken.None);

            CompilerLogSource.Log.StartPhase(CompilationPhase.Bind.ToString());

            // 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.EnqueueFieldsInitializer, allowParallel: true);

            CompilerLogSource.Log.StartPhase(CompilationPhase.Analyse.ToString());

            // 2. Analyze Operations
            //   a. type analysis (converge type - mask), resolve symbols
            //   b. lower semantics, update bound tree, repeat
            //   c. collect diagnostics
            compiler.AnalyzeMethods();
            compiler.DiagnoseMethods();
            compiler.DiagnoseTypes();
            compiler.DiagnoseFiles();

            CompilerLogSource.Log.EndPhase();

            //
            return(diagnostics.AsEnumerable());
        }
示例#3
0
        public static void CompileSources(
            PhpCompilation compilation,
            PEModuleBuilder moduleBuilder,
            bool emittingPdb,
            bool hasDeclarationErrors,
            DiagnosticBag diagnostics,
            CancellationToken cancellationToken)
        {
            var compiler = new SourceCompiler(compilation, moduleBuilder, emittingPdb, diagnostics);

            // 1.Bind Syntax & Symbols to Operations (CFG)
            //   a.equivalent to building CFG
            //   b.most generic types(and empty type - mask)
            compiler.WalkMethods(compiler.EnqueueRoutine);
            compiler.WalkTypes(compiler.EnqueueFieldsInitializer);

            // 2.Analyze Operations
            //   a.declared variables
            //   b.build global variables/constants table
            //   c.type analysis(converge type - mask), resolve symbols
            //   d.lower semantics, update bound tree, repeat
            compiler.AnalyzeMethods();

            // 3. Emit method bodies
            //   a. declared routines
            //   b. synthesized symbols
            compiler.EmitMethodBodies();
            compiler.EmitSynthesized();
            compiler.CompileReflectionEnumerators(cancellationToken);

            // 4. Entry Point (.exe)
            compiler.CompileEntryPoint(cancellationToken);
        }
示例#4
0
        public static void CompileSources(
            PhpCompilation compilation,
            PEModuleBuilder moduleBuilder,
            bool emittingPdb,
            bool hasDeclarationErrors,
            DiagnosticBag diagnostics,
            CancellationToken cancellationToken)
        {
            Debug.Assert(moduleBuilder != null);

            // ensure flow analysis
            var analysisdiagnostics = compilation.BindAndAnalyseTask().Result;

            diagnostics.AddRange(analysisdiagnostics);

            //
            var compiler = new SourceCompiler(compilation, moduleBuilder, emittingPdb, diagnostics, cancellationToken);

            // Emit method bodies
            //   a. declared routines
            //   b. synthesized symbols
            compiler.EmitMethodBodies();
            compiler.EmitSynthesized();
            compiler.CompileReflectionEnumerators();

            // Entry Point (.exe)
            compiler.CompileEntryPoint();
        }
示例#5
0
        public static void CompileSources(
            PhpCompilation compilation,
            PEModuleBuilder moduleBuilder,
            bool emittingPdb,
            bool hasDeclarationErrors,
            DiagnosticBag diagnostics,
            CancellationToken cancellationToken)
        {
            var compiler = new SourceCompiler(compilation, moduleBuilder, emittingPdb, diagnostics);

            // 1. Synthetize magic
            //   a.inline syntax like traits
            //   b.synthetize entry point, getters, setters, ctors, dispose, magic methods, …
            // TODO.

            // 2.Bind Syntax & Symbols to Operations (CFG)
            //   a.equivalent to building CFG
            //   b.most generic types(and empty type - mask)
            compiler.BindMethods();

            // 3.Analyze Operations
            //   a.declared variables
            //   b.build global variables/constants table
            //   c.type analysis(converge type - mask), resolve symbols
            //   d.lower semantics, update bound tree, repeat
            compiler.AnalyzeMethods();

            // 4. Emit method bodies
            compiler.EmitMethodBodies();
            compiler.CompileReflectionEnumerators(cancellationToken);

            // 5. Entry Point (.exe)
            compiler.CompileEntryPoint(cancellationToken);
        }
示例#6
0
        /// <summary>
        /// Ensures semantic binding and flow analysis.
        /// </summary>
        /// <returns>The result of the task contains enumeration of diagnostics.</returns>
        public async Task <IEnumerable <Diagnostic> > BindAndAnalyseTask()
        {
            if (_lazyAnalysisTask == null)
            {
                _lazyAnalysisTask = Task.Run(() => SourceCompiler.BindAndAnalyze(this));
            }

            return(await _lazyAnalysisTask);
        }
示例#7
0
        /// <summary>
        /// Ensures semantic binding and flow analysis.
        /// </summary>
        /// <returns>The result of the task contains enumeration of diagnostics.</returns>
        public async Task <IEnumerable <Diagnostic> > BindAndAnalyseTask()
        {
            if (_lazyAnalysisTask == null)
            {
                _lazyAnalysisTask = Task.Run(() => SourceCompiler.BindAndAnalyze(this, CancellationToken.None));
            }

            return(await _lazyAnalysisTask.ConfigureAwait(false));
        }
示例#8
0
        internal override bool CompileMethods(CommonPEModuleBuilder moduleBuilder, bool emittingPdb, bool emitMetadataOnly, bool emitTestCoverageData, DiagnosticBag diagnostics, Predicate <ISymbol> filterOpt, CancellationToken cancellationToken)
        {
            // The diagnostics should include syntax and declaration errors. We insert these before calling Emitter.Emit, so that the emitter
            // does not attempt to emit if there are declaration errors (but we do insert all errors from method body binding...)
            bool hasDeclarationErrors = false;  // !FilterAndAppendDiagnostics(diagnostics, GetDiagnostics(CompilationStage.Declare, true, cancellationToken));

            var moduleBeingBuilt = (PEModuleBuilder)moduleBuilder;

            if (emitMetadataOnly)
            {
                throw new NotImplementedException();
            }

            if (emittingPdb)
            {
                if (!CreateDebugDocuments(
                        moduleBeingBuilt.DebugDocumentsBuilder,
                        moduleBeingBuilt.EmbeddedTexts.Concat(CollectAdditionalEmbeddedTexts()),
                        diagnostics))
                {
                    return(false);
                }
            }

            // Use a temporary bag so we don't have to refilter pre-existing diagnostics.
            DiagnosticBag methodBodyDiagnosticBag = DiagnosticBag.GetInstance();

            // Perform initial bind of method bodies in spite of earlier errors. This is the same
            // behavior as when calling GetDiagnostics()

            try
            {
                SourceCompiler.CompileSources(
                    this,
                    moduleBeingBuilt,
                    emittingPdb,
                    hasDeclarationErrors,
                    methodBodyDiagnosticBag,
                    cancellationToken);

                bool hasMethodBodyErrorOrWarningAsError = !FilterAndAppendAndFreeDiagnostics(diagnostics, ref methodBodyDiagnosticBag);

                if (hasDeclarationErrors || hasMethodBodyErrorOrWarningAsError)
                {
                    return(false);
                }

                return(true);
            }
            catch (Exception ex)
            {
                this.TrackException(ex);
                throw;
            }
        }
示例#9
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.EnqueueFieldsInitializer, allowParallel: true);
            }

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

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

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

                // 4. 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);

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

            //
            return(diagnostics.AsEnumerable());
        }
示例#10
0
        public static IEnumerable <Diagnostic> BindAndAnalyze(PhpCompilation compilation)
        {
            var manager = compilation.GetBoundReferenceManager();   // ensure the references are resolved! (binds ReferenceManager)

            var diagnostics = new DiagnosticBag();
            var compiler    = new SourceCompiler(compilation, null, true, diagnostics, CancellationToken.None);

            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.EnqueueFieldsInitializer, allowParallel: true);
            }

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

            // TODO: Enable when the rewriting mechanism is refactored
            //if (!diagnostics.HasAnyErrors() && compilation.Options.OptimizationLevel == OptimizationLevel.Release)
            //{
            //    using (compilation.StartMetric("transform"))
            //    {
            //        // 3. Transform Semantic Trees for Runtime Optimization
            //        compiler.TransformMethods();
            //    }
            //}

            //
            return(diagnostics.AsEnumerable());
        }
示例#11
0
        public static IEnumerable <Diagnostic> BindAndAnalyze(PhpCompilation compilation)
        {
            var manager = compilation.GetBoundReferenceManager();   // ensure the references are resolved! (binds ReferenceManager)

            var diagnostics = new DiagnosticBag();
            var compiler    = new SourceCompiler(compilation, null, true, diagnostics, CancellationToken.None);

            // 1.Bind Syntax & Symbols to Operations (CFG)
            //   a.equivalent to building CFG
            //   b.most generic types(and empty type - mask)
            compiler.WalkMethods(compiler.EnqueueRoutine);
            compiler.WalkTypes(compiler.EnqueueFieldsInitializer);

            // 2.Analyze Operations
            //   a.declared variables
            //   b.build global variables/constants table
            //   c.type analysis(converge type - mask), resolve symbols
            //   d.lower semantics, update bound tree, repeat
            compiler.AnalyzeMethods();
            compiler.DiagnoseMethods();

            //
            return(diagnostics.AsEnumerable());
        }
示例#12
0
        internal override bool CompileImpl(CommonPEModuleBuilder moduleBuilder, Stream win32Resources, Stream xmlDocStream, bool emittingPdb, DiagnosticBag diagnostics, Predicate <ISymbol> filterOpt, CancellationToken cancellationToken)
        {
            // The diagnostics should include syntax and declaration errors. We insert these before calling Emitter.Emit, so that the emitter
            // does not attempt to emit if there are declaration errors (but we do insert all errors from method body binding...)
            bool hasDeclarationErrors = false;  // !FilterAndAppendDiagnostics(diagnostics, GetDiagnostics(CompilationStage.Declare, true, cancellationToken));

            var moduleBeingBuilt = (PEModuleBuilder)moduleBuilder;

            if (moduleBeingBuilt.EmitOptions.EmitMetadataOnly)
            {
                throw new NotImplementedException();
            }

            // Perform initial bind of method bodies in spite of earlier errors. This is the same
            // behavior as when calling GetDiagnostics()

            // Use a temporary bag so we don't have to refilter pre-existing diagnostics.
            DiagnosticBag methodBodyDiagnosticBag = DiagnosticBag.GetInstance();

            SourceCompiler.CompileSources(
                this,
                moduleBeingBuilt,
                emittingPdb,
                hasDeclarationErrors,
                methodBodyDiagnosticBag,
                cancellationToken);

            SetupWin32Resources(moduleBeingBuilt, win32Resources, methodBodyDiagnosticBag);

            ReportManifestResourceDuplicates(
                moduleBeingBuilt.ManifestResources,
                SourceAssembly.Modules.Skip(1).Select((m) => m.Name),   //all modules except the first one
                AddedModulesResourceNames(methodBodyDiagnosticBag),
                methodBodyDiagnosticBag);

            bool hasMethodBodyErrorOrWarningAsError = !FilterAndAppendAndFreeDiagnostics(diagnostics, ref methodBodyDiagnosticBag);

            if (hasDeclarationErrors || hasMethodBodyErrorOrWarningAsError)
            {
                return(false);
            }

            cancellationToken.ThrowIfCancellationRequested();

            // Use a temporary bag so we don't have to refilter pre-existing diagnostics.
            DiagnosticBag xmlDiagnostics = DiagnosticBag.GetInstance();

            string assemblyName = FileNameUtilities.ChangeExtension(moduleBeingBuilt.EmitOptions.OutputNameOverride, extension: null);

            DocumentationCommentCompiler.WriteDocumentationCommentXml(this, assemblyName, xmlDocStream, xmlDiagnostics, cancellationToken);

            if (!FilterAndAppendAndFreeDiagnostics(diagnostics, ref xmlDiagnostics))
            {
                return(false);
            }

            //// Use a temporary bag so we don't have to refilter pre-existing diagnostics.
            //DiagnosticBag importDiagnostics = DiagnosticBag.GetInstance();
            //this.ReportUnusedImports(importDiagnostics, cancellationToken);

            //if (!FilterAndAppendAndFreeDiagnostics(diagnostics, ref importDiagnostics))
            //{
            //    Debug.Assert(false, "Should never produce an error");
            //    return false;
            //}

            return(true);
        }
示例#13
0
        public static void CompileSources(
            PhpCompilation compilation,
            PEModuleBuilder moduleBuilder,
            bool emittingPdb,
            bool hasDeclarationErrors,
            DiagnosticBag diagnostics,
            CancellationToken cancellationToken)
        {
            var compiler = new SourceCompiler(compilation, moduleBuilder, emittingPdb, diagnostics);

            // 1.Bind Syntax & Symbols to Operations (CFG)
            //   a.equivalent to building CFG
            //   b.most generic types(and empty type - mask)
            compiler.WalkMethods(compiler.EnqueueRoutine);
            compiler.WalkTypes(compiler.EnqueueFieldsInitializer);

            // 2.Analyze Operations
            //   a.declared variables
            //   b.build global variables/constants table
            //   c.type analysis(converge type - mask), resolve symbols
            //   d.lower semantics, update bound tree, repeat
            compiler.AnalyzeMethods();

            // 3. Emit method bodies
            //   a. declared routines
            //   b. synthesized symbols
            compiler.EmitMethodBodies();
            compiler.EmitSynthesized();
            compiler.CompileReflectionEnumerators(cancellationToken);

            // 4. Entry Point (.exe)
            compiler.CompileEntryPoint(cancellationToken);
        }