From 39cb275456695f8d7b62f84a8f64085e0fb89d34 Mon Sep 17 00:00:00 2001 From: Lucas Trzesniewski Date: Thu, 23 Feb 2023 22:03:28 +0100 Subject: [PATCH] Add semantic highlighting for properties and events Also add a fallback mechanism for colors: if a color definition is empty, another one can be used instead. --- .../Output/TextTokenWriter.cs | 2 +- .../CSharpHighlightingTokenWriter.cs | 93 ++++++++++++------- ILSpy/TextView/CSharp-Mode.xshd | 9 ++ ILSpy/Themes/Theme.RSharpDark.xaml | 2 + ILSpy/Themes/Theme.RSharpLight.xaml | 2 + ILSpy/Themes/Theme.VSCodeDarkPlus.xaml | 2 + ILSpy/Themes/Theme.VSCodeLightPlus.xaml | 2 + 7 files changed, 77 insertions(+), 35 deletions(-) diff --git a/ICSharpCode.Decompiler/Output/TextTokenWriter.cs b/ICSharpCode.Decompiler/Output/TextTokenWriter.cs index 0562bcedd..d225feeaa 100644 --- a/ICSharpCode.Decompiler/Output/TextTokenWriter.cs +++ b/ICSharpCode.Decompiler/Output/TextTokenWriter.cs @@ -457,7 +457,7 @@ namespace ICSharpCode.Decompiler { if (node is EntityDeclaration && !(node.Parent is LocalFunctionDeclarationStatement)) return true; - if (node is VariableInitializer && node.Parent is FieldDeclaration) + if (node is VariableInitializer && node.Parent is FieldDeclaration or EventDeclaration) { node = node.Parent; return true; diff --git a/ILSpy/Languages/CSharpHighlightingTokenWriter.cs b/ILSpy/Languages/CSharpHighlightingTokenWriter.cs index e4ce9eba6..e2e66a090 100644 --- a/ILSpy/Languages/CSharpHighlightingTokenWriter.cs +++ b/ILSpy/Languages/CSharpHighlightingTokenWriter.cs @@ -55,9 +55,12 @@ namespace ICSharpCode.ILSpy HighlightingColor methodCallColor; HighlightingColor methodDeclarationColor; - HighlightingColor fieldDeclarationColor; HighlightingColor fieldAccessColor; + HighlightingColor propertyDeclarationColor; + HighlightingColor propertyAccessColor; + HighlightingColor eventDeclarationColor; + HighlightingColor eventAccessColor; HighlightingColor valueKeywordColor; HighlightingColor thisKeywordColor; @@ -74,39 +77,49 @@ namespace ICSharpCode.ILSpy this.locatable = locatable; this.textOutput = textOutput; - 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.visibilityKeywordsColor = GetColor("Visibility") ?? GetColor("Keywords"); + this.namespaceKeywordsColor = GetColor("NamespaceKeywords") ?? GetColor("Keywords"); + this.structureKeywordsColor = GetColor("Keywords"); + this.gotoKeywordsColor = GetColor("GotoKeywords") ?? GetColor("Keywords"); + this.queryKeywordsColor = GetColor("QueryKeywords") ?? GetColor("Keywords"); + this.exceptionKeywordsColor = GetColor("ExceptionKeywords") ?? GetColor("Keywords"); + this.checkedKeywordColor = GetColor("CheckedKeyword") ?? GetColor("Keywords"); + this.unsafeKeywordsColor = GetColor("UnsafeKeywords") ?? GetColor("Keywords"); + this.valueTypeKeywordsColor = GetColor("ValueTypeKeywords") ?? GetColor("Keywords"); + this.referenceTypeKeywordsColor = GetColor("ReferenceTypeKeywords") ?? GetColor("Keywords"); + this.operatorKeywordsColor = GetColor("OperatorKeywords") ?? GetColor("Keywords"); + this.parameterModifierColor = GetColor("ParameterModifiers") ?? GetColor("Keywords"); + this.modifiersColor = GetColor("Modifiers") ?? GetColor("Keywords"); + this.accessorKeywordsColor = GetColor("GetSetAddRemove") ?? GetColor("Keywords"); - 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.referenceTypeColor = GetColor("ReferenceTypes") ?? GetColor("Types"); + this.valueTypeColor = GetColor("ValueTypes") ?? GetColor("Types"); + this.interfaceTypeColor = GetColor("InterfaceTypes") ?? GetColor("Types"); + this.enumerationTypeColor = GetColor("EnumTypes") ?? GetColor("Types"); + this.typeParameterTypeColor = GetColor("TypeParameters") ?? GetColor("Types"); + this.delegateTypeColor = GetColor("DelegateTypes") ?? GetColor("Types"); + this.methodDeclarationColor = GetColor("MethodDeclaration") ?? GetColor("MethodCall"); + this.methodCallColor = GetColor("MethodCall") ?? GetColor("MethodDeclaration"); + this.fieldDeclarationColor = GetColor("FieldDeclaration") ?? GetColor("FieldAccess"); + this.fieldAccessColor = GetColor("FieldAccess") ?? GetColor("FieldDeclaration"); + this.propertyDeclarationColor = GetColor("PropertyDeclaration") ?? GetColor("PropertyAccess"); + this.propertyAccessColor = GetColor("PropertyAccess") ?? GetColor("PropertyDeclaration"); + this.eventDeclarationColor = GetColor("EventDeclaration") ?? GetColor("EventAccess"); + this.eventAccessColor = GetColor("EventAccess") ?? GetColor("EventDeclaration"); //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.valueKeywordColor = GetColor("NullOrValueKeywords") ?? GetColor("Keywords"); + this.thisKeywordColor = GetColor("ThisOrBaseReference") ?? GetColor("Keywords"); + this.trueKeywordColor = GetColor("TrueFalse") ?? GetColor("Keywords"); + this.typeKeywordsColor = GetColor("TypeKeywords") ?? GetColor("Keywords"); + this.attributeKeywordsColor = GetColor("AttributeKeywords") ?? GetColor("Keywords"); //this.externAliasKeywordColor = ...; + + HighlightingColor GetColor(string colorName) + { + var color = highlighting.GetNamedColor(colorName); + return color is not { Foreground: null, Background: null, FontFamily: null, FontWeight: null, FontSize: null, FontStyle: null, Strikethrough: null, Underline: null } ? color : null; + } } public override void WriteKeyword(Role role, string keyword) @@ -380,12 +393,18 @@ namespace ICSharpCode.ILSpy break; } break; - case IMethod m: + case IMethod: color = methodDeclarationColor; break; - case IField f: + case IField: color = fieldDeclarationColor; break; + case IProperty: + color = propertyDeclarationColor; + break; + case IEvent: + color = eventDeclarationColor; + break; } switch (GetCurrentMemberReference()) { @@ -409,12 +428,18 @@ namespace ICSharpCode.ILSpy break; } break; - case IMethod m: + case IMethod: color = methodCallColor; break; - case IField f: + case IField: color = fieldAccessColor; break; + case IProperty: + color = propertyAccessColor; + break; + case IEvent: + color = eventAccessColor; + break; } if (color != null) { diff --git a/ILSpy/TextView/CSharp-Mode.xshd b/ILSpy/TextView/CSharp-Mode.xshd index 5f5e0a2fd..8c9041d47 100644 --- a/ILSpy/TextView/CSharp-Mode.xshd +++ b/ILSpy/TextView/CSharp-Mode.xshd @@ -33,14 +33,23 @@ + + + + + + + + + diff --git a/ILSpy/Themes/Theme.RSharpDark.xaml b/ILSpy/Themes/Theme.RSharpDark.xaml index a420235c7..492fabc7a 100644 --- a/ILSpy/Themes/Theme.RSharpDark.xaml +++ b/ILSpy/Themes/Theme.RSharpDark.xaml @@ -70,6 +70,8 @@ + + diff --git a/ILSpy/Themes/Theme.RSharpLight.xaml b/ILSpy/Themes/Theme.RSharpLight.xaml index f749e6f9a..6b42b133d 100644 --- a/ILSpy/Themes/Theme.RSharpLight.xaml +++ b/ILSpy/Themes/Theme.RSharpLight.xaml @@ -70,6 +70,8 @@ + + diff --git a/ILSpy/Themes/Theme.VSCodeDarkPlus.xaml b/ILSpy/Themes/Theme.VSCodeDarkPlus.xaml index e4cd880ac..cf7f12f33 100644 --- a/ILSpy/Themes/Theme.VSCodeDarkPlus.xaml +++ b/ILSpy/Themes/Theme.VSCodeDarkPlus.xaml @@ -75,6 +75,8 @@ + + diff --git a/ILSpy/Themes/Theme.VSCodeLightPlus.xaml b/ILSpy/Themes/Theme.VSCodeLightPlus.xaml index e527cde58..b615d4332 100644 --- a/ILSpy/Themes/Theme.VSCodeLightPlus.xaml +++ b/ILSpy/Themes/Theme.VSCodeLightPlus.xaml @@ -75,6 +75,8 @@ + +