private void GotoCurrentWord(object sender, EventArgs e) { string sCurrentWord = CommonUtils.GetCurrentWord(); int iCurrentLine = CommonUtils.GetCurrentLine(); string sCurrentFile = Common.Instance.DTE2.ActiveDocument.FullName.ToLower(); Data.SymbolData originSymbol = null; Data.SymbolData symbol = null; //Search in local file IEnumerable <Data.SymbolData> documentSymbols = CTagsGenerator.GeneratorFromDocument(Common.Instance.DTE2.ActiveDocument); IEnumerable <Data.SymbolData> solutionSymbols = Common.Instance.SolutionWatcher.Files .AsParallel() .Where(file => file != null && file.Symbols != null) .SelectMany(file => file.Symbols) ; if (documentSymbols != null) { originSymbol = documentSymbols.Where(s => s.StartLine == iCurrentLine && s.Symbol.Contains(sCurrentWord)).FirstOrDefault(); } if (originSymbol != null) { if (originSymbol.Type == Data.SymbolData.ESymbolType.Method) { //Search prototype symbol = solutionSymbols.Where(s => s.Type == Data.SymbolData.ESymbolType.MethodPrototype && s.Class == originSymbol.Class && s.Symbol == originSymbol.Symbol).FirstOrDefault(); } else if (originSymbol.Type == Data.SymbolData.ESymbolType.MethodPrototype) { //Search method symbol = solutionSymbols.Where(s => s.Type == Data.SymbolData.ESymbolType.Method && s.Class == originSymbol.Class && s.Symbol == originSymbol.Symbol).FirstOrDefault(); } } if (symbol == null && documentSymbols != null) { IEnumerable <Data.SymbolData> filtered = documentSymbols.Where(s => s.StartLine < iCurrentLine && s.Symbol.Contains(sCurrentWord)); int iCount = filtered.Count(); if (iCount == 1) { symbol = filtered.First(); } else if (iCount > 1) { symbol = filtered.OrderBy(s => s.Type).First(); } } // Search in solution if (symbol == null) { IEnumerable <Data.SymbolData> filtered = solutionSymbols .Where(s => s.Symbol.Contains(sCurrentWord) && (s.StartLine != iCurrentLine || s.AssociatedFile.Path.ToLower() != sCurrentFile)); int iCount = filtered.Count(); if (iCount == 1) { symbol = filtered.First(); } else if (iCount > 1) { symbol = filtered.OrderBy(s => s.Type).First(); } } if (symbol != null) { CommonUtils.GotoSymbol(symbol); } }
/* CTags tags for C/C++ c class name d define (from #define XXX) e enumerator f function or method name F file name g enumeration name m member (of structure or class data) p function prototype s structure name t typedef u union name v variable CTags tags for C# */ static IEnumerable<SymbolData> ParseTagFile(string filePath) { List<SymbolData> symbols = new List<SymbolData>(); using (StreamReader reader = File.OpenText(filePath)) { while(!reader.EndOfStream) { string line = reader.ReadLine(); if (!line.StartsWith("!")) { string[] tagInfos = line.Split('\t'); //tagInfos[0] // symbol //tagInfos[1] // file //tagInfos[2] // line number //tagInfos[3] // type if (null != tagInfos && tagInfos.Length >= 4) { //string ext = Path.GetExtension(tagInfos[1]).ToLower(); int fileLine; if (!ExtractLine(tagInfos, out fileLine)) continue; SymbolData oSymbol = null; if (tagInfos[3] == "function" || tagInfos[3] == "method") { oSymbol = new SymbolData(tagInfos[0], fileLine, SymbolData.ESymbolType.Method); } else if (tagInfos[3] == "prototype") { oSymbol = new SymbolData(tagInfos[0], fileLine, SymbolData.ESymbolType.MethodPrototype); } else if (tagInfos[3] == "property") { oSymbol = new SymbolData(tagInfos[0], fileLine, SymbolData.ESymbolType.Property); } else if (tagInfos[3] == "class") { oSymbol = new SymbolData(tagInfos[0], fileLine, SymbolData.ESymbolType.Class); } else if (tagInfos[3] == "macro") { oSymbol = new SymbolData(tagInfos[0], fileLine, SymbolData.ESymbolType.Macro); } else if (tagInfos[3] == "enum") { oSymbol = new SymbolData(tagInfos[0], fileLine, SymbolData.ESymbolType.Enumeration); } else if (tagInfos[3] == "enumerator") { oSymbol = new SymbolData(tagInfos[0], fileLine, SymbolData.ESymbolType.Enumerator); } else if (tagInfos[3] == "member") { oSymbol = new SymbolData(tagInfos[0], fileLine, SymbolData.ESymbolType.Field); } if (null != oSymbol) { for (int i = 4; i < tagInfos.Length; ++i) { if (tagInfos[i].StartsWith("signature:")) { oSymbol.Parameters = tagInfos[i].Substring("signature:".Length); } if (tagInfos[i].StartsWith("class:")) { oSymbol.Class = tagInfos[i].Substring("class:".Length) + "::"; } } oSymbol.AssociatedFile = Common.Instance.SolutionWatcher.GetFileDataByPath(tagInfos[1]); symbols.Add(oSymbol); } } else { System.Diagnostics.Debug.WriteLine("WTF! wrong formatted CTags"); System.Diagnostics.Debug.Assert(false); } } } } return symbols; }
void ReadSymbolDatabase() { string dbPath = Common.Instance.DataFolder + "\\" + Common.Instance.DTE2.Solution.FileName.GetHashCode().ToString() + ".db"; if (System.IO.File.Exists(dbPath)) { using (BinaryReader reader = new BinaryReader(File.Open(SymbolsDatabasePath, FileMode.Open))) { int iFileCount = reader.ReadInt32(); for (int iFileIndex = 0; iFileIndex < iFileCount; ++iFileIndex) { string sFilePath = reader.ReadString(); FileData fileData = GetFileDataByPath(sFilePath); DateTime oLastSymbolsGeneration = DateTime.FromBinary(reader.ReadInt64()); int iSymbolCount = reader.ReadInt32(); List<SymbolData> symbols = new List<SymbolData>(); for (int i = 0; i < iSymbolCount; ++i) { SymbolData.ESymbolType eType = (SymbolData.ESymbolType)reader.ReadByte(); int iStartLine = reader.ReadInt32(); string sSymbol = reader.ReadString(); string sClass = reader.ReadString(); sClass = string.IsNullOrEmpty(sClass) ? null : sClass; string sParameters = reader.ReadString(); sParameters = string.IsNullOrEmpty(sParameters) ? null : sParameters; if (null != fileData) // ignore invalid file { SymbolData newSymbol = new SymbolData(sSymbol, iStartLine, eType); newSymbol.Class = sClass; newSymbol.Parameters = sParameters; symbols.Add(newSymbol); } //newSymbol.AssociatedFile; } if (null != fileData) // ignore invalid file { fileData.SetSymbols(symbols, oLastSymbolsGeneration); } } } } }
/* CTags tags for C/C++ c class name d define (from #define XXX) e enumerator f function or method name F file name g enumeration name m member (of structure or class data) p function prototype s structure name t typedef u union name v variable CTags tags for C# */ static IEnumerable<SymbolData> ParseTagFile(string filePath, SymbolData.ESymbolType types) { List<SymbolData> symbols = new List<SymbolData>(); using (StreamReader reader = File.OpenText(filePath)) { while(!reader.EndOfStream) { string line = reader.ReadLine(); if (!line.StartsWith("!")) { string[] tagInfos = line.Split('\t'); //tagInfos[0] // symbol //tagInfos[1] // file //tagInfos[2] // line number //tagInfos[3] // type if (null != tagInfos && tagInfos.Length >= 4) { //string ext = Path.GetExtension(tagInfos[1]).ToLower(); int fileLine; if (!ExtractLine(tagInfos, out fileLine)) continue; if ((types & SymbolData.ESymbolType.Method) != 0) { if (tagInfos[3] == "f" || tagInfos[3] == "p" || tagInfos[3] == "m") { SymbolData oSymbol = new SymbolData(tagInfos[0], fileLine, SymbolData.ESymbolType.Method); for (int i = 4; i < tagInfos.Length; ++i) { if (tagInfos[i].StartsWith("signature:")) { oSymbol.Parameters = tagInfos[i].Substring("signature:".Length); } if (tagInfos[i].StartsWith("class:")) { oSymbol.Class = tagInfos[i].Substring("class:".Length) + "::"; } if (tagInfos[i].StartsWith("file:")) { //TODO : To implement? } } symbols.Add(oSymbol); } } } else { System.Diagnostics.Debug.WriteLine("WTF! wrong formatted CTags"); System.Diagnostics.Debug.Assert(false); } } } } return symbols; }