internal SyntaxTree(string sourceText, SyntaxNode root, SyntaxTokenList tokens, IReadOnlyList<TextLineExtent> textLines, IReadOnlyList<Diagnostic> diagnostics, FileInfo fileInfo, Encoding encoding) { _sourceText = sourceText ?? String.Empty; _root = root; _fileInfo = fileInfo; _encoding = encoding; _diagnostics = diagnostics ?? Enumerable.Empty<Diagnostic>().ToList(); _tokens = tokens ?? new SyntaxTokenList(); _textLines = textLines ?? new List<TextLineExtent>(); }
void CheckNonNullChild(SyntaxNode node) { Assert.That(node, Is.Not.Null); foreach (var child in node.ChildNodes()) { CheckNonNullChild(child); } }
static SyntaxTokenList PostprocessTokens(List<SyntaxToken> tokens, NavCommonTokenStream cts, SyntaxNode syntax, CancellationToken cancellationToken) { var result = new List<SyntaxToken>(cts.AllTokens.Count); tokens.Sort((x, y) => x.Start - y.Start); // Wir haben bereits die signifikanten Token (T) im GrammarVisitor erstellt. // Wir können nicht alle Tokens hier ermitteln, da der Visitor viel mehr Kontextinformationen // hat. Somit wird aus einem "Identifier" z.B. je nach Kontext ein Keyword, oder Symbol (=> Classification). // Was uns hier jedoch noch fehlt sind vor allem die Whitespaces (w) und "unbekannten" (u), // die der Parser nie zu Gesicht bekommt. Der TokenStream liefert uns alle Token // (candidates = c): // -T---TTT---T----T-- <= bereits im Visitor erfasste Token // ccccccccccccccccccc <= alle Tokens (candidates) // wTwwwTTTwwwTwwwwTuu <= die Tokens, wie wir sie hier haben wollen var index = 0; foreach (var candidate in cts.AllTokens) { cancellationToken.ThrowIfCancellationRequested(); if (index < tokens.Count) { var existing = tokens[index]; // Das Token wurde bereits im Visitor erfasst (T) if (existing.Start == candidate.StartIndex) { result.Add(existing); index++; continue; } } // Das Token existiert noch nicht, da es der Parser/Visitor offensichtlich nicht "erwischt hat" (t, u) SyntaxTokenClassification tokenClassification; switch (candidate.Channel) { case NavGrammarLexer.TriviaChannel: switch (candidate.Type) { case NavGrammarLexer.NewLine: tokenClassification = SyntaxTokenClassification.Whitespace; break; case NavGrammarLexer.Whitespace: tokenClassification = SyntaxTokenClassification.Whitespace; break; case NavGrammarLexer.SingleLineComment: tokenClassification = SyntaxTokenClassification.Comment; break; case NavGrammarLexer.MultiLineComment: tokenClassification = SyntaxTokenClassification.Comment; break; case NavGrammarLexer.Unknown: tokenClassification = SyntaxTokenClassification.Skiped; break; default: // Wir haben sonst eigentlich nix im Trivia Channel throw new ArgumentException(); } break; case Lexer.DefaultTokenChannel: tokenClassification = SyntaxTokenClassification.Skiped; break; default: throw new ArgumentException(); } //TODO: hier evtl. den "echten" Parent herausfinden... SyntaxNode parent = syntax; result.Add(SyntaxTokenFactory.CreateToken(candidate, tokenClassification, parent)); } return new SyntaxTokenList(result); }
internal SyntaxToken(SyntaxNode parent, SyntaxTokenType type, SyntaxTokenClassification classification, TextExtent extent) { _extent = extent; _parent = parent; _classificationAndType = ((int)type << TypeBitShift) | ((int)classification << ClassificationBitShift); }