private List <ClangCursor> FindFunctions(ClangCursor head, string name) { var result = new List <ClangCursor>(); if (name != string.Empty) { foreach (var c in head.GetChildren()) { if (c.Spelling == name) { if (CursorIsValidDeclaration(c)) { if (!result.Any(cc => cc.DisplayName == c.DisplayName)) { result.Add(c); } } } result.AddRange(FindFunctions(c, name)); } } return(result); }
/// <summary> /// Cursor Visitor /// </summary> /// <param name="cursor">Clang Cursor</param> /// <param name="parent">Parent Clang Cursor</param> /// <param name="depth">Depth</param> /// <returns>Child Visit Result</returns> private ChildVisitResult Visitor(ClangCursor cursor, ClangCursor parent, int depth) { var loc = cursor.Location; if (loc.IsFromMainFile == true) { this.VisitChild(cursor, depth); } else { var file_path = loc.GetFilePath(true); if (loc.IsInSystemHeader == true) { this.SystemIncludes.Add(file_path); } else { this.UserIncludes.Add(file_path); this.VisitChild(cursor, depth); } } return(ChildVisitResult.Continue); }
private void GenerateHighlightData(ClangCursor cursor, SyntaxHighlightDataList highlightList, List <IndexEntry> result) { cursor.VisitChildren((current, parent, ptr) => { if (current.Location.IsFromMainFile) { var highlight = CreateOffsetData(current, parent); if (highlight != null) { highlightList.Add(highlight); } switch (current.Kind) { case NClang.CursorKind.CompoundStatement: case NClang.CursorKind.ClassDeclaration: case NClang.CursorKind.Namespace: result.Add(new IndexEntry(current.Spelling, current.CursorExtent.Start.FileLocation.Offset, current.CursorExtent.End.FileLocation.Offset, (CursorKind)current.Kind)); break; } return(ChildVisitResult.Recurse); } if (current.Location.IsInSystemHeader) { return(ChildVisitResult.Continue); } return(ChildVisitResult.Recurse); }, IntPtr.Zero); }
/// <summary> /// Get Behavior Namespace /// </summary> /// <param name="cursor">Clang Cursor</param> /// <returns>Behavior Namespace</returns> private string GetNamespace(ClangCursor cursor) { var namespace_stack = new Stack <string>(); this.ParseNamespace(cursor, namespace_stack); if (namespace_stack.Count == 0) { return(string.Empty); } else { var sb = new StringBuilder(); sb.Append(namespace_stack.Pop()); while (namespace_stack.Count != 0) { sb.Append("::"); sb.Append(namespace_stack.Pop()); } return(sb.ToString()); } }
/// <summary> /// Constructor /// </summary> /// <param name="cursor">Clang Cursor</param> public BehaviorInfo(ClangCursor cursor) : base(cursor) { this.Type = cursor.IsDefinition ? "Definition" : "Declaration"; this.Name = cursor.Spelling; this.Parameters = cursor.DisplayName.Replace(cursor.Spelling, ""); this.NameSpace = this.GetNamespace(cursor); }
/// <summary> /// Visit Child Clang Cursor /// </summary> /// <param name="cursor">Clang Cursor</param> /// <param name="depth">Depth</param> private void VisitChild(ClangCursor cursor, int depth) { if (this.Setting.DumpAST) { this.DumpAstInfo(cursor, depth); } this.AnalyseInvokationInfo(cursor); cursor.VisitChildren(this.Visitor, depth + 1); }
/// <summary> /// Dump AST Information /// </summary> /// <param name="cursor">Clang Cursor</param> /// <param name="depth">Depth</param> private void DumpAstInfo(ClangCursor cursor, int depth) { var indent = new string(' ', depth * 2); var kind = cursor.Kind; var name = cursor.Spelling; var loc = cursor.Location.ToStringEx(); this.SendMessage($"{indent}[{kind}] {name} @ {loc}"); }
private bool CursorIsValidDeclaration(ClangCursor c) { var result = false; if ((c.Kind == NClang.CursorKind.FunctionDeclaration) || c.Kind == NClang.CursorKind.CXXMethod || c.Kind == NClang.CursorKind.Constructor || c.Kind == NClang.CursorKind.Destructor || c.Kind == NClang.CursorKind.FunctionDeclaration) { result = true; } return(result); }
/// <summary> /// Visit Child Clang Cursor /// </summary> /// <param name="cursor">Clang Cursor</param> /// <param name="depth">Depth</param> private void VisitChild(ClangCursor cursor, int depth) { var indent = new string(' ', depth * 2); var kind = cursor.Kind; var name = cursor.Spelling; var loc = cursor.Location.ToStringEx(); this.SendMessage($"{indent}[{kind}] {name} @ {loc}"); cursor.VisitChildren(this.Visitor, depth + 1); }
/// <summary> /// Constructor /// </summary> /// <param name="cursor">Clang Cursor</param> public InvokationInfo(ClangCursor cursor) : base(cursor) { this.Name = cursor.Spelling; if (cursor.Referenced != null) { this.Declaration = BehaviorInfoFactory.Create(cursor.Referenced); this.ID = this.Declaration.ID; this.Definition = this.Declaration.Definition; } else { throw new FieldAccessException($"Behavior Declaration Not Found : {this.Name}"); } }
/// <summary> /// Get Location /// </summary> /// <param name="cursor">Clang Cursor</param> /// <returns>Location String</returns> public string GetLocation(ClangCursor cursor) { var loc = cursor.Location; if (loc != null) { var floc = loc.FileLocation; if (floc != null) { if (floc.File != null) { var path = Path.GetFullPath(floc.File.FileName); var line = floc.Line; var col = floc.Column; var location = $"{path}[L.{line},C.{col}]"; return(location); } else { var line = floc.Line; var col = floc.Column; var location = $"[L.{line},C.{col}]"; return(location); } } else { return(string.Empty); } } else { return(string.Empty); } }
/// <summary> /// Create Behavior Info /// </summary> /// <param name="cursor">Clang Cursor</param> /// <returns>Behavior Info</returns> public static BehaviorInfo Create(ClangCursor cursor) { switch (cursor.Kind) { case CursorKind.Constructor: return(new ConstructorInfo(cursor)); case CursorKind.Destructor: return(new DestructorInfo(cursor)); case CursorKind.FunctionDeclaration: return(new FunctionInfo(cursor)); case CursorKind.CXXMethod: return(new CppMethodInfo(cursor)); default: throw new ArgumentException($"Not Behavior Cursor"); } }
/// <summary> /// Parse Namespace /// </summary> /// <param name="cursor">Clang Cursor</param> /// <param name="namespace_stack">Namespace Stack</param> private void ParseNamespace(ClangCursor cursor, Stack <string> namespace_stack) { var parent = cursor.SemanticParent; if (parent != null) { if (parent.Kind == CursorKind.TranslationUnit) { /* Parse End */ } else if (parent.Kind == CursorKind.Namespace) { namespace_stack.Push(parent.Spelling); this.ParseNamespace(parent, namespace_stack); } else { this.ParseNamespace(parent, namespace_stack); } } }
/// <summary> /// Cursor Visitor /// </summary> /// <param name="cursor">Clang Cursor</param> /// <param name="parent">Parent Clang Cursor</param> /// <param name="depth">Depth</param> /// <returns>Child Visit Result</returns> private ChildVisitResult Visitor(ClangCursor cursor, ClangCursor parent, int depth) { var loc = cursor.Location; if (loc.IsFromMainFile == true) { this.VisitChild(cursor, depth); } else { if (loc.IsInSystemHeader == true) { /* Nothing to do */ } else { this.VisitChild(cursor, depth); } } return(ChildVisitResult.Continue); }
/// <summary> /// Analyse Invokation Info /// </summary> /// <param name="cursor">Clang Cursor</param> private void AnalyseInvokationInfo(ClangCursor cursor) { switch (cursor.Kind) { case CursorKind.TranslationUnit: this.CurrentTranslationUnit = new TranslationUnitInfo(cursor); this.TranslationUnitMap.Add(this.CurrentTranslationUnit); break; case CursorKind.Constructor: this.CurrentBehavior = BehaviorInfoFactory.Create(cursor); this.CurrentTranslationUnit.AddBehavior(this.CurrentBehavior); break; case CursorKind.Destructor: this.CurrentBehavior = BehaviorInfoFactory.Create(cursor); this.CurrentTranslationUnit.AddBehavior(this.CurrentBehavior); break; case CursorKind.FunctionDeclaration: this.CurrentBehavior = BehaviorInfoFactory.Create(cursor); this.CurrentTranslationUnit.AddBehavior(this.CurrentBehavior); break; case CursorKind.CXXMethod: this.CurrentBehavior = BehaviorInfoFactory.Create(cursor); this.CurrentTranslationUnit.AddBehavior(this.CurrentBehavior); break; case CursorKind.CallExpression: var invokation_info = new InvokationInfo(cursor); this.CurrentBehavior.AddInvokation(invokation_info); break; default: break; } }
private void GenerateHighlightData(ClangCursor cursor, SyntaxHighlightDataList highlightList) { cursor.VisitChildren((current, parent, ptr) => { if (current.Location.IsFromMainFile) { var highlight = CreateOffsetData(current, parent); if (highlight != null) { highlightList.Add(highlight); } return(ChildVisitResult.Recurse); } if (current.Location.IsInSystemHeader) { return(ChildVisitResult.Continue); } return(ChildVisitResult.Recurse); }, IntPtr.Zero); }
/// <summary> /// Constructor /// </summary> /// <param name="cursor">Clang Cursor</param> public FunctionInfo(ClangCursor cursor) : base(cursor) { var rtype = cursor.ResultType; this.ReturnType = rtype.Spelling; }
private static StyledText InfoTextFromCursor(ClangCursor cursor) { var result = StyledText.Create(); string name = ""; CursorKind kind = (CursorKind)cursor.Kind; switch (cursor.Kind) { case NClang.CursorKind.CXXAccessSpecifier: name = "(Access Specifier) " + cursor.CxxAccessSpecifier; break; default: name = cursor.Spelling; break; } var theme = ColorScheme.CurrentColorScheme; if (cursor.Kind == NClang.CursorKind.VarDeclaration) { switch (cursor.Linkage) { case NClang.LinkageKind.NoLinkage: result.Append("(local variable) "); break; case NClang.LinkageKind.Internal: result.Append("(static variable) "); break; case NClang.LinkageKind.External: result.Append("(global variable) "); break; } } switch (cursor.CxxAccessSpecifier) { case CXXAccessSpecifier.Private: result.Append("(private) "); break; case CXXAccessSpecifier.Protected: result.Append("(protected) "); break; case CXXAccessSpecifier.Public: result.Append("(public) "); break; } if (cursor.ResultType != null) { result.Append(cursor.ResultType.Spelling + " ", IsBuiltInType(cursor.ResultType) ? theme.Keyword : theme.Type); } else if (cursor.CursorType != null) { switch (kind) { case CursorKind.ClassDeclaration: case CursorKind.CXXThisExpression: result.Append("class ", theme.Keyword); break; case CursorKind.Namespace: result.Append("namespace ", theme.Keyword); break; case CursorKind.TypedefDeclaration: result.Append("typedef ", theme.Keyword); break; case CursorKind.EnumDeclaration: result.Append("enum ", theme.Keyword); break; case CursorKind.StructDeclaration: result.Append("struct ", theme.Keyword); break; case CursorKind.UnionDeclaration: result.Append("union ", theme.Keyword); break; } result.Append(cursor.CursorType.Spelling + " ", IsBuiltInType(cursor.ResultType) ? theme.Keyword : theme.Type); } switch (kind) { case CursorKind.UnionDeclaration: case CursorKind.TypedefDeclaration: case CursorKind.StructDeclaration: case CursorKind.ClassDeclaration: case CursorKind.CXXThisExpression: case CursorKind.Namespace: case CursorKind.EnumDeclaration: break; default: result.Append(name); break; } string parsedDocumentation = ""; switch (kind) { case CursorKind.EnumConstantDeclaration: result.Append(" = " + cursor.EnumConstantDeclUnsignedValue.ToString()); result.Append(" (0x" + cursor.EnumConstantDeclUnsignedValue.ToString("X") + ")"); break; case CursorKind.FunctionDeclaration: case CursorKind.CXXMethod: case CursorKind.Constructor: case CursorKind.Destructor: result.Append(" ("); for (var i = 0; i < cursor.ArgumentCount; i++) { var argument = cursor.GetArgument(i); result.Append(argument.CursorType.Spelling + " ", IsBuiltInType(argument.CursorType) ? theme.Keyword : theme.Type); result.Append(argument.Spelling + (i == cursor.ArgumentCount - 1 ? "" : ", ")); } if (cursor.IsVariadic) { result.Append(", ... variadic"); } if (cursor.ArgumentCount == 0) { result.Append("void", theme.Keyword); } result.Append(")"); if (cursor.ParsedComment.FullCommentAsXml != null) { var documentation = XDocument.Parse(cursor.ParsedComment.FullCommentAsXml); var function = documentation.Element("Function"); var parameters = function.Element("Parameters"); if (parameters != null) { var arguments = parameters.Elements("Parameter"); foreach (var argument in arguments) { var isVarArgs = argument.Element("IsVarArg"); var discussion = argument.Element("Discussion"); var paragraph = discussion.Element("Para"); if (paragraph != null) { if (isVarArgs != null) { parsedDocumentation += paragraph.Value + Environment.NewLine; } else { var inx = argument.Element("Index"); if (inx != null) { parsedDocumentation += paragraph.Value + Environment.NewLine; } } } } } } break; } if (cursor.BriefCommentText != null || !string.IsNullOrEmpty(parsedDocumentation)) { result.AppendLine(); if (cursor.BriefCommentText != null) { result.AppendLine(cursor.BriefCommentText); } if (!string.IsNullOrEmpty(parsedDocumentation)) { result.Append(parsedDocumentation); } } return(result); }
/// <summary> /// Constructor /// </summary> /// <param name="cursor">Clang Cursor</param> public TranslationUnitInfo(ClangCursor cursor) : base(cursor) { this.Path = System.IO.Path.GetFullPath(cursor.Spelling); }
private static Symbol SymbolFromClangCursor(ClangCursor cursor) { var result = new Symbol(); switch (cursor.Kind) { case NClang.CursorKind.CXXAccessSpecifier: result.Name = "(Access Specifier) " + cursor.CxxAccessSpecifier; break; default: result.Name = cursor.Spelling; break; } result.Kind = (CursorKind)cursor.Kind; result.BriefComment = cursor.BriefCommentText; result.TypeDescription = cursor.CursorType?.Spelling; result.EnumDescription = cursor.EnumConstantDeclValue.ToString(); result.Definition = cursor.Definition.DisplayName; result.Linkage = (LinkageKind)cursor.Linkage; result.IsBuiltInType = IsBuiltInType(cursor.CursorType); result.SymbolType = cursor.CursorType?.Spelling.Replace(" &", "&").Replace(" *", "*") + " "; result.ResultType = cursor.ResultType?.Spelling; result.Arguments = new List <ParameterSymbol>(); result.Access = (AccessType)cursor.CxxAccessSpecifier; result.IsVariadic = cursor.IsVariadic; switch (result.Kind) { case CursorKind.FunctionDeclaration: case CursorKind.CXXMethod: case CursorKind.Constructor: case CursorKind.Destructor: for (var i = 0; i < cursor.ArgumentCount; i++) { var argument = cursor.GetArgument(i); var arg = new ParameterSymbol(); arg.IsBuiltInType = IsBuiltInType(argument.CursorType); arg.Name = argument.Spelling; arg.TypeDescription = argument.CursorType.Spelling; result.Arguments.Add(arg); } if (cursor.IsVariadic) { result.Arguments.Last().Name += ", "; result.Arguments.Add(new ParameterSymbol { Name = "... variadic" }); } if (cursor.ParsedComment.FullCommentAsXml != null) { var documentation = XDocument.Parse(cursor.ParsedComment.FullCommentAsXml); var function = documentation.Element("Function"); var parameters = function.Element("Parameters"); if (parameters != null) { var arguments = parameters.Elements("Parameter"); foreach (var argument in arguments) { var isVarArgs = argument.Element("IsVarArg"); var discussion = argument.Element("Discussion"); var paragraph = discussion.Element("Para"); if (isVarArgs != null) { result.Arguments.Last().Comment = paragraph.Value; } else { var inx = argument.Element("Index"); if (inx != null) { // This happens when documentation for an argument was left in, but the argument no longer exists. var index = int.Parse(inx.Value); result.Arguments[index].Comment = paragraph.Value; } } } } } if (result.Arguments.Count == 0) { result.Arguments.Add(new ParameterSymbol { Name = "void" }); } break; } return(result); }
/// <summary> /// Constructor /// </summary> /// <param name="cursor">Clang Cursor</param> public ClassBehaviorInfo(ClangCursor cursor) : base(cursor) { var parent_class = cursor.SemanticParent; this.ClassName = parent_class.Spelling; }
private List<ClangCursor> FindFunctions(ClangCursor head, string name) { var result = new List<ClangCursor>(); if (name != string.Empty) { foreach (var c in head.GetChildren()) { if (c.Spelling == name) { if (CursorIsValidDeclaration(c)) { if (!result.Any(cc => cc.DisplayName == c.DisplayName)) { result.Add(c); } } } result.AddRange(FindFunctions(c, name)); } } return result; }
private bool CursorIsValidDeclaration(ClangCursor c) { var result = false; if ((c.Kind == NClang.CursorKind.FunctionDeclaration) || c.Kind == NClang.CursorKind.CXXMethod || c.Kind == NClang.CursorKind.Constructor || c.Kind == NClang.CursorKind.Destructor || c.Kind == NClang.CursorKind.FunctionDeclaration) { result = true; } return result; }
private static Symbol SymbolFromClangCursor(ClangCursor cursor) { var result = new Symbol(); switch (cursor.Kind) { case NClang.CursorKind.CXXAccessSpecifier: result.Name = "(Access Specifier) " + cursor.CxxAccessSpecifier; break; default: result.Name = cursor.Spelling; break; } result.Kind = (CursorKind)cursor.Kind; result.BriefComment = cursor.BriefCommentText; result.TypeDescription = cursor.CursorType?.Spelling; result.EnumDescription = cursor.EnumConstantDeclValue.ToString(); result.Definition = cursor.Definition.DisplayName; result.Linkage = (LinkageKind)cursor.Linkage; result.IsBuiltInType = IsBuiltInType(cursor.CursorType); result.SymbolType = cursor.CursorType?.Spelling.Replace(" &", "&").Replace(" *", "*") + " "; result.ResultType = cursor.ResultType?.Spelling; result.Arguments = new List<ParameterSymbol>(); result.Access = (AccessType)cursor.CxxAccessSpecifier; result.IsVariadic = cursor.IsVariadic; switch (result.Kind) { case CursorKind.FunctionDeclaration: case CursorKind.CXXMethod: case CursorKind.Constructor: case CursorKind.Destructor: for (var i = 0; i < cursor.ArgumentCount; i++) { var argument = cursor.GetArgument(i); var arg = new ParameterSymbol(); arg.IsBuiltInType = IsBuiltInType(argument.CursorType); arg.Name = argument.Spelling; arg.TypeDescription = argument.CursorType.Spelling; result.Arguments.Add(arg); } if (cursor.IsVariadic) { result.Arguments.Last().Name += ", "; result.Arguments.Add(new ParameterSymbol { Name = "... variadic" }); } if (cursor.ParsedComment.FullCommentAsXml != null) { var documentation = XDocument.Parse(cursor.ParsedComment.FullCommentAsXml); var function = documentation.Element("Function"); var parameters = function.Element("Parameters"); if (parameters != null) { var arguments = parameters.Elements("Parameter"); foreach (var argument in arguments) { var isVarArgs = argument.Element("IsVarArg"); var discussion = argument.Element("Discussion"); var paragraph = discussion.Element("Para"); if (isVarArgs != null) { result.Arguments.Last().Comment = paragraph.Value; } else { var inx = argument.Element("Index"); if (inx != null) // This happens when documentation for an argument was left in, but the argument no longer exists. { var index = int.Parse(inx.Value); result.Arguments[index].Comment = paragraph.Value; } } } } } if (result.Arguments.Count == 0) { result.Arguments.Add(new ParameterSymbol { Name = "void" }); } break; } return result; }
/// <summary> /// Constructor /// </summary> /// <param name="cursor">Clang Cursor</param> public CppMethodInfo(ClangCursor cursor) : base(cursor) { var rtype = cursor.ResultType; this.ReturnType = rtype.Spelling; }
/// <summary> /// Constructor /// </summary> /// <param name="cursor">Clang Cursor</param> public ConstructorInfo(ClangCursor cursor) : base(cursor) { }
public static int GetLine(this ClangCursor cursor) { var loc = cursor.Location.FileLocation; return loc?.Line ?? -1; }
public static string GetFile(this ClangCursor cursor) { var loc = cursor.Location.FileLocation; return loc?.File?.FileName; }
public static int GetColumn(this ClangCursor cursor) { var loc = cursor.Location.FileLocation; return loc?.Column ?? -1; }
/// <summary> /// Constructor /// </summary> /// <param name="cursor">Clang Cursor</param> public AstNodeInfo(ClangCursor cursor) { this.Location = this.GetLocation(cursor); }