#develop (short for SharpDevelop) is a free IDE for .NET programming languages.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

544 lines
20 KiB

// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Media;
using System.Text;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.AvalonEdit.Highlighting;
using System.Collections.Generic;
namespace CSharpBinding.OutlinePad
{
internal static class AstNodeHelper {
static bool showExtendedInfos = true;
static bool colorizeNode = false;
static HighlightingColor nameSpaceHighLighting, regionHighLighting, classHighLighting, methodHighLighting, interfaceHighLighting;
static AstNodeHelper() {
var highlightingDefinition = HighlightingManager.Instance.GetDefinition("C#");
nameSpaceHighLighting = highlightingDefinition.NamedHighlightingColors.First( x => x.Name == "NamespaceKeywords");
regionHighLighting = highlightingDefinition.NamedHighlightingColors.First( x => x.Name == "Preprocessor");
classHighLighting = highlightingDefinition.NamedHighlightingColors.First( x => x.Name == "ReferenceTypeKeywords");
interfaceHighLighting = highlightingDefinition.NamedHighlightingColors.First( x => x.Name == "ReferenceTypeKeywords");
methodHighLighting = highlightingDefinition.NamedHighlightingColors.First( x => x.Name == "MethodCall");
}
private static Modifiers GetAccessModifier(AstNode node) {
var accessModifier = node.Children.FirstOrDefault(x => x is CSharpModifierToken &&
((x as CSharpModifierToken).Modifier == Modifiers.Public ||
(x as CSharpModifierToken).Modifier == Modifiers.Protected ||
(x as CSharpModifierToken).Modifier == Modifiers.Private ||
(x as CSharpModifierToken).Modifier == Modifiers.Internal )) as CSharpModifierToken;
// special case: All members in an interface are public, although they have no access modifier
if (accessModifier == null && IsInterface(node.Parent)) {
return Modifiers.Public;
}
return accessModifier == null
? Modifiers.None
: accessModifier.Modifier;
}
private static string GetParameterDeclsAsString(AstNodeCollection<ParameterDeclaration> parameterDecls) {
var parameterString = new StringBuilder();
int current = 0;
foreach (var paramDecl in parameterDecls) {
if (paramDecl.ParameterModifier != ParameterModifier.None) {
parameterString.Append(paramDecl.ParameterModifier.ToString().ToLower());
parameterString.Append(" ");
}
parameterString.Append(paramDecl.Type.ToString());
parameterString.Append(" ");
parameterString.Append(paramDecl.Name);
if (current < (parameterDecls.Count - 1)) {
parameterString.Append(", ");
}
current++;
}
return parameterString.ToString();
}
private static string GetTypeParameterDeclsAsString(AstNodeCollection<TypeParameterDeclaration> parameterDecls) {
var parameterString = new StringBuilder();
int current = 0;
foreach (var paramDecl in parameterDecls) {
parameterString.Append(paramDecl.NameToken.ToString());
if (current < (parameterDecls.Count - 1)) {
parameterString.Append(", ");
}
current++;
}
return parameterString.ToString();
}
public static bool IsAllowedNode(AstNode node) {
return (IsRegionStart(node)
|| IsRegionEnd(node)
|| IsClass(node)
|| IsInterface(node)
|| IsMethod(node)
|| IsField(node)
|| IsProperty(node)
|| IsNameSpace(node)
|| IsConstructor(node)
|| IsEvent(node)
|| IsDelegate(node)
|| IsIndexer(node)
|| IsEnum(node)
|| IsEnumMember(node)
|| IsStruct(node)
|| IsOperator(node)
);
}
public static bool IsRegionStart(AstNode node) {
return (node is PreProcessorDirective && (node as PreProcessorDirective).Type == PreProcessorDirectiveType.Region);
}
internal static void SetRegionStartInfos(CSharpOutlineNode node, AstNode dataNode) {
var preProcessorNode = (PreProcessorDirective)dataNode;
node.Name = "*****" + preProcessorNode.Argument + "****";
node.ForegroundBrush = (regionHighLighting.Foreground as SimpleHighlightingBrush).GetBrush(null);
// node.Weight = regionHighLighting.FontWeight != null ? regionHighLighting.FontWeight.Value : FontWeights.Normal;
}
public static bool IsRegionEnd(AstNode node) {
return (node is PreProcessorDirective && (node as PreProcessorDirective).Type == PreProcessorDirectiveType.Endregion);
}
internal static void SetRegionEndInfos(CSharpOutlineNode node, AstNode dataNode) {
var preProcessorNode = (PreProcessorDirective)dataNode;
node.Name = "********************";
node.ForegroundBrush = (regionHighLighting.Foreground as SimpleHighlightingBrush).GetBrush(null);
// node.Weight = regionHighLighting.FontWeight != null ? regionHighLighting.FontWeight.Value : FontWeights.Normal;
}
public static bool IsDelegate(AstNode node) {
return (node is DelegateDeclaration);
}
internal static void SetDelegateNodeInfos(CSharpOutlineNode node, AstNode dataNode) {
var typeNode = (DelegateDeclaration)dataNode;
node.Name = typeNode.Name;
if (colorizeNode)
node.ForegroundBrush = Brushes.Black;
// node.Weight = classHighLighting.FontWeight != null ? classHighLighting.FontWeight.Value : FontWeights.Normal;
switch(GetAccessModifier(dataNode)) {
case Modifiers.Public:
node.IconName = "Icons.16x16.Delegate";
break;
case Modifiers.Protected:
node.IconName = "Icons.16x16.ProtectedDelegate";
break;
case Modifiers.Private:
node.IconName = "Icons.16x16.PrivateDelegate";
break;
default:
node.IconName = "Icons.16x16.InternalDelegate";
break;
}
}
public static bool IsStruct(AstNode node) {
return (node is TypeDeclaration && (node as TypeDeclaration).ClassType == ClassType.Struct);
}
internal static void SetStructNodeInfos(CSharpOutlineNode node, AstNode dataNode) {
var typeNode = (TypeDeclaration)dataNode;
node.Name = typeNode.Name;
node.IsExpanded = true;
if (colorizeNode)
node.ForegroundBrush = (classHighLighting.Foreground as SimpleHighlightingBrush).GetBrush(null);
// node.Weight = classHighLighting.FontWeight != null ? classHighLighting.FontWeight.Value : FontWeights.Normal;
switch(GetAccessModifier(dataNode)) {
case Modifiers.Public:
node.IconName = "Icons.16x16.Struct";
break;
case Modifiers.Protected:
node.IconName = "Icons.16x16.ProtectedStruct";
break;
case Modifiers.Private:
node.IconName = "Icons.16x16.PrivateStruct";
break;
default:
node.IconName = "Icons.16x16.InternalStruct";
break;
}
}
public static bool IsEnumMember(AstNode node) {
return (node is EnumMemberDeclaration);
}
internal static void SetEnumMemberNodeInfos(CSharpOutlineNode node, AstNode dataNode) {
var enumMemberNode = (EnumMemberDeclaration)dataNode;
node.Name = enumMemberNode.Name;
if (colorizeNode)
node.ForegroundBrush = Brushes.Black;
node.IconName = "Icons.16x16.Enum";
}
public static bool IsEnum(AstNode node) {
return (node is TypeDeclaration && (node as TypeDeclaration).ClassType == ClassType.Enum);
}
internal static void SetEnumNodeInfos(CSharpOutlineNode node, AstNode dataNode) {
var typeNode = (TypeDeclaration)dataNode;
node.Name = typeNode.Name;
node.IsExpanded = true;
if (colorizeNode)
node.ForegroundBrush = (classHighLighting.Foreground as SimpleHighlightingBrush).GetBrush(null);
switch(GetAccessModifier(dataNode)) {
case Modifiers.Public:
node.IconName = "Icons.16x16.Enum";
break;
case Modifiers.Protected:
node.IconName = "Icons.16x16.ProtectedEnum";
break;
case Modifiers.Private:
node.IconName = "Icons.16x16.PrivateEnum";
break;
default:
node.IconName = "Icons.16x16.InternalEnum";
break;
}
}
public static bool IsClass(AstNode node) {
return (node is TypeDeclaration && (node as TypeDeclaration).ClassType == ClassType.Class);
}
internal static void SetClassNodeInfos(CSharpOutlineNode node, AstNode dataNode) {
var typeNode = (TypeDeclaration)dataNode;
node.Name = typeNode.Name
+ typeNode.LChevronToken
+ GetTypeParameterDeclsAsString(typeNode.TypeParameters)
+ typeNode.RChevronToken;
node.IsExpanded = true;
if (colorizeNode)
node.ForegroundBrush = (classHighLighting.Foreground as SimpleHighlightingBrush).GetBrush(null);
// node.Weight = classHighLighting.FontWeight != null ? classHighLighting.FontWeight.Value : FontWeights.Normal;
switch(GetAccessModifier(dataNode)) {
case Modifiers.Public:
node.IconName = "Icons.16x16.Class";
break;
case Modifiers.Protected:
node.IconName = "Icons.16x16.ProtectedClass";
break;
case Modifiers.Private:
node.IconName = "Icons.16x16.PrivateClass";
break;
default:
node.IconName = "Icons.16x16.InternalClass";
break;
}
}
public static bool IsEvent(AstNode node) {
return (node is EventDeclaration);
}
internal static void SetEventNodeInfos(CSharpOutlineNode node, AstNode dataNode) {
var eventNode = (EventDeclaration)dataNode;
var varInitializer = eventNode.Children.FirstOrDefault(x => x is VariableInitializer) as VariableInitializer;
node.Name = (varInitializer != null)
? varInitializer.Name
: "<unknown>";
if (colorizeNode)
node.ForegroundBrush = Brushes.Black;
switch(GetAccessModifier(dataNode)) {
case Modifiers.Public:
node.IconName = "Icons.16x16.Event";
break;
case Modifiers.Protected:
node.IconName = "Icons.16x16.ProtectedEvent";
break;
default:
node.IconName = "Icons.16x16.PrivateEvent";
break;
}
}
public static bool IsInterface(AstNode node) {
return (node is TypeDeclaration && (node as TypeDeclaration).ClassType == ClassType.Interface);
}
internal static void SetInterfaceNodeInfos(CSharpOutlineNode node, AstNode dataNode) {
var typeNode = (TypeDeclaration)dataNode;
node.Name = typeNode.Name;
node.IsExpanded = true;
if (colorizeNode)
node.ForegroundBrush = (interfaceHighLighting.Foreground as SimpleHighlightingBrush).GetBrush(null);
switch(GetAccessModifier(dataNode)) {
case Modifiers.Public:
node.IconName = "Icons.16x16.Interface";
break;
case Modifiers.Protected:
node.IconName = "Icons.16x16.ProtectedInterface";
break;
case Modifiers.Private:
node.IconName = "Icons.16x16.PrivateInterface";
break;
default:
node.IconName = "Icons.16x16.InternalInterface";
break;
}
}
public static bool IsOperator(AstNode node) {
return (node is OperatorDeclaration);
}
internal static void SetOperatorNodeInfos(CSharpOutlineNode node, AstNode dataNode) {
var operatorNode = (OperatorDeclaration)dataNode;
node.Name = operatorNode.OperatorToken
+ " "
+ operatorNode.OperatorTypeToken;
if (colorizeNode)
node.ForegroundBrush = Brushes.Black;
if (showExtendedInfos) {
node.Name += " "
+ operatorNode.LParToken
+ GetParameterDeclsAsString(operatorNode.Parameters)
+ operatorNode.RParToken;
}
switch(GetAccessModifier(dataNode)) {
case Modifiers.Public:
node.IconName = "Icons.16x16.Method";
break;
case Modifiers.Protected:
node.IconName = "Icons.16x16.ProtectedMethod";
break;
default:
node.IconName = "Icons.16x16.PrivateMethod";
break;
}
}
public static bool IsMethod(AstNode node) {
return (node is MethodDeclaration);
}
internal static void SetMethodNodeInfos(CSharpOutlineNode node, AstNode dataNode) {
var methodNode = (MethodDeclaration)dataNode;
node.Name = methodNode.Name;
node.Name += " "
+ methodNode.LParToken
+ (showExtendedInfos ? GetParameterDeclsAsString(methodNode.Parameters) : "")
+ methodNode.RParToken;
if (colorizeNode)
node.ForegroundBrush = (methodHighLighting.Foreground as SimpleHighlightingBrush).GetBrush(null);
// node.Weight = methodHighLighting.FontWeight != null ? methodHighLighting.FontWeight.Value : FontWeights.Normal;
switch(GetAccessModifier(dataNode)) {
case Modifiers.Public:
node.IconName = "Icons.16x16.Method";
break;
case Modifiers.Protected:
node.IconName = "Icons.16x16.ProtectedMethod";
break;
default:
node.IconName = "Icons.16x16.PrivateMethod";
break;
}
}
public static bool IsField(AstNode node) {
return (node is FieldDeclaration);
}
internal static void SetFieldNodeInfos(CSharpOutlineNode node, AstNode dataNode) {
var fieldNode = (FieldDeclaration)dataNode;
var fieldName = new StringBuilder();
int current = 0;
foreach (var varInitializer in fieldNode.Variables) {
fieldName.Append(varInitializer.Name);
if (current < (fieldNode.Variables.Count - 1)) {
fieldName.Append(", ");
}
current++;
}
node.Name = fieldName.ToString();
if (colorizeNode)
node.ForegroundBrush = Brushes.Black;
switch(GetAccessModifier(dataNode)) {
case Modifiers.Public:
node.IconName = "Icons.16x16.Field";
break;
case Modifiers.Protected:
node.IconName = "Icons.16x16.ProtectedField";
break;
default:
node.IconName = "Icons.16x16.PrivateField";
break;
}
}
public static bool IsProperty(AstNode node) {
return (node is PropertyDeclaration);
}
internal static void SetPropertyNodeInfos(CSharpOutlineNode node, AstNode dataNode) {
var propertyNode = (PropertyDeclaration)dataNode;
node.Name = propertyNode.Name;
if (colorizeNode)
node.ForegroundBrush = Brushes.Black;
if (showExtendedInfos) {
node.Name += " " + propertyNode.LBraceToken
+ " " + propertyNode.Getter.Keyword + (!string.IsNullOrEmpty(propertyNode.Getter.Keyword.ToString()) ? ";" : "")
+ " " + propertyNode.Setter.Keyword + (!string.IsNullOrEmpty(propertyNode.Setter.Keyword.ToString()) ? ";" : "")
+ " " + propertyNode.RBraceToken;
}
switch(GetAccessModifier(dataNode)) {
case Modifiers.Public:
node.IconName = "Icons.16x16.Property";
break;
case Modifiers.Protected:
node.IconName = "Icons.16x16.ProtectedProperty";
break;
default:
node.IconName = "Icons.16x16.PrivateProperty";
break;
}
}
public static bool IsIndexer(AstNode node) {
return (node is IndexerDeclaration);
}
internal static void SetIndexerNodeInfos(CSharpOutlineNode node, AstNode dataNode) {
var indexerNode = (IndexerDeclaration)dataNode;
node.Name = indexerNode.ReturnType.ToString()
+ " "
+ indexerNode.ThisToken.ToString()
+ indexerNode.LBracketToken
+ GetParameterDeclsAsString(indexerNode.Parameters)
+ indexerNode.RBracketToken;
if (colorizeNode)
node.ForegroundBrush = Brushes.Black;
if (showExtendedInfos) {
node.Name += " " + indexerNode.LBraceToken
+ " " + indexerNode.Getter.Keyword + (!string.IsNullOrEmpty(indexerNode.Getter.Keyword.ToString()) ? ";" : "")
+ " " + indexerNode.Setter.Keyword + (!string.IsNullOrEmpty(indexerNode.Setter.Keyword.ToString()) ? ";" : "")
+ " " + indexerNode.RBraceToken;
}
switch(GetAccessModifier(dataNode)) {
case Modifiers.Public:
node.IconName = "Icons.16x16.Property";
break;
case Modifiers.Protected:
node.IconName = "Icons.16x16.ProtectedProperty";
break;
default:
node.IconName = "Icons.16x16.PrivateProperty";
break;
}
}
public static bool IsNameSpace(AstNode node) {
return (node is NamespaceDeclaration);
}
internal static void SetNameSpaceNodeInfos(CSharpOutlineNode node, AstNode dataNode) {
var nameSpaceNode = (NamespaceDeclaration)dataNode;
node.Name = nameSpaceNode.Name;
node.IconName = "Icons.16x16.NameSpace";
node.IsExpanded = true;
if (colorizeNode)
node.ForegroundBrush = (nameSpaceHighLighting.Foreground as SimpleHighlightingBrush).GetBrush(null);
// node.Weight = nameSpaceHighLighting.FontWeight != null ? nameSpaceHighLighting.FontWeight.Value : FontWeights.Normal;
}
public static bool IsConstructor(AstNode node) {
return (node is ConstructorDeclaration);
}
internal static void SetConstructorNodeInfos(CSharpOutlineNode node, AstNode dataNode) {
var constructorNode = (ConstructorDeclaration)dataNode;
node.Name = constructorNode.Name;
if (colorizeNode)
node.ForegroundBrush = Brushes.Black;
node.Name += " "
+ constructorNode.LParToken
+ (showExtendedInfos ? GetParameterDeclsAsString(constructorNode.Parameters) : "")
+ constructorNode.RParToken;
switch(GetAccessModifier(dataNode)) {
case Modifiers.Public:
node.IconName = "Icons.16x16.Method";
break;
case Modifiers.Protected:
node.IconName = "Icons.16x16.ProtectedMethod";
break;
default:
node.IconName = "Icons.16x16.PrivateMethod";
break;
}
}
public static bool IsDocument(AstNode node) {
return (node is SyntaxTree);
}
internal static void SetDocumentNodeInfos(CSharpOutlineNode node, AstNode dataNode) {
node.Name = Path.GetFileName(((SyntaxTree)dataNode).FileName);
node.IconName = "C#.File.FullFile";
node.IsExpanded = true;
node.Weight = FontWeights.Bold;
if (colorizeNode)
node.ForegroundBrush = Brushes.Black;
}
}
}