public BracketFinder(NemerleSource source, int startLine, int startCol, NemerleScanner scanner, IVsTextColorState colorState) { #region Init fields Scanner = scanner; Source = source; StartLine = startLine; Lex = scanner.GetNewLexer(); Lex.SetFileName(source.GetFilePath()); ColorState = colorState; _lineCount = source.GetLineCount(); var line = startLine - 1; _buffer = new string[1] { source.GetText(line, 0, line, source.GetLineLength(line)) }; _startBufferLine = line; #endregion #region 2. Determine that it is a paired token. 3. Determine paired token. // Get tokens of line under text carret into dynamic array. List <ScanTokenInfo> lineToks = GetLineTokens(startLine, true); // Find index of token which located under text carret. int index = FindIndex(lineToks, x => x.Token.Location.Contains(startLine, startCol)); if (index < 0) { return; } // If index is corret get corresponding token. ScanTokenInfo startBraceInfo = lineToks[index]; // Remember it, if token have paired token. if (IsPairedToken(startBraceInfo.Token)) { StartBraceInfo = startBraceInfo; } else { // otherwise try get right-hand token... startBraceInfo = RightHand(lineToks, index); // Remember it, if token have paired token. if (IsPairedToken(startBraceInfo.Token)) { StartBraceInfo = startBraceInfo; } } #endregion }
/// <summary> /// Get tokens of specified line. /// </summary> /// <param name="line">Line number which tokens it is necessary retrieve</param> /// <param name="isForward">Direction of iteration (true is forward)</param> /// <returns>Token list</returns> List <ScanTokenInfo> GetLineTokens(int nline, bool isForward) { int line = nline - 1; ScanState scanState = GetLineState(nline); string lineText; int index = line - _startBufferLine; // читаем буферами по BufferLen стрк, чтобы ускорить работу if (index < 0 || index >= _buffer.Length) { int start, end; if (isForward) { end = Math.Min(_lineCount - 1, line + BufferLen); start = line; } else { start = Math.Max(0, line - BufferLen); end = line; } var str = Source.GetText(start, 0, end, Source.GetLineLength(end)); _buffer = str.Split(new string[] { "\r\n", "\n", "\r" }, StringSplitOptions.None); _startBufferLine = start; index = line - _startBufferLine; } lineText = _buffer[index]; Scanner.SetSource(lineText, 0); Lex.SetLine(nline, lineText, 0, null, null); List <ScanTokenInfo> lst = new List <ScanTokenInfo>(); foreach (ScanTokenInfo var in GetLineTokens(Lex, scanState)) { lst.Add(var); } if (!isForward) { lst.Reverse(); } return(lst); }
internal void ShowInfo(NemerleSource source) { if (!IsAutoUpdate) return; Action action = () => { _checkCountLabel.Text = (++_checkCount).ToString(); _items.Clear(); ProjectInfo projectInfo = source.ProjectInfo; if (projectInfo == null || !projectInfo.Engine.IsProjectAvailable) return; switch (_displayType.SelectedIndex) { case 0: // Tokens string code = source.GetText(); LexerBase lex = new LexerString((ManagerClass)projectInfo.Engine, code, new Location(source.FileIndex, 1, 1)); //lex.BeginParseFile(); lex.Keywords = lex.Manager.CoreEnv.Keywords; AstUtils.FillList(lex, _items); break; case 1: // AST //var ns = projectInfo.Engine.Project.CompileUnits // .GetTopNamespace(source.FileIndex); //AstUtils.FillList(ns, _items); break; } _grid.RowCount = _items.Count; _grid.Invalidate(); _grid.Update(); }; _checkCountLabel.BeginInvoke(action); }