public static ILSpyUnresolvedFile Create(DecompiledTypeReference name, AstBuilder builder) { var writer = new StringWriter(); var target = new TextWriterTokenWriter(writer) { IndentationString = "\t" }; var output = new DebugInfoTokenWriterDecorator(TokenWriter.WrapInWriterThatSetsLocationsInAST(target)); builder.RunTransformations(); var syntaxTree = builder.SyntaxTree; syntaxTree.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true }); syntaxTree.AcceptVisitor(new CSharpOutputVisitor(output, FormattingOptionsFactory.CreateSharpDevelop())); ILSpyUnresolvedFile file = new ILSpyUnresolvedFile(name); var v = new TypeSystemConvertVisitor(file); syntaxTree.AcceptVisitor(v); file.MemberLocations = output.MemberLocations; file.DebugSymbols = output.DebugSymbols; file.output = writer.ToString(); return(file); }
public void ConvertType(IType type, TextWriterTokenWriter formatter, CSharpFormattingOptions formattingPolicy) { TypeSystemAstBuilder astBuilder = CreateAstBuilder(); AstType astType = astBuilder.ConvertType(type); astType.AcceptVisitor(new CSharpOutputVisitor(formatter, formattingPolicy)); }
static string CleanUpVariableName(string name) { // remove the backtick (generics) int pos = name.IndexOf('`'); if (pos >= 0) { name = name.Substring(0, pos); } // remove field prefix: if (name.Length > 2 && name.StartsWith("m_", StringComparison.Ordinal)) { name = name.Substring(2); } else if (name.Length > 1 && name[0] == '_' && (char.IsLetter(name[1]) || name[1] == '_')) { name = name.Substring(1); } if (TextWriterTokenWriter.ContainsNonPrintableIdentifierChar(name)) { return(null); } if (name.Length == 0) { return("obj"); } else { return(char.ToLower(name[0]) + name.Substring(1)); } }
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); }
static void WriteCode(TextWriter output, DecompilerSettings settings, SyntaxTree syntaxTree, IDecompilerTypeSystem typeSystem) { syntaxTree.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true }); TokenWriter tokenWriter = new TextWriterTokenWriter(output); tokenWriter = TokenWriter.WrapInWriterThatSetsLocationsInAST(tokenWriter); syntaxTree.AcceptVisitor(new CSharpOutputVisitor(tokenWriter, settings.CSharpFormattingOptions)); }
public static string FormatValue(Thread evalThread, Value val) { if (val.IsNull) { return("null"); } else if (val.Type.Kind == TypeKind.Array) { StringBuilder sb = new StringBuilder(); sb.Append(new CSharpAmbience().ConvertType(val.Type)); sb.Append(" {"); bool first = true; int size = val.ArrayLength; for (int i = 0; i < size; i++) { if (!first) { sb.Append(", "); } first = false; sb.Append(FormatValue(evalThread, val.GetElementAtPosition(i))); } sb.Append("}"); return(sb.ToString()); } else if (val.Type.GetAllBaseTypeDefinitions().Any(def => def.IsKnownType(KnownTypeCode.ICollection))) { StringBuilder sb = new StringBuilder(); sb.Append(new CSharpAmbience().ConvertType(val.Type)); sb.Append(" {"); val = val.GetPermanentReference(evalThread); var countProp = val.Type.GetProperties(p => p.Name == "Count" && !p.IsExplicitInterfaceImplementation).Single(); int count = (int)val.GetMemberValue(evalThread, countProp).PrimitiveValue; for (int i = 0; i < count; i++) { if (i > 0) { sb.Append(", "); } var itemProperty = val.Type.GetProperties(p => p.IsIndexer && p.Name == "Item" && !p.IsExplicitInterfaceImplementation).Single(); Value item = val.GetPropertyValue(evalThread, itemProperty, Eval.CreateValue(evalThread, i)); sb.Append(FormatValue(evalThread, item)); } sb.Append("}"); return(sb.ToString()); } else if (val.Type.IsKnownType(KnownTypeCode.String) || val.Type.IsPrimitiveType()) { return(TextWriterTokenWriter.PrintPrimitiveValue(val.PrimitiveValue)); } else { return(val.InvokeToString(evalThread)); } }
void PrintModifiers(Modifiers modifiers, TextWriterTokenWriter formatter) { foreach (var m in CSharpModifierToken.AllModifiers) { if ((modifiers & m) == m) { formatter.WriteToken(TypeDeclaration.ModifierRole, CSharpModifierToken.GetModifierName(m)); formatter.Space(); } } }
public string OutputNode(AstNode node) { using (var stringWriter = new System.IO.StringWriter()) { var formatter = new TextWriterTokenWriter(stringWriter); // formatter.Indentation = indentLevel; stringWriter.NewLine = Document.Editor.EolMarker; var visitor = new CSharpOutputVisitor(formatter, FormattingOptionsFactory.CreateMono()); node.AcceptVisitor(visitor); return(stringWriter.ToString()); } }
static string OutputNode(MonoDevelop.Ide.Gui.Document doc, AstNode node) { using (var stringWriter = new System.IO.StringWriter()) { // formatter.Indentation = indentLevel; var formatter = new TextWriterTokenWriter(stringWriter); stringWriter.NewLine = doc.Editor.EolMarker; var visitor = new CSharpOutputVisitor(formatter, doc.GetFormattingOptions()); node.AcceptVisitor(visitor); return(stringWriter.ToString()); } }
public override RichText GetRichTextTooltip(IEntity entity) { var flags = ConversionFlags.All & ~(ConversionFlags.ShowBody | ConversionFlags.PlaceReturnTypeAfterParameterList); var output = new StringWriter(); var decoratedWriter = new TextWriterTokenWriter(output); var writer = new CSharpHighlightingTokenWriter(TokenWriter.InsertRequiredSpaces(decoratedWriter), locatable: decoratedWriter); new CSharpAmbience() { ConversionFlags = flags }.ConvertSymbol(entity, writer, new DecompilerSettings().CSharpFormattingOptions); return(new RichText(output.ToString(), writer.HighlightingModel)); }
public string Generate(ISymbol symbol) { if (symbol == null) { throw new ArgumentNullException("symbol"); } StringWriter writer = new StringWriter(); _writer = new TextWriterTokenWriter(writer); _policy = FormattingOptionsFactory.CreateMono(); TypeSystemAstBuilder astBuilder = CreateAstBuilder(); astBuilder.AlwaysUseShortTypeNames = true; AstNode node = astBuilder.ConvertSymbol(symbol); if (symbol is ITypeDefinition) { WriteTypeDeclarationName((ITypeDefinition)symbol, _writer, _policy); } else if (symbol is IMember) { WriteMemberDeclarationName((IMember)symbol, _writer, _policy); } else { _writer.WriteIdentifier(Identifier.Create(symbol.Name)); } if (HasParameters(symbol)) { _writer.WriteToken(symbol.SymbolKind == SymbolKind.Indexer ? Roles.LBracket : Roles.LPar, symbol.SymbolKind == SymbolKind.Indexer ? "[" : "("); IEnumerable <ParameterDeclaration> parameters = new List <ParameterDeclaration>(node.GetChildrenByRole(Roles.Parameter)); if (symbol is IMethod && ((IMethod)symbol).IsExtensionMethod) { parameters = parameters.Skip(1); } WriteCommaSeparatedList(parameters); _writer.WriteToken(symbol.SymbolKind == SymbolKind.Indexer ? Roles.RBracket : Roles.RPar, symbol.SymbolKind == SymbolKind.Indexer ? "]" : ")"); } if (_includePlaceholders) { _writer.WriteToken(Roles.Text, "$0"); } return(writer.ToString()); }
static string ToString(object val) { if (val == null) { return("null"); } else if (val is string) { return("\"" + TextWriterTokenWriter.ConvertString((string)val) + "\""); } else if (val is char) { return("'" + TextWriterTokenWriter.ConvertChar((char)val) + "'"); } else { return(val.ToString()); } }
void AppendReturnType(StringBuilder result, CodeGenerationOptions options, IType type) { if (type == null) { throw new ArgumentNullException("type"); } var implementingType = options.Part; var loc = implementingType.Region.End; var pf = implementingType.UnresolvedFile; var file = pf as CSharpUnresolvedFile; var resolved = type; if (resolved.Kind == TypeKind.Unknown) { result.Append(type.FullName); return; } var def = type.GetDefinition(); if (def != null) { using (var stringWriter = new System.IO.StringWriter()) { var formatter = new TextWriterTokenWriter(stringWriter); stringWriter.NewLine = EolMarker; var visitor = new CSharpOutputVisitor(formatter, FormattingOptionsFactory.CreateMono()); var shortType = CreateShortType(def.Compilation, file, loc, resolved); shortType.AcceptVisitor(visitor); var typeString = stringWriter.ToString(); if (typeString.StartsWith("global::")) { typeString = typeString.Substring("global::".Length); } result.Append(typeString); } } else { result.Append(new ICSharpCode.NRefactory.CSharp.CSharpAmbience().ConvertType(type)); } }
void WriteTypeDeclarationName(ITypeDefinition typeDef, TextWriterTokenWriter formatter, CSharpFormattingOptions formattingPolicy) { TypeSystemAstBuilder astBuilder = CreateAstBuilder(); if (typeDef.DeclaringTypeDefinition != null) { WriteTypeDeclarationName(typeDef.DeclaringTypeDefinition, formatter, formattingPolicy); formatter.WriteToken(Roles.Dot, "."); } else if ((ConversionFlags & ConversionFlags.UseFullyQualifiedTypeNames) == ConversionFlags.UseFullyQualifiedTypeNames) { formatter.WriteIdentifier(Identifier.Create(typeDef.Namespace)); formatter.WriteToken(Roles.Dot, "."); } formatter.WriteIdentifier(Identifier.Create(typeDef.Name)); if ((ConversionFlags & ConversionFlags.ShowTypeParameterList) == ConversionFlags.ShowTypeParameterList) { var outputVisitor = new CSharpOutputVisitor(formatter, formattingPolicy); outputVisitor.WriteTypeParameters(astBuilder.ConvertEntity(typeDef).GetChildrenByRole(Roles.TypeParameter)); } }
private void TestCreateSequencePoints(string code, params string[] expectedSequencePoints) { var decompiler = Tester.GetDecompilerForSnippet(code); var firstType = decompiler.TypeSystem.Compilation.GetTopLevelTypeDefinitions().First(t => code.Contains(t.Name)); var tree = decompiler.DecompileType(firstType.FullTypeName); var output = new StringWriter(); tree.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true }); TokenWriter tokenWriter = new TextWriterTokenWriter(output); tokenWriter = new InsertMissingTokensDecorator(tokenWriter, (ILocatable)tokenWriter); var formattingOptions = FormattingOptionsFactory.CreateSharpDevelop(); tree.AcceptVisitor(new CSharpOutputVisitor(tokenWriter, formattingOptions)); var functionsWithSequencePoints = decompiler.CreateSequencePoints(tree); var finalText = output.ToString(); var lines = finalText.Split(new[] { output.NewLine }, StringSplitOptions.None); var actualSequencePoints = new List <string>(); foreach (var sequencePoint in functionsWithSequencePoints.Values.First()) { if (sequencePoint.IsHidden) { continue; } var line = lines[sequencePoint.StartLine - 1]; var text = line.Substring(sequencePoint.StartColumn - 1, sequencePoint.EndColumn - sequencePoint.StartColumn); actualSequencePoints.Add(text); } Assert.True(Enumerable.SequenceEqual(expectedSequencePoints, actualSequencePoints)); }
public string ConvertSymbol(ISymbol symbol) { var stringWriter = new StringWriter(); var astBuilder = new TypeSystemAstBuilder(); astBuilder.AlwaysUseShortTypeNames = true; AstNode node = astBuilder.ConvertSymbol(symbol); var writer = new TextWriterTokenWriter(stringWriter); var rt = node.GetChildByRole(Roles.Type); if (!rt.IsNull) { rt.AcceptVisitor(new CSharpOutputVisitor(stringWriter, FormattingOptionsFactory.CreateMono())); } IProperty property = symbol as IProperty; if (property != null) { writer.Space(); writer.WriteToken(Roles.LBrace, "{"); writer.Space(); if (property.CanGet) { writer.WriteKeyword(PropertyDeclaration.GetKeywordRole, "get"); writer.WriteToken(Roles.Semicolon, ";"); writer.Space(); } if (property.CanSet) { writer.WriteKeyword(PropertyDeclaration.SetKeywordRole, "set"); writer.WriteToken(Roles.Semicolon, ";"); writer.Space(); } writer.WriteToken(Roles.RBrace, "}"); } return(stringWriter.ToString()); }
void WriteStringId(BamlContext ctx, ushort id) { string str; if (id > 0x7fff) { str = ctx.KnownThings.Strings((short)-id); } else if (ctx.StringIdMap.ContainsKey(id)) { str = ctx.StringIdMap[id].Value; } else { str = null; } string reference = null; if (str != null) { reference = string.Format("\"{0}\"", TextWriterTokenWriter.ConvertString(str)); } output.WriteReference(string.Format("0x{0:x4}", id), reference, TextTokenType.Number, true); }
public void ConvertEntity(IEntity entity, TextWriterTokenWriter formatter, CSharpFormattingOptions formattingPolicy) { if (entity == null) { throw new ArgumentNullException("entity"); } if (formatter == null) { throw new ArgumentNullException("formatter"); } if (formattingPolicy == null) { throw new ArgumentNullException("options"); } TypeSystemAstBuilder astBuilder = CreateAstBuilder(); EntityDeclaration node = astBuilder.ConvertEntity(entity); PrintModifiers(node.Modifiers, formatter); if ((ConversionFlags & ConversionFlags.ShowDefinitionKeyword) == ConversionFlags.ShowDefinitionKeyword) { if (node is TypeDeclaration) { switch (((TypeDeclaration)node).ClassType) { case ClassType.Class: formatter.WriteKeyword(Roles.ClassKeyword, "class"); break; case ClassType.Struct: formatter.WriteKeyword(Roles.StructKeyword, "struct"); break; case ClassType.Interface: formatter.WriteKeyword(Roles.InterfaceKeyword, "interface"); break; case ClassType.Enum: formatter.WriteKeyword(Roles.EnumKeyword, "enum"); break; default: throw new Exception("Invalid value for ClassType"); } formatter.Space(); } else if (node is DelegateDeclaration) { formatter.WriteKeyword(Roles.DelegateKeyword, "delegate"); formatter.Space(); } else if (node is EventDeclaration) { formatter.WriteKeyword(EventDeclaration.EventKeywordRole, "event"); formatter.Space(); } } if ((ConversionFlags & ConversionFlags.ShowReturnType) == ConversionFlags.ShowReturnType) { var rt = node.GetChildByRole(Roles.Type); if (!rt.IsNull) { rt.AcceptVisitor(new CSharpOutputVisitor(formatter, formattingPolicy)); formatter.Space(); } } if (entity is ITypeDefinition) { WriteTypeDeclarationName((ITypeDefinition)entity, formatter, formattingPolicy); } else { WriteMemberDeclarationName((IMember)entity, formatter, formattingPolicy); } if ((ConversionFlags & ConversionFlags.ShowParameterList) == ConversionFlags.ShowParameterList && HasParameters(entity)) { if (entity.SymbolKind == SymbolKind.Indexer) { formatter.WriteToken(Roles.LBracket, "["); } else { formatter.WriteToken(Roles.LBrace, "("); } bool first = true; foreach (var param in node.GetChildrenByRole(Roles.Parameter)) { if (first) { first = false; } else { formatter.WriteToken(Roles.Comma, ","); formatter.Space(); } param.AcceptVisitor(new CSharpOutputVisitor(formatter, formattingPolicy)); } if (entity.SymbolKind == SymbolKind.Indexer) { formatter.WriteToken(Roles.RBracket, "]"); } else { formatter.WriteToken(Roles.RBrace, ")"); } } if ((ConversionFlags & ConversionFlags.ShowBody) == ConversionFlags.ShowBody && !(node is TypeDeclaration)) { IProperty property = entity as IProperty; if (property != null) { formatter.Space(); formatter.WriteToken(Roles.LBrace, "{"); formatter.Space(); if (property.CanGet) { formatter.WriteKeyword(PropertyDeclaration.GetKeywordRole, "get"); formatter.WriteToken(Roles.Semicolon, ";"); formatter.Space(); } if (property.CanSet) { formatter.WriteKeyword(PropertyDeclaration.SetKeywordRole, "set"); formatter.WriteToken(Roles.Semicolon, ";"); formatter.Space(); } formatter.WriteToken(Roles.RBrace, "}"); } else { formatter.WriteToken(Roles.Semicolon, ";"); } } }
static int Main(string[] args) { var assemblyFilenameOption = new Option <FileInfo>( new[] { "--assembly", "-a" }, description: "The assembly to decompile into XML."); var verboseOption = new Option <bool>( new[] { "--verbose", "-v" }, description: "Provide output as code is running."); var outputOption = new Option <DirectoryInfo>( new[] { "--output", "-o" }, description: "The root directory where the XML files will be written. The directory must exist."); var rootCommand = new RootCommand { assemblyFilenameOption, verboseOption, outputOption, }; rootCommand.Description = "Command to extract C# code into XML suitable for reasoning."; rootCommand.SetHandler((FileInfo assemblyFile, bool verbose, DirectoryInfo outputDirectory) => { if (assemblyFile == null) { Console.Error.WriteLine("No assembly provided to extract"); return; } if (outputDirectory == null) { Console.Error.WriteLine("No target directory provided"); return; } // Set up the preferences for the decompilation of the IL into source. var settings = new DecompilerSettings() { AlwaysUseBraces = true, ShowXmlDocumentation = true }; settings.CSharpFormattingOptions.IndentationString = " "; var decompiler = new CSharpDecompiler(assemblyFile.FullName, settings); // Traverse all the types in the assembly foreach (var typeDefinition in decompiler.TypeSystem.MainModule.TopLevelTypeDefinitions) { if (typeDefinition.Name.StartsWith("<")) { continue; } if (verbose) { Console.WriteLine($"Extracting {typeDefinition.FullName}."); } var syntaxTree = decompiler.DecompileType(typeDefinition.FullTypeName); // This is needed to get the locations correctly set in the AST. StringWriter w = new StringWriter(); var q = new TextWriterTokenWriter(w); q.IndentationString = " "; TokenWriter tokenWriter = q; tokenWriter = TokenWriter.WrapInWriterThatSetsLocationsInAST(tokenWriter); syntaxTree.AcceptVisitor(new CSharpOutputVisitor(tokenWriter, settings.CSharpFormattingOptions)); var source = w.ToString(); var generator = new XmlGeneratorVisitor(assemblyFile.FullName, source); syntaxTree.AcceptVisitor(generator); File.WriteAllText(Path.Combine(outputDirectory.FullName, typeDefinition.FullTypeName.Name) + ".xml", generator.Document.ToString()); } }, assemblyFilenameOption, verboseOption, outputOption); return(rootCommand.Invoke(args)); }
void WriteDefinition(string value, string def = null) { string str = string.Format("\"{0}\"", TextWriterTokenWriter.ConvertString(value)); output.WriteDefinition(str, def ?? IdentifierEscaper.Escape(value), TextTokenType.String, true); }
public override void WritePrimitiveValue(object value, TextTokenKind?tokenKind = null, string literalValue = null) { int column = 0; TextWriterTokenWriter.WritePrimitiveValue(value, tokenKind, literalValue, ref column, (a, b) => output.Write(a, b), WriteToken); }
static string ToString(object val) { return(TextWriterTokenWriter.PrintPrimitiveValue(val)); }
public override void WriteInterpolatedText(string text) { output.Write(TextWriterTokenWriter.ConvertString(text)); }
void WriteMemberDeclarationName(IMember member, TextWriterTokenWriter formatter, CSharpFormattingOptions formattingPolicy) { TypeSystemAstBuilder astBuilder = CreateAstBuilder(); if ((ConversionFlags & ConversionFlags.ShowDeclaringType) == ConversionFlags.ShowDeclaringType) { ConvertType(member.DeclaringType, formatter, formattingPolicy); formatter.WriteToken(Roles.Dot, "."); } switch (member.SymbolKind) { case SymbolKind.Indexer: formatter.WriteKeyword(IndexerDeclaration.ThisKeywordRole, "this"); break; case SymbolKind.Constructor: formatter.WriteIdentifier(Identifier.Create(member.DeclaringType.Name)); break; case SymbolKind.Destructor: formatter.WriteToken(DestructorDeclaration.TildeRole, "~"); formatter.WriteIdentifier(Identifier.Create(member.DeclaringType.Name)); break; case SymbolKind.Operator: switch (member.Name) { case "op_Implicit": formatter.WriteKeyword(OperatorDeclaration.ImplicitRole, "implicit"); formatter.Space(); formatter.WriteKeyword(OperatorDeclaration.OperatorKeywordRole, "operator"); formatter.Space(); ConvertType(member.ReturnType, formatter, formattingPolicy); break; case "op_Explicit": formatter.WriteKeyword(OperatorDeclaration.ExplicitRole, "explicit"); formatter.Space(); formatter.WriteKeyword(OperatorDeclaration.OperatorKeywordRole, "operator"); formatter.Space(); ConvertType(member.ReturnType, formatter, formattingPolicy); break; default: formatter.WriteKeyword(OperatorDeclaration.OperatorKeywordRole, "operator"); formatter.Space(); var operatorType = OperatorDeclaration.GetOperatorType(member.Name); if (operatorType.HasValue) { formatter.WriteToken(OperatorDeclaration.GetRole(operatorType.Value), OperatorDeclaration.GetToken(operatorType.Value)); } else { formatter.WriteIdentifier(Identifier.Create(member.Name)); } break; } break; default: formatter.WriteIdentifier(Identifier.Create(member.Name)); break; } if ((ConversionFlags & ConversionFlags.ShowTypeParameterList) == ConversionFlags.ShowTypeParameterList && member.SymbolKind == SymbolKind.Method) { var outputVisitor = new CSharpOutputVisitor(formatter, formattingPolicy); outputVisitor.WriteTypeParameters(astBuilder.ConvertEntity(member).GetChildrenByRole(Roles.TypeParameter)); } }
public override void WritePrimitiveValue(object value, TextTokenType?tokenType = null, string literalValue = null) { int column = 0; TextWriterTokenWriter.WritePrimitiveValue(value, tokenType, literalValue, ref column, (a, b) => output.Write(a, b), (a, b, c) => WriteToken(a, b, c)); }
void WriteString(string value) { string str = string.Format("\"{0}\"", TextWriterTokenWriter.ConvertString(value)); output.Write(str, TextTokenType.String); }