Exemplo n.º 1
0
        public void DisassembleField(FieldDefinition field)
        {
            // create mappings for decompiled fields only
            this.DecompiledMemberReferences.Add(field.MetadataToken.ToInt32(), field);

            output.WriteDefinition(".field ", field);
            WriteEnum(field.Attributes & FieldAttributes.FieldAccessMask, fieldVisibility);
            const FieldAttributes hasXAttributes = FieldAttributes.HasDefault | FieldAttributes.HasFieldMarshal | FieldAttributes.HasFieldRVA;

            WriteFlags(field.Attributes & ~(FieldAttributes.FieldAccessMask | hasXAttributes), fieldAttributes);
            if (field.HasMarshalInfo)
            {
                WriteMarshalInfo(field.MarshalInfo);
            }
            field.FieldType.WriteTo(output);
            output.Write(' ');
            output.Write(DisassemblerHelpers.Escape(field.Name));
            if ((field.Attributes & FieldAttributes.HasFieldRVA) == FieldAttributes.HasFieldRVA)
            {
                output.Write(" at I_{0:x8}", field.RVA);
            }
            if (field.HasConstant)
            {
                output.Write(" = ");
                WriteConstant(field.Constant);
            }
            output.WriteLine();
            if (field.HasCustomAttributes)
            {
                output.MarkFoldStart();
                WriteAttributes(field.CustomAttributes);
                output.MarkFoldEnd();
            }
        }
Exemplo n.º 2
0
        public void DisassembleField(FieldDefinition field)
        {
            _output.WriteDefinition(".field ", field);
            if (field.HasLayoutInfo)
            {
                _output.Write("[" + field.Offset + "] ");
            }
            WriteEnum(field.Attributes & FieldAttributes.FieldAccessMask, _fieldVisibility);
            const FieldAttributes hasXAttributes = FieldAttributes.HasDefault | FieldAttributes.HasFieldMarshal | FieldAttributes.HasFieldRVA;

            WriteFlags(field.Attributes & ~(FieldAttributes.FieldAccessMask | hasXAttributes), _fieldAttributes);
            if (field.HasMarshalInfo)
            {
                WriteMarshalInfo(field.MarshalInfo);
            }
            field.FieldType.WriteTo(_output);
            _output.Write(' ');
            _output.Write(DisassemblerHelpers.Escape(field.Name));
            if ((field.Attributes & FieldAttributes.HasFieldRVA) == FieldAttributes.HasFieldRVA)
            {
                _output.Write(" at I_{0:x8}", field.RVA);
            }
            if (field.HasConstant)
            {
                _output.Write(" = ");
                WriteConstant(field.Constant);
            }
            _output.WriteLine();
            if (field.HasCustomAttributes)
            {
                _output.MarkFoldStart();
                WriteAttributes(field.CustomAttributes);
                _output.MarkFoldEnd();
            }
        }
Exemplo n.º 3
0
        public override void WriteIdentifier(Identifier identifier)
        {
            if (identifier.IsVerbatim || CSharpOutputVisitor.IsKeyword(identifier.Name, identifier))
            {
                output.Write('@');
            }

            var    definition = GetCurrentDefinition();
            string name       = TextWriterTokenWriter.EscapeIdentifier(identifier.Name);

            switch (definition)
            {
            case IType t:
                output.WriteReference(t, name, true);
                return;

            case IMember m:
                output.WriteReference(m, name, true);
                return;
            }

            var member = GetCurrentMemberReference();

            switch (member)
            {
            case IType t:
                output.WriteReference(t, name, false);
                return;

            case IMember m:
                output.WriteReference(m, name, false);
                return;
            }

            var localDefinition = GetCurrentLocalDefinition();

            if (localDefinition != null)
            {
                output.WriteLocalReference(name, localDefinition, isDefinition: true);
                return;
            }

            var localRef = GetCurrentLocalReference();

            if (localRef != null)
            {
                output.WriteLocalReference(name, localRef);
                return;
            }

            if (firstUsingDeclaration && !lastUsingDeclaration)
            {
                output.MarkFoldStart(defaultCollapsed: !settings.ExpandUsingDeclarations);
                firstUsingDeclaration = false;
            }

            output.Write(name);
        }
Exemplo n.º 4
0
        public override void WriteIdentifier(Identifier identifier, TextTokenType tokenType)
        {
            if (tokenType == TextTokenType.Text)
            {
                tokenType = TextTokenHelper.GetTextTokenType(identifier.AnnotationVT <TextTokenType>() ?? identifier.Annotation <object>());
            }

            if (tokenType != TextTokenType.Keyword && (identifier.IsVerbatim || CSharpOutputVisitor.IsKeyword(identifier.Name, identifier)))
            {
                output.Write('@', TextTokenType.Operator);
            }

            var definition = GetCurrentDefinition(identifier);

            if (definition != null)
            {
                output.WriteDefinition(IdentifierEscaper.Escape(identifier.Name), definition, tokenType, false);
                return;
            }

            object memberRef = GetCurrentMemberReference();

            if (memberRef != null)
            {
                output.WriteReference(IdentifierEscaper.Escape(identifier.Name), memberRef, tokenType);
                return;
            }

            definition = GetCurrentLocalDefinition();
            if (definition != null)
            {
                output.WriteDefinition(IdentifierEscaper.Escape(identifier.Name), definition, tokenType);
                return;
            }

            memberRef = GetCurrentLocalReference();
            if (memberRef != null)
            {
                output.WriteReference(IdentifierEscaper.Escape(identifier.Name), memberRef, tokenType, true);
                return;
            }

            if (firstUsingDeclaration)
            {
                output.MarkFoldStart(defaultCollapsed: true);
                firstUsingDeclaration = false;
            }

            var s = identifier.Name;

            if (identifier.Annotation <IdentifierFormatted>() == null)
            {
                s = IdentifierEscaper.Escape(s);
            }
            output.Write(s, tokenType);
        }
Exemplo n.º 5
0
        public override void WriteIdentifier(Identifier identifier)
        {
            if (identifier.IsVerbatim || CSharpOutputVisitor.IsKeyword(identifier.Name, identifier))
            {
                output.Write('@');
            }

            var definition = GetCurrentDefinition();

            if (definition != null)
            {
                MemberReference cecil = SymbolToCecil(definition);
                if (cecil != null)
                {
                    output.WriteDefinition(identifier.Name, cecil, false);
                    return;
                }
            }

            var member = GetCurrentMemberReference();

            if (member != null)
            {
                MemberReference cecil = SymbolToCecil(member);
                if (cecil != null)
                {
                    output.WriteReference(identifier.Name, cecil);
                    return;
                }
            }

            var localDefinition = GetCurrentLocalDefinition();

            if (localDefinition != null)
            {
                output.WriteDefinition(identifier.Name, localDefinition);
                return;
            }

            var localRef = GetCurrentLocalReference();

            if (localRef != null)
            {
                output.WriteReference(identifier.Name, localRef, true);
                return;
            }

            if (firstUsingDeclaration)
            {
                output.MarkFoldStart(defaultCollapsed: true);
                firstUsingDeclaration = false;
            }

            output.Write(identifier.Name);
        }
Exemplo n.º 6
0
 public void OpenBrace(BraceStyle style)
 {
     if (braceLevelWithinType >= 0 || nodeStack.Peek() is TypeDeclaration)
     {
         braceLevelWithinType++;
     }
     if (nodeStack.OfType <BlockStatement>().Count() <= 1)
     {
         output.MarkFoldStart(defaultCollapsed: braceLevelWithinType == 1);
     }
     output.WriteLine();
     output.WriteLine("{");
     output.Indent();
 }
Exemplo n.º 7
0
        public override void Decompile(Language language, ITextOutput output, DecompilationOptions options)
        {
            void HandleException(Exception ex, string message)
            {
                language.WriteCommentLine(output, message);

                output.WriteLine();
                output.MarkFoldStart("Exception details", true);
                output.Write(ex.ToString());
                output.MarkFoldEnd();
            }

            try {
                assembly.WaitUntilLoaded();                 // necessary so that load errors are passed on to the caller
            } catch (AggregateException ex) {
                language.WriteCommentLine(output, assembly.FileName);
                switch (ex.InnerException)
                {
                case BadImageFormatException badImage:
                    HandleException(badImage, "This file does not contain a managed assembly.");
                    return;

                case FileNotFoundException fileNotFound:
                    HandleException(fileNotFound, "The file was not found.");
                    return;

                default:
                    throw;
                }
            }
            language.DecompileAssembly(assembly, output, options);
        }
Exemplo n.º 8
0
 public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
 {
     output.WriteDefinition("BlockContainer", this);
     output.Write(' ');
     output.MarkFoldStart("{...}");
     output.WriteLine("{");
     output.Indent();
     foreach (var inst in Blocks)
     {
         if (inst.Parent == this)
         {
             inst.WriteTo(output, options);
         }
         else
         {
             output.Write("stale reference to ");
             output.WriteReference(inst.Label, inst, isLocal: true);
         }
         output.WriteLine();
         output.WriteLine();
     }
     output.Unindent();
     output.Write("}");
     output.MarkFoldEnd();
 }
Exemplo n.º 9
0
 public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
 {
     WriteILRange(output, options);
     output.Write("deconstruct ");
     output.MarkFoldStart("{...}");
     output.WriteLine("{");
     output.Indent();
     output.WriteLine("init:");
     output.Indent();
     foreach (var inst in this.Init)
     {
         inst.WriteTo(output, options);
         output.WriteLine();
     }
     output.Unindent();
     output.WriteLine("pattern:");
     output.Indent();
     pattern.WriteTo(output, options);
     output.Unindent();
     output.WriteLine();
     output.Write("conversions: ");
     conversions.WriteTo(output, options);
     output.WriteLine();
     output.Write("assignments: ");
     assignments.WriteTo(output, options);
     output.Unindent();
     output.WriteLine();
     output.Write('}');
     output.MarkFoldEnd();
 }
Exemplo n.º 10
0
 public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
 {
     ILRange.WriteTo(output, options);
     output.Write("Block ");
     output.WriteDefinition(Label, this);
     if (Parent is BlockContainer)
     {
         output.Write(" (incoming: {0})", IncomingEdgeCount);
     }
     output.Write(' ');
     output.MarkFoldStart("{...}");
     output.WriteLine("{");
     output.Indent();
     foreach (var inst in Instructions)
     {
         inst.WriteTo(output, options);
         output.WriteLine();
     }
     if (finalInstruction.OpCode != OpCode.Nop)
     {
         output.Write("final: ");
         finalInstruction.WriteTo(output, options);
         output.WriteLine();
     }
     output.Unindent();
     output.Write("}");
     output.MarkFoldEnd();
 }
Exemplo n.º 11
0
        public override void WriteIdentifier(Identifier identifier, TextTokenType tokenType)
        {
            if (tokenType == TextTokenType.Text)
            {
                tokenType = TextTokenHelper.GetTextTokenType(identifier.AnnotationVT <TextTokenType>() ?? identifier.Annotation <object>());
            }

            var definition = GetCurrentDefinition(identifier);

            if (definition != null)
            {
                output.WriteDefinition(IdentifierEscaper.Escape(identifier.Name), definition, tokenType, false);
                return;
            }

            object memberRef = GetCurrentMemberReference();

            if (memberRef != null)
            {
                output.WriteReference(IdentifierEscaper.Escape(identifier.Name), memberRef, tokenType);
                return;
            }

            definition = GetCurrentLocalDefinition();
            if (definition != null)
            {
                output.WriteDefinition(IdentifierEscaper.Escape(identifier.Name), definition, tokenType);
                return;
            }

            memberRef = GetCurrentLocalReference();
            if (memberRef != null)
            {
                output.WriteReference(IdentifierEscaper.Escape(identifier.Name), memberRef, tokenType, true);
                return;
            }

            if (firstUsingDeclaration)
            {
                output.MarkFoldStart(defaultCollapsed: true);
                firstUsingDeclaration = false;
            }

            output.Write(IdentifierEscaper.Escape(identifier.Name), tokenType);
        }
Exemplo n.º 12
0
        public void WriteIdentifier(string identifier)
        {
            identifier = CSharpOutputVisitor.ConvertString(identifier);

            var definition = GetCurrentDefinition();

            if (definition != null)
            {
                output.WriteDefinition(identifier, definition, false);
                return;
            }

            object memberRef = GetCurrentMemberReference();

            if (memberRef != null)
            {
                output.WriteReference(identifier, memberRef);
                return;
            }

            definition = GetCurrentLocalDefinition();
            if (definition != null)
            {
                output.WriteDefinition(identifier, definition);
                return;
            }

            memberRef = GetCurrentLocalReference();
            if (memberRef != null)
            {
                output.WriteReference(identifier, memberRef, true);
                return;
            }

            if (firstUsingDeclaration)
            {
                output.MarkFoldStart(defaultCollapsed: true);
                firstUsingDeclaration = false;
            }

            output.Write(identifier);
        }
Exemplo n.º 13
0
        public void WriteIdentifier(string identifier)
        {
            var definition = GetCurrentDefinition();

            if (definition != null)
            {
                output.WriteDefinition(identifier, definition);
                return;
            }

            object memberRef = GetCurrentMemberReference();

            if (memberRef != null)
            {
                output.WriteReference(identifier, memberRef);
                return;
            }

            definition = GetCurrentLocalDefinition();
            if (definition != null)
            {
                output.WriteDefinition(identifier, definition);
                return;
            }

            memberRef = GetCurrentLocalReference();
            if (memberRef != null)
            {
                output.WriteReference(identifier, memberRef, true);
                return;
            }

            if (firstImport)
            {
                output.MarkFoldStart(defaultCollapsed: true);
                firstImport = false;
            }

            output.Write(identifier);
        }
Exemplo n.º 14
0
        public override void WriteIdentifier(Identifier identifier)
        {
            var definition = GetCurrentDefinition();

            if (definition != null)
            {
                output.WriteDefinition(identifier.Name, definition, false);
                return;
            }

            object memberRef = GetCurrentMemberReference();

            if (memberRef != null)
            {
                output.WriteReference(identifier.Name, memberRef);
                return;
            }

            definition = GetCurrentLocalDefinition();
            if (definition != null)
            {
                output.WriteDefinition(identifier.Name, definition);
                return;
            }

            memberRef = GetCurrentLocalReference();
            if (memberRef != null)
            {
                output.WriteReference(identifier.Name, memberRef, true);
                return;
            }

            if (firstUsingDeclaration)
            {
                output.MarkFoldStart(defaultCollapsed: true);
                firstUsingDeclaration = false;
            }

            output.Write(identifier.Name);
        }
Exemplo n.º 15
0
 public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
 {
     output.Write("switch (");
     value.WriteTo(output, options);
     output.Write(") ");
     output.MarkFoldStart("{...}");
     output.WriteLine("{");
     output.Indent();
     output.Write("default: ");
     defaultBody.WriteTo(output, options);
     output.WriteLine();
     foreach (var section in this.Sections)
     {
         section.WriteTo(output, options);
         output.WriteLine();
     }
     output.Unindent();
     output.Write('}');
     output.MarkFoldEnd();
 }
Exemplo n.º 16
0
        public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
        {
            WriteILRange(output, options);
            output.Write("Block ");
            output.WriteLocalReference(Label, this, isDefinition: true);
            if (Kind != BlockKind.ControlFlow)
            {
                output.Write($" ({Kind})");
            }
            if (Parent is BlockContainer)
            {
                output.Write(" (incoming: {0})", IncomingEdgeCount);
            }
            output.Write(' ');
            output.MarkFoldStart("{...}");
            output.WriteLine("{");
            output.Indent();
            int index = 0;

            foreach (var inst in Instructions)
            {
                if (options.ShowChildIndexInBlock)
                {
                    output.Write("[" + index + "] ");
                    index++;
                }
                inst.WriteTo(output, options);
                output.WriteLine();
            }
            if (finalInstruction.OpCode != OpCode.Nop)
            {
                output.Write("final: ");
                finalInstruction.WriteTo(output, options);
                output.WriteLine();
            }
            output.Unindent();
            output.Write("}");
            output.MarkFoldEnd();
        }
Exemplo n.º 17
0
 public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
 {
     WriteILRange(output, options);
     output.Write("switch");
     if (IsLifted)
     {
         output.Write(".lifted");
     }
     output.Write(" (");
     value.WriteTo(output, options);
     output.Write(") ");
     output.MarkFoldStart("{...}");
     output.WriteLine("{");
     output.Indent();
     foreach (var section in this.Sections)
     {
         section.WriteTo(output, options);
         output.WriteLine();
     }
     output.Unindent();
     output.Write('}');
     output.MarkFoldEnd();
 }
Exemplo n.º 18
0
        public override void WriteIdentifier(Identifier identifier)
        {
            if (identifier.IsVerbatim || CSharpOutputVisitor.IsKeyword(identifier.Name, identifier))
            {
                output.Write('@');
            }

            var definition = GetCurrentDefinition();

            if (definition != null)
            {
                output.WriteDefinition(identifier.Name, definition, false);
                return;
            }

            var member = GetCurrentMemberReference();

            if (member != null)
            {
                MemberReference cecil;
                if (member is IType type)
                {
                    cecil = typeSystem.GetCecil(type.GetDefinition());
                }
                else if (member is IMember)
                {
                    cecil = typeSystem.GetCecil((IMember)member);
                }
                else
                {
                    cecil = null;
                }
                if (cecil != null)
                {
                    output.WriteReference(identifier.Name, cecil);
                    return;
                }
            }

            definition = GetCurrentLocalDefinition();
            if (definition != null)
            {
                output.WriteDefinition(identifier.Name, definition);
                return;
            }

            var memberRef = GetCurrentLocalReference();

            if (memberRef != null)
            {
                output.WriteReference(identifier.Name, memberRef, true);
                return;
            }

            if (firstUsingDeclaration)
            {
                output.MarkFoldStart(defaultCollapsed: true);
                firstUsingDeclaration = false;
            }

            output.Write(identifier.Name);
        }
Exemplo n.º 19
0
        public override void WriteTo(ITextOutput output, ILAstWritingOptions options)
        {
            WriteILRange(output, options);
            output.Write(OpCode);
            if (Method != null)
            {
                output.Write(' ');
                Method.WriteTo(output);
            }
            if (IsExpressionTree)
            {
                output.Write(".ET");
            }
            if (DelegateType != null)
            {
                output.Write("[");
                DelegateType.WriteTo(output);
                output.Write("]");
            }
            output.WriteLine(" {");
            output.Indent();

            if (IsAsync)
            {
                output.WriteLine(".async");
            }
            if (IsIterator)
            {
                output.WriteLine(".iterator");
            }

            output.MarkFoldStart(Variables.Count + " variable(s)", true);
            foreach (var variable in Variables)
            {
                variable.WriteDefinitionTo(output);
                output.WriteLine();
            }
            output.MarkFoldEnd();
            output.WriteLine();

            foreach (string warning in Warnings)
            {
                output.WriteLine("//" + warning);
            }

            body.WriteTo(output, options);
            output.WriteLine();

            if (options.ShowILRanges)
            {
                var unusedILRanges = FindUnusedILRanges();
                if (!unusedILRanges.IsEmpty)
                {
                    output.Write("// Unused IL Ranges: ");
                    output.Write(string.Join(", ", unusedILRanges.Intervals.Select(
                                                 range => $"[{range.Start:x4}..{range.InclusiveEnd:x4}]")));
                    output.WriteLine();
                }
            }

            output.Unindent();
            output.WriteLine("}");
        }
Exemplo n.º 20
0
 public void MarkFoldStart(string collapsedText = "...", bool defaultCollapsed = false)
 {
     _wrapped.MarkFoldStart(collapsedText, defaultCollapsed);
 }
Exemplo n.º 21
0
 public void MarkFoldStart(string collapsedText, bool defaultCollapsed)
 {
     output.MarkFoldStart(collapsedText, defaultCollapsed);
 }
Exemplo n.º 22
0
        public void DisassembleType(TypeDefinition type)
        {
            // create IL code mappings - used for debugger
            if (this.CodeMappings == null)
            {
                this.CodeMappings = new Tuple <string, List <MemberMapping> >(type.FullName, new List <MemberMapping>());
            }

            // start writing IL
            output.WriteDefinition(".class ", type);

            if ((type.Attributes & TypeAttributes.ClassSemanticMask) == TypeAttributes.Interface)
            {
                output.Write("interface ");
            }
            WriteEnum(type.Attributes & TypeAttributes.VisibilityMask, typeVisibility);
            WriteEnum(type.Attributes & TypeAttributes.LayoutMask, typeLayout);
            WriteEnum(type.Attributes & TypeAttributes.StringFormatMask, typeStringFormat);
            const TypeAttributes masks = TypeAttributes.ClassSemanticMask | TypeAttributes.VisibilityMask | TypeAttributes.LayoutMask | TypeAttributes.StringFormatMask;

            WriteFlags(type.Attributes & ~masks, typeAttributes);

            output.Write(DisassemblerHelpers.Escape(type.Name));
            WriteTypeParameters(output, type);
            output.MarkFoldStart(defaultCollapsed: isInType);
            output.WriteLine();

            if (type.BaseType != null)
            {
                output.Indent();
                output.Write("extends ");
                type.BaseType.WriteTo(output, true);
                output.WriteLine();
                output.Unindent();
            }
            if (type.HasInterfaces)
            {
                output.Indent();
                for (int index = 0; index < type.Interfaces.Count; index++)
                {
                    if (index > 0)
                    {
                        output.WriteLine(",");
                    }
                    if (index == 0)
                    {
                        output.Write("implements ");
                    }
                    else
                    {
                        output.Write("           ");
                    }
                    if (type.Interfaces[index].Namespace != null)
                    {
                        output.Write("{0}.", type.Interfaces[index].Namespace);
                    }
                    output.Write(type.Interfaces[index].Name);
                }
                output.WriteLine();
                output.Unindent();
            }

            output.WriteLine("{");
            output.Indent();
            bool oldIsInType = isInType;

            isInType = true;
            WriteAttributes(type.CustomAttributes);
            if (type.HasLayoutInfo)
            {
                output.WriteLine(".pack {0}", type.PackingSize);
                output.WriteLine(".size {0}", type.ClassSize);
                output.WriteLine();
            }
            if (type.HasNestedTypes)
            {
                output.WriteLine("// Nested Types");
                foreach (var nestedType in type.NestedTypes)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    DisassembleType(nestedType);
                    output.WriteLine();
                }
                output.WriteLine();
            }
            if (type.HasFields)
            {
                output.WriteLine("// Fields");
                foreach (var field in type.Fields)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    DisassembleField(field);
                }
                output.WriteLine();
            }
            if (type.HasProperties)
            {
                output.WriteLine("// Properties");
                foreach (var prop in type.Properties)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    DisassembleProperty(prop);
                }
                output.WriteLine();
            }
            if (type.HasEvents)
            {
                output.WriteLine("// Events");
                foreach (var ev in type.Events)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    DisassembleEvent(ev);
                    output.WriteLine();
                }
                output.WriteLine();
            }
            if (type.HasMethods)
            {
                output.WriteLine("// Methods");
                var accessorMethods = type.GetAccessorMethods();
                foreach (var m in type.Methods)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    if (!(detectControlStructure && accessorMethods.Contains(m)))
                    {
                        DisassembleMethod(m);
                        output.WriteLine();
                    }
                }
            }
            CloseBlock("End of class " + type.FullName);
            isInType = oldIsInType;
        }
Exemplo n.º 23
0
 public void MarkFoldStart(string collapsedText = "...", bool defaultCollapsed = false)
 {
     actions.Add(target => target.MarkFoldStart(collapsedText, defaultCollapsed));
 }
Exemplo n.º 24
0
 void ITextOutput.MarkFoldStart(string collapsedText, bool defaultCollapsed) => _inner.MarkFoldStart(collapsedText, defaultCollapsed);
 public void MarkFoldStart()
 {
     output.MarkFoldStart();
 }
Exemplo n.º 26
0
		public void DisassembleType(TypeDefinition type)
		{
			output.WriteDefinition(".class ", type);
			
			if ((type.Attributes & TypeAttributes.ClassSemanticMask) == TypeAttributes.Interface)
				output.Write("interface ");
			WriteEnum(type.Attributes & TypeAttributes.VisibilityMask, typeVisibility);
			WriteEnum(type.Attributes & TypeAttributes.LayoutMask, typeLayout);
			WriteEnum(type.Attributes & TypeAttributes.StringFormatMask, typeStringFormat);
			const TypeAttributes masks = TypeAttributes.ClassSemanticMask | TypeAttributes.VisibilityMask | TypeAttributes.LayoutMask | TypeAttributes.StringFormatMask;
			WriteFlags(type.Attributes & ~masks, typeAttributes);
			
			output.Write(DisassemblerHelpers.Escape(type.Name));
			output.MarkFoldStart(defaultCollapsed: isInType);
			output.WriteLine();
			
			if (type.BaseType != null) {
				output.Indent();
				output.Write("extends ");
				type.BaseType.WriteTo(output, true);
				output.WriteLine();
				output.Unindent();
			}
			
			output.WriteLine("{");
			output.Indent();
			bool oldIsInType = isInType;
			isInType = true;
			WriteAttributes(type.CustomAttributes);
			if (type.HasLayoutInfo) {
				output.WriteLine(".pack {0}", type.PackingSize);
				output.WriteLine(".size {0}", type.ClassSize);
				output.WriteLine();
			}
			if (type.HasNestedTypes) {
				output.WriteLine("// Nested Types");
				foreach (var nestedType in type.NestedTypes) {
					cancellationToken.ThrowIfCancellationRequested();
					DisassembleType(nestedType);
					output.WriteLine();
				}
				output.WriteLine();
			}
			if (type.HasFields) {
				output.WriteLine("// Fields");
				foreach (var field in type.Fields) {
					cancellationToken.ThrowIfCancellationRequested();
					DisassembleField(field);
				}
				output.WriteLine();
			}
			if (type.HasProperties) {
				output.WriteLine("// Properties");
				foreach (var prop in type.Properties) {
					cancellationToken.ThrowIfCancellationRequested();
					DisassembleProperty(prop);
				}
				output.WriteLine();
			}
			if (type.HasEvents) {
				output.WriteLine("// Events");
				foreach (var ev in type.Events) {
					cancellationToken.ThrowIfCancellationRequested();
					DisassembleEvent(ev);
					output.WriteLine();
				}
				output.WriteLine();
			}
			if (type.HasMethods) {
				output.WriteLine("// Methods");
				var accessorMethods = type.GetAccessorMethods();
				foreach (var m in type.Methods) {
					cancellationToken.ThrowIfCancellationRequested();
					if (!(detectControlStructure && accessorMethods.Contains(m))) {
						DisassembleMethod(m);
						output.WriteLine();
					}
				}
			}
			CloseBlock("End of class " + type.FullName);
			isInType = oldIsInType;
		}