Exemplo n.º 1
0
        void EndKeywordBlock(IDecompilerOutput output, BraceInfo info, CodeBracesRangeFlags flags, bool addLineSeparator = false)
        {
            output.DecreaseIndent();
            var end = output.NextPosition;

            output.Write("}", BoxedTextColor.Punctuation);
            output.AddBracePair(new TextSpan(info.Start, 1), new TextSpan(end, 1), flags);
            if (addLineSeparator)
            {
                output.AddLineSeparator(end);
            }
            output.WriteLine();
        }
Exemplo n.º 2
0
        public override void Decompile(MethodDef method, IDecompilerOutput output, DecompilationContext ctx)
        {
            WriteCommentBegin(output, true);
            output.Write("Method: ", BoxedTextColor.Comment);
            output.Write(IdentifierEscaper.Escape(method.FullName), method, DecompilerReferenceFlags.Definition, BoxedTextColor.Comment);
            WriteCommentEnd(output, true);
            output.WriteLine();

            if (!method.HasBody)
            {
                return;
            }

            var bodyInfo = StartKeywordBlock(output, ".body", method);

            ILAstBuilder      astBuilder = new ILAstBuilder();
            ILBlock           ilMethod   = new ILBlock(CodeBracesRangeFlags.MethodBraces);
            DecompilerContext context    = new DecompilerContext(method.Module, MetadataTextColorProvider)
            {
                CurrentType       = method.DeclaringType,
                CurrentMethod     = method,
                CalculateBinSpans = ctx.CalculateBinSpans,
            };

            ilMethod.Body = astBuilder.Build(method, inlineVariables, context);

            if (abortBeforeStep != null)
            {
                new ILAstOptimizer().Optimize(context, ilMethod, abortBeforeStep.Value);
            }

            if (context.CurrentMethodIsYieldReturn)
            {
                output.Write("yield", BoxedTextColor.Keyword);
                output.Write(" ", BoxedTextColor.Text);
                output.WriteLine("return", BoxedTextColor.Keyword);
            }
            if (context.CurrentMethodIsAsync)
            {
                output.Write("async", BoxedTextColor.Keyword);
                output.Write("/", BoxedTextColor.Punctuation);
                output.WriteLine("await", BoxedTextColor.Keyword);
            }

            var allVariables = ilMethod.GetSelfAndChildrenRecursive <ILExpression>().Select(e => e.Operand as ILVariable)
                               .Where(v => v != null && !v.IsParameter).Distinct();

            foreach (ILVariable v in allVariables)
            {
                output.Write(IdentifierEscaper.Escape(v.Name), (object)v.OriginalVariable ?? (object)v.OriginalParameter ?? v.Id, DecompilerReferenceFlags.Local | DecompilerReferenceFlags.Definition, v.IsParameter ? BoxedTextColor.Parameter : BoxedTextColor.Local);
                if (v.Type != null)
                {
                    output.Write(" ", BoxedTextColor.Text);
                    output.Write(":", BoxedTextColor.Punctuation);
                    output.Write(" ", BoxedTextColor.Text);
                    if (v.IsPinned)
                    {
                        output.Write("pinned", BoxedTextColor.Keyword);
                        output.Write(" ", BoxedTextColor.Text);
                    }
                    v.Type.WriteTo(output, ILNameSyntax.ShortTypeName);
                }
                if (v.GeneratedByDecompiler)
                {
                    output.Write(" ", BoxedTextColor.Text);
                    var start = output.NextPosition;
                    output.Write("[", BoxedTextColor.Punctuation);
                    output.Write("generated", BoxedTextColor.Keyword);
                    var end = output.NextPosition;
                    output.Write("]", BoxedTextColor.Punctuation);
                    output.AddBracePair(new TextSpan(start, 1), new TextSpan(end, 1), CodeBracesRangeFlags.SquareBrackets);
                }
                output.WriteLine();
            }

            var builder = new MethodDebugInfoBuilder(method);

            foreach (ILNode node in ilMethod.Body)
            {
                node.WriteTo(output, builder);
                if (!node.WritesNewLine)
                {
                    output.WriteLine();
                }
            }
            output.AddDebugInfo(builder.Create());
            EndKeywordBlock(output, bodyInfo, CodeBracesRangeFlags.MethodBraces, addLineSeparator: true);
        }
Exemplo n.º 3
0
        public override void Decompile(MethodDef method, IDecompilerOutput output, DecompilationContext ctx)
        {
            WriteCommentBegin(output, true);
            output.Write("Method: ", BoxedTextColor.Comment);
            output.Write(IdentifierEscaper.Escape(method.FullName), method, DecompilerReferenceFlags.Definition, BoxedTextColor.Comment);
            WriteCommentEnd(output, true);
            output.WriteLine();

            if (!method.HasBody)
            {
                return;
            }

            var bodyInfo = StartKeywordBlock(output, ".body", method);

            ILAstBuilder      astBuilder = new ILAstBuilder();
            ILBlock           ilMethod   = new ILBlock(CodeBracesRangeFlags.MethodBraces);
            DecompilerContext context    = new DecompilerContext(settingsVersion, method.Module, MetadataTextColorProvider)
            {
                CurrentType      = method.DeclaringType,
                CurrentMethod    = method,
                CalculateILSpans = ctx.CalculateILSpans,
            };

            ilMethod.Body = astBuilder.Build(method, inlineVariables, context);

            var                  stateMachineKind = StateMachineKind.None;
            MethodDef?           inlinedMethod    = null;
            AsyncMethodDebugInfo?asyncInfo        = null;
            string?              compilerName     = null;

            if (!(abortBeforeStep is null))
            {
                var optimizer = new ILAstOptimizer();
                optimizer.Optimize(context, ilMethod, out stateMachineKind, out inlinedMethod, out asyncInfo, abortBeforeStep.Value);
                compilerName = optimizer.CompilerName;
            }

            if (context.CurrentMethodIsYieldReturn)
            {
                output.Write("yield", BoxedTextColor.Keyword);
                output.Write(" ", BoxedTextColor.Text);
                output.WriteLine("return", BoxedTextColor.Keyword);
            }
            if (context.CurrentMethodIsAsync)
            {
                output.Write("async", BoxedTextColor.Keyword);
                output.Write("/", BoxedTextColor.Punctuation);
                output.WriteLine("await", BoxedTextColor.Keyword);
            }

            var allVariables = ilMethod.GetSelfAndChildrenRecursive <ILExpression>().Select(e => e.Operand as ILVariable)
                               .Where(v => !(v is null) && !v.IsParameter).Distinct();

            foreach (ILVariable v in allVariables)
            {
                output.Write(IdentifierEscaper.Escape(v.Name), v.GetTextReferenceObject(), DecompilerReferenceFlags.Local | DecompilerReferenceFlags.Definition, v.IsParameter ? BoxedTextColor.Parameter : BoxedTextColor.Local);
                if (!(v.Type is null))
                {
                    output.Write(" ", BoxedTextColor.Text);
                    output.Write(":", BoxedTextColor.Punctuation);
                    output.Write(" ", BoxedTextColor.Text);
                    if (v.IsPinned)
                    {
                        output.Write("pinned", BoxedTextColor.Keyword);
                        output.Write(" ", BoxedTextColor.Text);
                    }
                    v.Type.WriteTo(output, ILNameSyntax.ShortTypeName);
                }
                if (v.GeneratedByDecompiler)
                {
                    output.Write(" ", BoxedTextColor.Text);
                    var start = output.NextPosition;
                    output.Write("[", BoxedTextColor.Punctuation);
                    output.Write("generated", BoxedTextColor.Keyword);
                    var end = output.NextPosition;
                    output.Write("]", BoxedTextColor.Punctuation);
                    output.AddBracePair(new TextSpan(start, 1), new TextSpan(end, 1), CodeBracesRangeFlags.SquareBrackets);
                }
                output.WriteLine();
            }

            var localVariables = new HashSet <ILVariable>(GetVariables(ilMethod));
            var builder        = new MethodDebugInfoBuilder(settingsVersion, stateMachineKind, inlinedMethod ?? method, !(inlinedMethod is null) ? method : null, CreateSourceLocals(localVariables), CreateSourceParameters(localVariables), asyncInfo);

            builder.CompilerName = compilerName;
            foreach (ILNode node in ilMethod.Body)
            {
                node.WriteTo(output, builder);
                if (!node.WritesNewLine)
                {
                    output.WriteLine();
                }
            }
            output.AddDebugInfo(builder.Create());
            EndKeywordBlock(output, bodyInfo, CodeBracesRangeFlags.MethodBraces, addLineSeparator: true);
        }
Exemplo n.º 4
0
 public void AddBracePair(int leftStart, int leftEnd, int rightStart, int rightEnd, CodeBracesRangeFlags flags) =>
 output.AddBracePair(TextSpan.FromBounds(leftStart, leftEnd), TextSpan.FromBounds(rightStart, rightEnd), flags);