internal static BoundStatement AnalyzeMethodBody(MethodBodyCompiler methodCompiler, MethodSymbol method, BoundBlock body, DiagnosticBag diagnostics) { Debug.Assert(diagnostics != null); body = FlowAnalysisPass.Rewrite(method, body, diagnostics); var analyzedBody = (BoundBlock)RewritePass.Rewrite(methodCompiler, method.ContainingType, body); return RewritePass.InsertPrologueSequencePoint(analyzedBody, method); }
internal static BoundStatement AnalyzeMethodBody(MethodBodyCompiler methodCompiler, MethodSymbol method, BoundBlock body, DiagnosticBag diagnostics) { Debug.Assert(diagnostics != null); body = FlowAnalysisPass.Rewrite(method, body, diagnostics); var analyzedBody = (BoundBlock)RewritePass.Rewrite(methodCompiler, method.ContainingType, body); return(RewritePass.InsertPrologueSequencePoint(analyzedBody, method)); }
internal static BoundStatementList AnalyzeFieldInitializers(MethodBodyCompiler methodCompiler, MethodSymbol constructor, ReadOnlyArray<BoundInitializer> boundInitializers) { if (boundInitializers.IsNull) { return null; } // The lowered tree might be reused in multiple constructors. Therefore, unless there is just a single constructor // (e.g. in interactive submission), the lowered code should not refer to it. var initializerStatements = InitializerRewriter.Rewrite(boundInitializers, constructor.IsInteractiveSubmissionConstructor ? constructor : null); return (BoundStatementList)RewritePass.Rewrite(methodCompiler, constructor.ContainingType, initializerStatements); }
internal static BoundStatementList AnalyzeFieldInitializers(MethodBodyCompiler methodCompiler, MethodSymbol constructor, ReadOnlyArray <BoundInitializer> boundInitializers) { if (boundInitializers.IsNull) { return(null); } // The lowered tree might be reused in multiple constructors. Therefore, unless there is just a single constructor // (e.g. in interactive submission), the lowered code should not refer to it. var initializerStatements = InitializerRewriter.Rewrite(boundInitializers, constructor.IsInteractiveSubmissionConstructor ? constructor : null); return((BoundStatementList)RewritePass.Rewrite(methodCompiler, constructor.ContainingType, initializerStatements)); }
public void IgnoreOtherDiagnosticsCompilingSynthesizedMethods() { var source = @"class C { static object F = new object(); // generate .cctor static System.Action M() { return () => { }; // generate lambda } }"; var compilation = CreateCompilationWithMscorlib(source, compOptions: TestOptions.Dll.WithConcurrentBuild(false)); var options = compilation.Options; var diagnostics = DiagnosticBag.GetInstance(); var assembly = (SourceAssemblySymbol)compilation.Assembly; var outputName = GetUniqueName(); var module = new PEAssemblyBuilder( assembly, outputName, options.OutputKind, GetDefaultModulePropertiesForSerialization(), new ResourceDescription[0], null); var methodBodyCompiler = new MethodBodyCompiler(compilation, module, false, false, diagnostics, null, CancellationToken.None); // Add diagnostic to MethodBodyCompiler bag, as if // code gen for an earlier method had generated an errror. diagnostics.Add(new CSDiagnostic(new CSDiagnosticInfo(ErrorCode.ERR_IntDivByZero), NoLocation.Singleton)); // Compile all methods for type including synthesized methods. var type = compilation.GlobalNamespace.GetMember<NamedTypeSymbol>("C"); methodBodyCompiler.Visit(type); Assert.Equal(1, diagnostics.AsEnumerable().Count()); diagnostics.Free(); }
public override void DecompileMethod(Mono.Cecil.MethodDefinition method, ICSharpCode.Decompiler.ITextOutput output, DecompilationOptions options) { var node = MethodBodyCompiler.CreateOptimizedAst(method); node.WriteTo(new TextOutputBridge(output)); }
private void DecompileMethod(XMethodDefinition xMethod, ITextOutput output, int indentation = 0) { var indent = new string(Enumerable.Repeat('\t', indentation).ToArray()); var ilMethod = xMethod as XBuilder.ILMethodDefinition; if (ilMethod == null || !ilMethod.OriginalMethod.HasBody) { output.Write(indent); output.WriteLine("// not an il method or method without body."); return; } var methodSource = new MethodSource(xMethod, ilMethod.OriginalMethod); var node = MethodBodyCompiler.CreateOptimizedAst(AssemblyCompiler, methodSource, GenerateSetNextInstructionCode, StopConversion, StopOptimizing); bool writeExtraLine = false; if (StopConversion != StopAstConversion.None) { output.Write(indent); output.Write("// Stop Ast Conversion after " + StopConversion); output.WriteLine(); writeExtraLine = true; } if (StopOptimizing != AstOptimizationStep.None) { output.Write(indent); output.Write("// Stop Ast Optimizing before " + StopOptimizing); output.WriteLine(); writeExtraLine = true; } if (writeExtraLine) { output.WriteLine(); } var bridge = new TextOutputBridge(output); for (int i = 0; i < indentation; ++i) { bridge.Indent(); } FormattingOptions formattingOptions; if (StopConversion == StopAstConversion.AfterILConversion || !BreakExpressionLines) { formattingOptions = FormattingOptions.Default; } else { formattingOptions = FormattingOptions.BreakExpressions; } if (!ShowFullNames) { formattingOptions |= FormattingOptions.SimpleNames; } if (ShowHasSeqPoint) { formattingOptions |= FormattingOptions.ShowHasSeqPoint; } node.WriteTo(bridge, formattingOptions); for (int i = 0; i < indentation; ++i) { bridge.Unindent(); } }
/// <summary> /// Resets numbering in anonymous type names and compiles the /// anonymous type methods. Also seals the collection of templates. /// </summary> public void AssignTemplatesNamesAndCompile(MethodBodyCompiler compiler, PEModuleBuilder moduleBeingBuilt, DiagnosticBag diagnostics) { // Ensure all previous anonymous type templates are included so the // types are available for subsequent edit and continue generations. foreach (var key in moduleBeingBuilt.GetPreviousAnonymousTypes()) { var templateKey = AnonymousTypeDescriptor.ComputeKey(key.Names, f => f); this.AnonymousTypeTemplates.GetOrAdd(templateKey, k => this.CreatePlaceholderTemplate(key)); } // Get all anonymous types owned by this manager var builder = ArrayBuilder <AnonymousTypeTemplateSymbol> .GetInstance(); var anonymousTypes = lazyAnonymousTypeTemplates; if (anonymousTypes != null) { foreach (var template in anonymousTypes.Values) { // NOTE: in interactive scenarios the cache may contain templates // from other compilation, those should be discarded here if (ReferenceEquals(template.Manager, this)) { builder.Add(template); } } } // If the collection is not sealed yet we should assign // new indexes to the created anonymous type templates if (this.anonymousTypeTemplatesIsSealed != ThreeState.True) { // Sort type templates using smallest location builder.Sort(new AnonymousTypeComparer(this.Compilation)); // If we are emitting .NET module, include module's name into type's name to ensure // uniqueness across added modules. string moduleId; if (moduleBeingBuilt.OutputKind == OutputKind.NetModule) { moduleId = moduleBeingBuilt.Name; string extension = OutputKind.NetModule.GetDefaultExtension(); if (moduleId.EndsWith(extension, StringComparison.OrdinalIgnoreCase)) { moduleId = moduleId.Substring(0, moduleId.Length - extension.Length); } moduleId = moduleId.Replace('.', '_'); } else { moduleId = string.Empty; } int nextIndex = moduleBeingBuilt.GetNextAnonymousTypeIndex(); foreach (var template in builder) { string name; int index; if (!moduleBeingBuilt.TryGetAnonymousTypeName(template, out name, out index)) { index = nextIndex++; name = GeneratedNames.MakeAnonymousTypeTemplateName(index, this.Compilation.GetSubmissionSlotIndex(), moduleId); } // normally it should only happen once, but in case there is a race // NameAndIndex.set has an assert which guarantees that the // template name provided is the same as the one already assigned template.NameAndIndex = new NameAndIndex(name, index); } this.anonymousTypeTemplatesIsSealed = ThreeState.True; } if (builder.Count > 0 && !ReportMissingOrErroneousSymbols(diagnostics)) { // Process all the templates foreach (var template in builder) { foreach (var method in template.SpecialMembers) { moduleBeingBuilt.AddCompilerGeneratedDefinition(template, method); } compiler.Visit(template, null); } } builder.Free(); var delegates = lazySynthesizedDelegates; if (delegates != null) { foreach (var template in delegates.Values) { // NOTE: in interactive scenarios the cache may contain templates // from other compilation, those should be discarded here if (ReferenceEquals(template.Manager, this)) { compiler.Visit(template.Delegate, null); } } } }