Browse Source

Add C# semantic highlighting

pull/863/head
Siegfried Pammer 8 years ago
parent
commit
0b135c23e4
  1. 17
      ICSharpCode.Decompiler/Output/TextTokenWriter.cs
  2. 9
      ILSpy/ExtensionMethods.cs
  3. 1
      ILSpy/ILSpy.csproj
  4. 5
      ILSpy/ISmartTextOutput.cs
  5. 465
      ILSpy/Languages/CSharpLanguage.cs
  6. 26
      ILSpy/TextView/AvalonEditTextOutput.cs
  7. 136
      ILSpy/TextView/CSharp-Mode.xshd
  8. 19
      ILSpy/TextView/DecompilerTextView.cs

17
ICSharpCode.Decompiler/Output/TextTokenWriter.cs

@ -19,7 +19,6 @@ @@ -19,7 +19,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.Decompiler.CSharp.OutputVisitor;
using ICSharpCode.Decompiler.CSharp.Syntax;
@ -189,7 +188,7 @@ namespace ICSharpCode.Decompiler @@ -189,7 +188,7 @@ namespace ICSharpCode.Decompiler
var node = nodeStack.Peek();
if (node is Identifier)
node = node.Parent;
if (IsDefinition(node))
if (IsDefinition(ref node))
return node.GetSymbol();
return null;
@ -403,11 +402,17 @@ namespace ICSharpCode.Decompiler @@ -403,11 +402,17 @@ namespace ICSharpCode.Decompiler
// }
}
private static bool IsDefinition(AstNode node)
static bool IsDefinition(ref AstNode node)
{
return node is EntityDeclaration
|| (node is VariableInitializer && node.Parent is FieldDeclaration)
|| node is FixedVariableInitializer;
if (node is EntityDeclaration)
return true;
if (node is VariableInitializer && node.Parent is FieldDeclaration) {
node = node.Parent;
return true;
}
if (node is FixedVariableInitializer)
return true;
return false;
}
}
}

9
ILSpy/ExtensionMethods.cs

@ -34,7 +34,14 @@ namespace ICSharpCode.ILSpy @@ -34,7 +34,14 @@ namespace ICSharpCode.ILSpy
if (!list.Contains(item))
list.Add(item);
}
public static T PeekOrDefault<T>(this Stack<T> stack)
{
if (stack.Count == 0)
return default(T);
return stack.Peek();
}
public static int BinarySearch<T>(this IList<T> list, T item, int start, int count, IComparer<T> comparer)
{
if (list == null)

1
ILSpy/ILSpy.csproj

@ -232,6 +232,7 @@ @@ -232,6 +232,7 @@
<Resource Include="Images\ILSpy.ico" />
<Resource Include="Images\FindAssembly.png" />
<None Include="app.config" />
<EmbeddedResource Include="TextView\CSharp-Mode.xshd" />
<Resource Include="Images\Breakpoint.png" />
<Resource Include="Images\CurrentLine.png" />
<Resource Include="Images\DisabledBreakpoint.png" />

5
ILSpy/ISmartTextOutput.cs

@ -21,7 +21,7 @@ using System.Windows; @@ -21,7 +21,7 @@ using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.Decompiler;
namespace ICSharpCode.ILSpy
@ -35,6 +35,9 @@ namespace ICSharpCode.ILSpy @@ -35,6 +35,9 @@ namespace ICSharpCode.ILSpy
/// Inserts an interactive UI element at the current position in the text output.
/// </summary>
void AddUIElement(Func<UIElement> element);
void BeginSpan(HighlightingColor highlightingColor);
void EndSpan();
}
public static class SmartTextOutputExtensions

465
ILSpy/Languages/CSharpLanguage.cs

@ -35,6 +35,8 @@ using System.Windows; @@ -35,6 +35,8 @@ using System.Windows;
using System.Windows.Controls;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.Decompiler.CSharp.Transforms;
using ICSharpCode.AvalonEdit.Highlighting;
using System.Windows.Media;
namespace ICSharpCode.ILSpy
{
@ -96,9 +98,11 @@ namespace ICSharpCode.ILSpy @@ -96,9 +98,11 @@ namespace ICSharpCode.ILSpy
void WriteCode(ITextOutput output, DecompilerSettings settings, SyntaxTree syntaxTree, IDecompilerTypeSystem typeSystem)
{
syntaxTree.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true });
var outputFormatter = new TextTokenWriter(output, settings, typeSystem) { FoldBraces = settings.FoldBraces };
var formattingPolicy = settings.CSharpFormattingOptions;
syntaxTree.AcceptVisitor(new CSharpOutputVisitor(outputFormatter, formattingPolicy));
TokenWriter tokenWriter = new TextTokenWriter(output, settings, typeSystem) { FoldBraces = settings.FoldBraces };
if (output is ISmartTextOutput highlightingOutput) {
tokenWriter = new HighlightingTokenWriter(tokenWriter, highlightingOutput);
}
syntaxTree.AcceptVisitor(new CSharpOutputVisitor(tokenWriter, settings.CSharpFormattingOptions));
}
public override void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options)
@ -396,25 +400,6 @@ namespace ICSharpCode.ILSpy @@ -396,25 +400,6 @@ namespace ICSharpCode.ILSpy
}
}
/*
AstBuilder CreateAstBuilder(DecompilationOptions options, ModuleDefinition currentModule = null, TypeDefinition currentType = null, bool isSingleMember = false)
{
if (currentModule == null)
currentModule = currentType.Module;
DecompilerSettings settings = options.DecompilerSettings;
if (isSingleMember) {
settings = settings.Clone();
settings.UsingDeclarations = false;
}
return new AstBuilder(
new DecompilerContext(currentModule) {
CancellationToken = options.CancellationToken,
CurrentType = currentType,
Settings = settings
});
}
*/
public override string TypeToString(TypeReference type, bool includeNamespace, ICustomAttributeProvider typeAttributes = null)
{
ConvertTypeOptions options = ConvertTypeOptions.IncludeTypeParameterDefinitions;
@ -533,5 +518,441 @@ namespace ICSharpCode.ILSpy @@ -533,5 +518,441 @@ namespace ICSharpCode.ILSpy
var flags = ConversionFlags.All & ~ConversionFlags.ShowBody;
return new CSharpAmbience() { ConversionFlags = flags }.ConvertSymbol(symbol);
}
class HighlightingTokenWriter : DecoratingTokenWriter
{
ISmartTextOutput textOutput;
HighlightingColor defaultTextColor;
HighlightingColor visibilityKeywordsColor;
HighlightingColor namespaceKeywordsColor;
HighlightingColor structureKeywordsColor;
HighlightingColor gotoKeywordsColor;
HighlightingColor queryKeywordsColor;
HighlightingColor exceptionKeywordsColor;
HighlightingColor checkedKeywordColor;
HighlightingColor unsafeKeywordsColor;
HighlightingColor valueTypeKeywordsColor;
HighlightingColor referenceTypeKeywordsColor;
HighlightingColor operatorKeywordsColor;
HighlightingColor parameterModifierColor;
HighlightingColor modifiersColor;
HighlightingColor accessorKeywordsColor;
HighlightingColor attributeKeywordsColor;
HighlightingColor referenceTypeColor;
HighlightingColor valueTypeColor;
HighlightingColor interfaceTypeColor;
HighlightingColor enumerationTypeColor;
HighlightingColor typeParameterTypeColor;
HighlightingColor delegateTypeColor;
HighlightingColor methodCallColor;
HighlightingColor methodDeclarationColor;
HighlightingColor eventDeclarationColor;
HighlightingColor eventAccessColor;
HighlightingColor propertyDeclarationColor;
HighlightingColor propertyAccessColor;
HighlightingColor fieldDeclarationColor;
HighlightingColor fieldAccessColor;
HighlightingColor variableDeclarationColor;
HighlightingColor variableAccessColor;
HighlightingColor parameterDeclarationColor;
HighlightingColor parameterAccessColor;
HighlightingColor valueKeywordColor;
HighlightingColor thisKeywordColor;
HighlightingColor trueKeywordColor;
HighlightingColor typeKeywordsColor;
HighlightingColor externAliasKeywordColor;
HighlightingColor varKeywordTypeColor;
HighlightingColor stringFormatItemColor;
public HighlightingTokenWriter(TokenWriter decoratedWriter, ISmartTextOutput textOutput) : base(decoratedWriter)
{
this.textOutput = textOutput;
var highlighting = HighlightingManager.Instance.GetDefinition("C#");
//this.defaultTextColor = ???;
this.visibilityKeywordsColor = highlighting.GetNamedColor("Visibility");
this.namespaceKeywordsColor = highlighting.GetNamedColor("NamespaceKeywords");
this.structureKeywordsColor = highlighting.GetNamedColor("Keywords");
this.gotoKeywordsColor = highlighting.GetNamedColor("GotoKeywords");
this.queryKeywordsColor = highlighting.GetNamedColor("QueryKeywords");
this.exceptionKeywordsColor = highlighting.GetNamedColor("ExceptionKeywords");
this.checkedKeywordColor = highlighting.GetNamedColor("CheckedKeyword");
this.unsafeKeywordsColor = highlighting.GetNamedColor("UnsafeKeywords");
this.valueTypeKeywordsColor = highlighting.GetNamedColor("ValueTypeKeywords");
this.referenceTypeKeywordsColor = highlighting.GetNamedColor("ReferenceTypeKeywords");
this.operatorKeywordsColor = highlighting.GetNamedColor("OperatorKeywords");
this.parameterModifierColor = highlighting.GetNamedColor("ParameterModifiers");
this.modifiersColor = highlighting.GetNamedColor("Modifiers");
this.accessorKeywordsColor = highlighting.GetNamedColor("GetSetAddRemove");
this.referenceTypeColor = highlighting.GetNamedColor("ReferenceTypes");
this.valueTypeColor = highlighting.GetNamedColor("ValueTypes");
this.interfaceTypeColor = highlighting.GetNamedColor("InterfaceTypes");
this.enumerationTypeColor = highlighting.GetNamedColor("EnumTypes");
this.typeParameterTypeColor = highlighting.GetNamedColor("TypeParameters");
this.delegateTypeColor = highlighting.GetNamedColor("DelegateTypes");
this.methodDeclarationColor = this.methodCallColor = highlighting.GetNamedColor("MethodCall");
//this.eventDeclarationColor = this.eventAccessColor = defaultTextColor;
//this.propertyDeclarationColor = this.propertyAccessColor = defaultTextColor;
this.fieldDeclarationColor = this.fieldAccessColor = highlighting.GetNamedColor("FieldAccess");
//this.variableDeclarationColor = this.variableAccessColor = defaultTextColor;
//this.parameterDeclarationColor = this.parameterAccessColor = defaultTextColor;
this.valueKeywordColor = highlighting.GetNamedColor("NullOrValueKeywords");
this.thisKeywordColor = highlighting.GetNamedColor("ThisOrBaseReference");
this.trueKeywordColor = highlighting.GetNamedColor("TrueFalse");
this.typeKeywordsColor = highlighting.GetNamedColor("TypeKeywords");
this.attributeKeywordsColor = highlighting.GetNamedColor("AttributeKeywords");
//this.externAliasKeywordColor = ...;
}
public override void WriteKeyword(Role role, string keyword)
{
HighlightingColor color = null;
switch (keyword) {
case "namespace":
case "using":
if (role == UsingStatement.UsingKeywordRole)
color = structureKeywordsColor;
else
color = namespaceKeywordsColor;
break;
case "this":
case "base":
color = thisKeywordColor;
break;
case "true":
case "false":
color = trueKeywordColor;
break;
case "public":
case "internal":
case "protected":
case "private":
color = visibilityKeywordsColor;
break;
case "if":
case "else":
case "switch":
case "case":
case "default":
case "while":
case "do":
case "for":
case "foreach":
case "lock":
case "global":
case "dynamic":
case "await":
case "where":
color = structureKeywordsColor;
break;
case "in":
if (nodeStack.PeekOrDefault() is ForeachStatement)
color = structureKeywordsColor;
else if (nodeStack.PeekOrDefault() is QueryExpression)
color = queryKeywordsColor;
else
color = parameterModifierColor;
break;
case "as":
case "is":
case "new":
case "sizeof":
case "typeof":
case "nameof":
case "stackalloc":
color = typeKeywordsColor;
break;
case "try":
case "throw":
case "catch":
case "finally":
color = exceptionKeywordsColor;
break;
case "when":
if (role == CatchClause.WhenKeywordRole)
color = exceptionKeywordsColor;
break;
case "get":
case "set":
case "add":
case "remove":
if (role == PropertyDeclaration.GetKeywordRole ||
role == PropertyDeclaration.SetKeywordRole ||
role == CustomEventDeclaration.AddKeywordRole ||
role == CustomEventDeclaration.RemoveKeywordRole)
color = accessorKeywordsColor;
break;
case "abstract":
case "const":
case "event":
case "extern":
case "override":
case "readonly":
case "sealed":
case "static":
case "virtual":
case "volatile":
case "async":
case "partial":
color = modifiersColor;
break;
case "checked":
case "unchecked":
color = checkedKeywordColor;
break;
case "fixed":
case "unsafe":
color = unsafeKeywordsColor;
break;
case "enum":
case "struct":
color = valueTypeKeywordsColor;
break;
case "class":
case "interface":
case "delegate":
color = referenceTypeKeywordsColor;
break;
case "select":
case "group":
case "by":
case "into":
case "from":
case "ascending":
case "descending":
case "orderby":
case "let":
case "join":
case "on":
case "equals":
if (nodeStack.PeekOrDefault() is QueryExpression)
color = queryKeywordsColor;
break;
case "explicit":
case "implicit":
case "operator":
color = operatorKeywordsColor;
break;
case "params":
case "ref":
case "out":
color = parameterModifierColor;
break;
case "break":
case "continue":
case "goto":
case "yield":
case "return":
color = gotoKeywordsColor;
break;
}
if (Roles.AttributeTargetRole == role)
color = attributeKeywordsColor;
if (color != null) {
textOutput.BeginSpan(color);
}
base.WriteKeyword(role, keyword);
if (color != null) {
textOutput.EndSpan();
}
}
public override void WritePrimitiveType(string type)
{
HighlightingColor color = null;
switch (type) {
case "new":
color = typeKeywordsColor;
break;
case "bool":
case "byte":
case "char":
case "decimal":
case "double":
case "enum":
case "float":
case "int":
case "long":
case "sbyte":
case "short":
case "struct":
case "uint":
case "ushort":
case "ulong":
color = valueTypeKeywordsColor;
break;
case "object":
case "string":
case "void":
color = referenceTypeKeywordsColor;
break;
}
if (color != null) {
textOutput.BeginSpan(color);
}
base.WritePrimitiveType(type);
if (color != null) {
textOutput.EndSpan();
}
}
public override void WriteIdentifier(Identifier identifier)
{
HighlightingColor color = null;
if (identifier.Name == "value" && nodeStack.PeekOrDefault() is Accessor accessor && accessor.Role != PropertyDeclaration.GetterRole)
color = valueKeywordColor;
switch (GetCurrentDefinition()) {
case ITypeDefinition t:
switch (t.Kind) {
case TypeKind.Delegate:
color = delegateTypeColor;
break;
case TypeKind.Class:
color = referenceTypeColor;
break;
case TypeKind.Interface:
color = interfaceTypeColor;
break;
case TypeKind.Enum:
color = enumerationTypeColor;
break;
case TypeKind.Struct:
color = valueTypeColor;
break;
}
break;
case IMethod m:
color = methodDeclarationColor;
break;
case IField f:
color = fieldDeclarationColor;
break;
}
switch (GetCurrentMemberReference()) {
case IType t:
switch (t.Kind) {
case TypeKind.Delegate:
color = delegateTypeColor;
break;
case TypeKind.Class:
color = referenceTypeColor;
break;
case TypeKind.Interface:
color = interfaceTypeColor;
break;
case TypeKind.Enum:
color = enumerationTypeColor;
break;
case TypeKind.Struct:
color = valueTypeColor;
break;
}
break;
case IMethod m:
color = methodCallColor;
break;
case IField f:
color = fieldAccessColor;
break;
}
if (color != null) {
textOutput.BeginSpan(color);
}
base.WriteIdentifier(identifier);
if (color != null) {
textOutput.EndSpan();
}
}
public override void WritePrimitiveValue(object value, string literalValue = null)
{
HighlightingColor color = null;
if (value is null) {
color = valueKeywordColor;
}
if (value is true || value is false) {
color = trueKeywordColor;
}
if (color != null) {
textOutput.BeginSpan(color);
}
base.WritePrimitiveValue(value, literalValue);
if (color != null) {
textOutput.EndSpan();
}
}
ISymbol GetCurrentDefinition()
{
if (nodeStack == null || nodeStack.Count == 0)
return null;
var node = nodeStack.Peek();
if (node is Identifier)
node = node.Parent;
if (IsDefinition(ref node))
return node.GetSymbol();
return null;
}
static bool IsDefinition(ref AstNode node)
{
if (node is EntityDeclaration)
return true;
if (node is VariableInitializer && node.Parent is FieldDeclaration) {
node = node.Parent;
return true;
}
if (node is FixedVariableInitializer)
return true;
return false;
}
ISymbol GetCurrentMemberReference()
{
AstNode node = nodeStack.Peek();
var symbol = node.GetSymbol();
if (symbol == null && node.Role == Roles.TargetExpression && node.Parent is InvocationExpression) {
symbol = node.Parent.GetSymbol();
}
if (symbol != null && node.Parent is ObjectCreateExpression) {
symbol = node.Parent.GetSymbol();
}
if (node is IdentifierExpression && node.Role == Roles.TargetExpression && node.Parent is InvocationExpression && symbol is IMember member) {
var declaringType = member.DeclaringType;
if (declaringType != null && declaringType.Kind == TypeKind.Delegate)
return null;
}
return symbol;
}
Stack<AstNode> nodeStack = new Stack<AstNode>();
public override void StartNode(AstNode node)
{
nodeStack.Push(node);
base.StartNode(node);
}
public override void EndNode(AstNode node)
{
base.EndNode(node);
nodeStack.Pop();
}
}
}
}

26
ILSpy/TextView/AvalonEditTextOutput.cs

@ -25,6 +25,7 @@ using System.Windows; @@ -25,6 +25,7 @@ using System.Windows;
using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.AvalonEdit.Folding;
using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.AvalonEdit.Rendering;
using TextLocation = ICSharpCode.Decompiler.CSharp.Syntax.TextLocation;
@ -91,6 +92,8 @@ namespace ICSharpCode.ILSpy.TextView @@ -91,6 +92,8 @@ namespace ICSharpCode.ILSpy.TextView
/// <summary>Embedded UIElements, see <see cref="UIElementGenerator"/>.</summary>
internal readonly List<KeyValuePair<int, Lazy<UIElement>>> UIElements = new List<KeyValuePair<int, Lazy<UIElement>>>();
public RichTextModel HighlightingModel { get; } = new RichTextModel();
public AvalonEditTextOutput()
{
@ -247,5 +250,28 @@ namespace ICSharpCode.ILSpy.TextView @@ -247,5 +250,28 @@ namespace ICSharpCode.ILSpy.TextView
this.UIElements.Add(new KeyValuePair<int, Lazy<UIElement>>(this.TextLength, new Lazy<UIElement>(element)));
}
}
readonly Stack<HighlightingColor> colorStack = new Stack<HighlightingColor>();
HighlightingColor currentColor = new HighlightingColor();
int currentColorBegin = -1;
public void BeginSpan(HighlightingColor highlightingColor)
{
WriteIndent();
if (currentColorBegin > -1)
HighlightingModel.SetHighlighting(currentColorBegin, b.Length - currentColorBegin, currentColor);
colorStack.Push(currentColor);
currentColor = currentColor.Clone();
currentColorBegin = b.Length;
currentColor.MergeWith(highlightingColor);
currentColor.Freeze();
}
public void EndSpan()
{
HighlightingModel.SetHighlighting(currentColorBegin, b.Length - currentColorBegin, currentColor);
currentColor = colorStack.Pop();
currentColorBegin = b.Length;
}
}
}

136
ILSpy/TextView/CSharp-Mode.xshd

@ -0,0 +1,136 @@ @@ -0,0 +1,136 @@
<?xml version="1.0"?>
<SyntaxDefinition name="C#" extensions=".cs" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008">
<!-- This is a variant of the AvalonEdit C# highlighting that has several constructs disabled.
The disabled constructs (e.g. contextual keywords) are highlighted using the CSharpLanguage.HighlightingTokenWriter instead.
-->
<!-- The named colors 'Comment' and 'String' are used in SharpDevelop to detect if a line is inside a multiline string/comment -->
<Color name="Comment" foreground="Green" exampleText="// comment" />
<Color name="String" foreground="Blue" exampleText="string text = &quot;Hello, World!&quot;"/>
<Color name="Char" foreground="Magenta" exampleText="char linefeed = '\n';"/>
<Color name="Preprocessor" foreground="Green" exampleText="#region Title" />
<Color name="Punctuation" exampleText="a(b.c);" />
<Color name="ValueTypeKeywords" fontWeight="bold" foreground="Red" exampleText="bool b = true;" />
<Color name="ReferenceTypeKeywords" foreground="Red" exampleText="object o;" />
<Color name="NumberLiteral" foreground="DarkBlue" exampleText="3.1415f"/>
<Color name="ThisOrBaseReference" fontWeight="bold" exampleText="this.Do(); base.Do();"/>
<Color name="NullOrValueKeywords" fontWeight="bold" exampleText="if (value == null)"/>
<Color name="Keywords" fontWeight="bold" foreground="Blue" exampleText="if (a) {} else {}"/>
<Color name="GotoKeywords" foreground="Navy" exampleText="continue; return null;"/>
<Color name="QueryKeywords" foreground="Navy" exampleText="from x in y select z;"/>
<Color name="ExceptionKeywords" fontWeight="bold" foreground="Teal" exampleText="try {} catch {} finally {}"/>
<Color name="CheckedKeyword" fontWeight="bold" foreground="DarkGray" exampleText="checked {}"/>
<Color name="UnsafeKeywords" foreground="Olive" exampleText="unsafe { fixed (..) {} }"/>
<Color name="OperatorKeywords" fontWeight="bold" foreground="Pink" exampleText="public static implicit operator..."/>
<Color name="ParameterModifiers" fontWeight="bold" foreground="DeepPink" exampleText="(ref int a, params int[] b)"/>
<Color name="Modifiers" foreground="Brown" exampleText="static readonly int a;"/>
<Color name="Visibility" fontWeight="bold" foreground="Blue" exampleText="public override void ToString();"/>
<Color name="NamespaceKeywords" fontWeight="bold" foreground="Green" exampleText="namespace A.B { using System; }"/>
<Color name="GetSetAddRemove" foreground="SaddleBrown" exampleText="int Prop { get; set; }"/>
<Color name="TrueFalse" fontWeight="bold" foreground="DarkCyan" exampleText="b = false; a = true;" />
<Color name="TypeKeywords" fontWeight="bold" foreground="DarkCyan" exampleText="if (x is int) { a = x as int; type = typeof(int); size = sizeof(int); c = new object(); }"/>
<Color name="AttributeKeywords" foreground="Navy" exampleText="[assembly: AssemblyVersion(&quot;1.0.0.*&quot;)]" />
<!-- Colors used for semantic highlighting -->
<Color name="ReferenceTypes" foreground="#004085" exampleText="System.#{#Uri#}# uri;"/>
<Color name="InterfaceTypes" foreground="#004085" exampleText="System.#{#IDisposable#}# obj;"/>
<Color name="TypeParameters" foreground="#004085" exampleText="class MyList&lt;#{#T#}#&gt; { }"/>
<Color name="DelegateTypes" foreground="#004085" exampleText="System.#{#Action#}#; action;"/>
<Color name="ValueTypes" fontWeight="bold" foreground="#004085" exampleText="System.#{#DateTime#}# date;"/>
<Color name="EnumTypes" fontWeight="bold" foreground="#004085" exampleText="System.#{#ConsoleKey#}# key;"/>
<Color name="MethodCall" foreground="MidnightBlue" fontWeight="bold" exampleText="o.#{#ToString#}#();"/>
<Color name="FieldAccess" fontStyle="italic" exampleText="return this.#{#name#}#;"/>
<Color name="InactiveCode" foreground="Gray" exampleText="#{#Deactivated by #if#}#"/>
<Color name="SemanticError" foreground="DarkRed" exampleText="o.#{#MissingMethod#}#()"/>
<Property name="DocCommentMarker" value="///" />
<RuleSet name="CommentMarkerSet">
<Keywords fontWeight="bold" foreground="Red">
<Word>TODO</Word>
<Word>FIXME</Word>
</Keywords>
<Keywords fontWeight="bold" foreground="#E0E000">
<Word>HACK</Word>
<Word>UNDONE</Word>
</Keywords>
</RuleSet>
<!-- This is the main ruleset. -->
<RuleSet>
<Span color="Preprocessor">
<Begin>\#</Begin>
<RuleSet name="PreprocessorSet">
<Span> <!-- preprocessor directives that allow comments -->
<Begin fontWeight="bold">
(define|undef|if|elif|else|endif|line)\b
</Begin>
<RuleSet>
<Span color="Comment" ruleSet="CommentMarkerSet">
<Begin>//</Begin>
</Span>
</RuleSet>
</Span>
<Span> <!-- preprocessor directives that don't allow comments -->
<Begin fontWeight="bold">
(region|endregion|error|warning|pragma)\b
</Begin>
</Span>
</RuleSet>
</Span>
<Span color="Comment">
<Begin color="XmlDoc/DocComment">///(?!/)</Begin>
<RuleSet>
<Import ruleSet="XmlDoc/DocCommentSet"/>
<Import ruleSet="CommentMarkerSet"/>
</RuleSet>
</Span>
<Span color="Comment" ruleSet="CommentMarkerSet">
<Begin>//</Begin>
</Span>
<Span color="Comment" ruleSet="CommentMarkerSet" multiline="true">
<Begin>/\*</Begin>
<End>\*/</End>
</Span>
<Span color="String">
<Begin>"</Begin>
<End>"</End>
<RuleSet>
<!-- span for escape sequences -->
<Span begin="\\" end="."/>
</RuleSet>
</Span>
<Span color="Char">
<Begin>'</Begin>
<End>'</End>
<RuleSet>
<!-- span for escape sequences -->
<Span begin="\\" end="."/>
</RuleSet>
</Span>
<Span color="String" multiline="true">
<Begin color="String">@"</Begin>
<End>"</End>
<RuleSet>
<!-- span for escape sequences -->
<Span begin='""' end=""/>
</RuleSet>
</Span>
<!-- Digits -->
<Rule color="NumberLiteral">
\b0[xX][0-9a-fA-F]+ # hex number
|
( \b\d+(\.[0-9]+)? #number with optional floating point
| \.[0-9]+ #or just starting with floating point
)
([eE][+-]?[0-9]+)? # optional exponent
</Rule>
</RuleSet>
</SyntaxDefinition>

19
ILSpy/TextView/DecompilerTextView.cs

@ -63,6 +63,7 @@ namespace ICSharpCode.ILSpy.TextView @@ -63,6 +63,7 @@ namespace ICSharpCode.ILSpy.TextView
readonly ReferenceElementGenerator referenceElementGenerator;
readonly UIElementGenerator uiElementGenerator;
List<VisualLineElementGenerator> activeCustomElementGenerators = new List<VisualLineElementGenerator>();
RichTextColorizer activeRichTextColorizer;
FoldingManager foldingManager;
ILSpyTreeNode[] decompiledNodes;
@ -85,7 +86,17 @@ namespace ICSharpCode.ILSpy.TextView @@ -85,7 +86,17 @@ namespace ICSharpCode.ILSpy.TextView
}
}
});
HighlightingManager.Instance.RegisterHighlighting(
"C#", new string[] { ".cs" },
delegate {
using (Stream s = typeof(DecompilerTextView).Assembly.GetManifestResourceStream(typeof(DecompilerTextView), "CSharp-Mode.xshd")) {
using (XmlTextReader reader = new XmlTextReader(s)) {
return HighlightingLoader.Load(reader, HighlightingManager.Instance);
}
}
});
InitializeComponent();
this.referenceElementGenerator = new ReferenceElementGenerator(this.JumpToReference, this.IsLink);
@ -361,6 +372,12 @@ namespace ICSharpCode.ILSpy.TextView @@ -361,6 +372,12 @@ namespace ICSharpCode.ILSpy.TextView
references = textOutput.References;
definitionLookup = textOutput.DefinitionLookup;
textEditor.SyntaxHighlighting = highlighting;
if (activeRichTextColorizer != null)
textEditor.TextArea.TextView.LineTransformers.Remove(activeRichTextColorizer);
if (textOutput.HighlightingModel != null) {
activeRichTextColorizer = new RichTextColorizer(textOutput.HighlightingModel);
textEditor.TextArea.TextView.LineTransformers.Insert(highlighting == null ? 0 : 1, activeRichTextColorizer);
}
// Change the set of active element generators:
foreach (var elementGenerator in activeCustomElementGenerators) {

Loading…
Cancel
Save