private TextRun _GetTextRun(int textSourceCharacterIndex) { _charIndex = textSourceCharacterIndex; _debugFn?.Invoke($"GetTextRun(textSourceCharacterIndex = {textSourceCharacterIndex})", 5); if (textSourceCharacterIndex == 0) { #if DEBUG _debugFn?.Invoke($"Clearing runs because at beginning of text source", 4); #endif Runs.Clear(); SyntaxInfos = GetSyntaxInfos().GetEnumerator(); if (!SyntaxInfos.MoveNext()) { var endOfParagraph = new CustomTextEndOfParagraph(2) { Index = textSourceCharacterIndex }; Runs.Add(endOfParagraph); return(endOfParagraph); } } else { #if DEBUGRUNS foreach (var textRun in Runs) { _debugFn?.Invoke(" " + textRun.ToString(), 4); } #endif Runs = RunsBefore(textSourceCharacterIndex, Runs).ToList(); } var si = SyntaxInfos.Current; if (si == null) { var endOfParagraph = new CustomTextEndOfParagraph(2) { Index = textSourceCharacterIndex }; Runs.Add(endOfParagraph); return(endOfParagraph); } // ReSharper disable once PossibleNullReferenceException while (textSourceCharacterIndex > si.Span1.Start || /*|| si.Span1.End < textSourceCharacterIndex*/ si.Text.Length == 0) { if (!SyntaxInfos.MoveNext()) { if (textSourceCharacterIndex < Length) { var len = Length - textSourceCharacterIndex; var buf = new char[len]; Text.CopyTo(textSourceCharacterIndex, buf, 0, len); if (len == 2 && buf[0] == '\r' && buf[1] == '\n') { var eol = new CustomTextEndOfLine(2) { Index = textSourceCharacterIndex }; Runs.Add(eol); return(eol); } var t = string.Join("", buf); var customTextCharacters = new CustomTextCharacters(t, MakeProperties(SyntaxKind.None, t)) { Index = textSourceCharacterIndex }; Runs.Add(customTextCharacters); return(customTextCharacters); } var endOfParagraph = new CustomTextEndOfParagraph(2) { Index = textSourceCharacterIndex }; Runs.Add(endOfParagraph); return(endOfParagraph); } si = SyntaxInfos.Current; } if (textSourceCharacterIndex < si.Span1.Start) { var len = si.Span1.Start - textSourceCharacterIndex; var buf = new char[len]; Text.CopyTo(textSourceCharacterIndex, buf, 0, len); if (len == 2 && buf[0] == '\r' && buf[1] == '\n') { var eol = new CustomTextEndOfLine(2) { Index = textSourceCharacterIndex }; Runs.Add(eol); return(eol); } var t = string.Join("", buf); var nl = t.IndexOf("\r\n", StringComparison.Ordinal); if (nl != -1) { t = t.Substring(0, nl); if (t == "") { var eol = new CustomTextEndOfLine(2) { Index = textSourceCharacterIndex }; Runs.Add(eol); return(eol); } var ctc = new CustomTextCharacters(t, MakeProperties(SyntaxKind.None, t)) { Index = textSourceCharacterIndex }; Runs.Add(ctc); return(ctc); } var customTextCharacters = new CustomTextCharacters(t, MakeProperties(SyntaxKind.None, t)) { Index = textSourceCharacterIndex }; Runs.Add(customTextCharacters); return(customTextCharacters); } // while (textSourceCharacterIndex > si.Span1.Start) // { // if (!SyntaxInfos.MoveNext()) // { // } // } if (textSourceCharacterIndex != si.Span1.Start) { throw new InvalidOperationException("Character index does not match span start"); } if (si.SyntaxTrivia.HasValue) { var syntaxKind = CSharpExtensions.Kind(si.SyntaxTrivia.Value); if (syntaxKind == SyntaxKind.EndOfLineTrivia || syntaxKind == SyntaxKind.XmlTextLiteralNewLineToken) { var customTextEndOfLine = new CustomTextEndOfLine(2) { Index = textSourceCharacterIndex }; Runs.Add(customTextEndOfLine); return(customTextEndOfLine); } var p = PropsFor(si.SyntaxTrivia.Value, si.Text); var syntaxTriviaTextCharacters = new SyntaxTriviaTextCharacters(si.Text, p, si.Span1, si.SyntaxTrivia.Value, si.Node, si.Token, si.TriviaPosition, si.StructuredTrivia) { Index = si.Span1.Start }; Runs.Add(syntaxTriviaTextCharacters); return(syntaxTriviaTextCharacters); } if (si.SyntaxToken.HasValue) { if (CSharpExtensions.Kind(si.SyntaxToken.Value) == SyntaxKind.XmlTextLiteralNewLineToken) { var customTextEndOfLine = new CustomTextEndOfLine(2) { Index = textSourceCharacterIndex }; Runs.Add(customTextEndOfLine); return(customTextEndOfLine); } var syntaxTokenTextCharacters = new SyntaxTokenTextCharacters(si.Text, si.Text.Length, PropsFor(si.SyntaxToken.Value, si.Text), si.SyntaxToken.Value, si.SyntaxToken.Value.Parent) { Index = si.Span1.Start }; Runs.Add(syntaxTokenTextCharacters); return(syntaxTokenTextCharacters); } var textEndOfParagraph = new CustomTextEndOfParagraph(2) { Index = textSourceCharacterIndex }; Runs.Add(textEndOfParagraph); return(textEndOfParagraph); #if false Debug.WriteLine($"index: {textSourceCharacterIndex}"); TextSpan?TakeToken() { var includeDocumentationComments = true; var includeDirectives = true; var includeSkipped = true; var includeZeroWidth = true; token = token.HasValue ? token.Value.GetNextToken(includeZeroWidth, includeSkipped, includeDirectives, includeDocumentationComments) : Node?.GetFirstToken(includeZeroWidth, includeSkipped, includeDirectives, includeDocumentationComments); if (token.HasValue) { if (!_starts.Any() && token.Value.SpanStart != 0) { } var tuple = new StartInfo(token.Value.Span, token.Value); _starts.Add(tuple); DumpStarts(); return(token.Value.Span); } return(null); } TextSpan?span = null; if (textSourceCharacterIndex == 0) { if (Length == 0) { return(new TextEndOfParagraph(2)); } _curStart = 0; if (_starts.Any()) { var startInfo = _starts.First(); token = startInfo.Token; trivia = startInfo.SyntaxTrivia; span = startInfo.TextSpan; if (token.HasValue) { CheckToken(token); } } // _starts.Clear(); DumpStarts(); } else { var startInfo = _starts[_curStart]; token = startInfo.Token; trivia = startInfo.SyntaxTrivia; span = startInfo.TextSpan; if (token.HasValue) { CheckToken(token); } } try { var childInPos = Node.ChildThatContainsPosition(textSourceCharacterIndex); if (childInPos.IsNode) { var n = childInPos.AsNode(); if (textSourceCharacterIndex < n.SpanStart) { foreach (var syntaxTrivia in n.GetLeadingTrivia()) { if (textSourceCharacterIndex >= syntaxTrivia.SpanStart && textSourceCharacterIndex < syntaxTrivia.Span.End) { Debug.WriteLine("In trivia " + syntaxTrivia); if (textSourceCharacterIndex > syntaxTrivia.SpanStart) { Debug.WriteLine("In middle of trivia"); } var characterString = syntaxTrivia.ToFullString(); return(new SyntaxTriviaTextCharacters(characterString, PropsFor(syntaxTrivia, characterString), syntaxTrivia.FullSpan, syntaxTrivia, null, null, TriviaPosition.Leading)); } } } } } catch (Exception ex) { } var token1 = token; // Debug.WriteLine("Index = " + textSourceCharacterIndex); // if (!token1.HasValue) // { // span = TakeToken(); // if (!this.token.HasValue) return new TextEndOfParagraph(2); // token1 = this.token; // } // var token = token1.Value; if (!span.HasValue) { throw new InvalidOperationException(); } var k = span.Value; if (textSourceCharacterIndex < k.Start) { var len = k.Start - textSourceCharacterIndex; var buf = new char[len]; Text.CopyTo(textSourceCharacterIndex, buf, 0, len); if (len == 2 && buf[0] == '\r' && buf[1] == '\n') { return(new CustomTextEndOfLine(2)); } var t = string.Join("", buf); return(new CustomTextCharacters(t, MakeProperties(SyntaxKind.None, t))); } else if (textSourceCharacterIndex >= k.End && k.Length != 0) { TakeToken(); return(GetTextRun(textSourceCharacterIndex)); } else { if (trivia.HasValue) { var syntaxTrivia1 = trivia.Value; var q = syntaxTrivia1.Token.LeadingTrivia .SkipWhile(syntaxTrivia => syntaxTrivia != syntaxTrivia1) .Skip(1); if (q.Any()) { _curStart++; var startInfo = new StartInfo(q.First()); if (_starts.Count <= _curStart) { _starts.Add(startInfo); } else { _starts[_curStart] = startInfo; } } else { var t2 = syntaxTrivia1.Token.GetNextToken(true, true, true, true); if (t2.HasLeadingTrivia) { var st = new StartInfo(t2.LeadingTrivia.First()); _curStart++; if (_starts.Count <= _curStart) { _starts.Add(st); } else { _starts[_curStart] = st; } } else if (CSharpExtensions.Kind(t2) != SyntaxKind.None) { var st = new StartInfo(t2.Span, t2); _curStart++; if (_starts.Count <= _curStart) { _starts.Add(st); } else { _starts[_curStart] = st; } } } var t = syntaxTrivia1.ToFullString(); return(new SyntaxTriviaTextCharacters(t, PropsFor(trivia.Value, t), span.Value, syntaxTrivia1, null, null, TriviaPosition.Leading)); } if (token.HasValue && (CSharpExtensions.Kind(token.Value) == SyntaxKind.None || CSharpExtensions.Kind(token.Value) == SyntaxKind.EndOfFileToken)) { return(new TextEndOfParagraph(2)); } var token0 = token.Value; if (CSharpExtensions.Kind(token0) == SyntaxKind.EndOfLineTrivia) { return(new CustomTextEndOfLine(2)); } var len = k.Length; if (len == 0) { TakeToken(); return(GetTextRun(textSourceCharacterIndex)); } TakeToken(); if (token0.Text.Length != len) { } return(new CustomTextCharacters(token0.Text, MakeProperties(token, token0.Text))); } #endif }
public void Clear() { Runs.Clear(); }