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);
        }
Esempio n. 2
0
        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);
        }
Esempio n. 4
0
        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));
        }
Esempio n. 5
0
        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();
        }
Esempio n. 6
0
        public override void DecompileMethod(Mono.Cecil.MethodDefinition method, ICSharpCode.Decompiler.ITextOutput output, DecompilationOptions options)
        {
            var node = MethodBodyCompiler.CreateOptimizedAst(method);

            node.WriteTo(new TextOutputBridge(output));
        }
Esempio n. 7
0
        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);
                    }
                }
            }
        }