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(); }
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()); }
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); }
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(); }
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); }
/// <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); }
/// <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)); }
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; } }
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()); }
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()); }
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()); }
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); }