private bool TryClassify(IEmbeddedLanguageClassifier classifier, EmbeddedLanguageClassificationContext context) { var count = _result.Count; classifier.RegisterClassifications(context); return(_result.Count != count); }
private static void AddTriviaClassifications(RegexToken token, EmbeddedLanguageClassificationContext context) { foreach (var trivia in token.LeadingTrivia) { AddTriviaClassifications(trivia, context); } }
private static void AddTriviaClassifications(RegexTrivia trivia, EmbeddedLanguageClassificationContext context) { if (trivia.Kind == RegexKind.CommentTrivia && trivia.VirtualChars.Length > 0) { context.AddClassification(ClassificationTypeNames.RegexComment, GetSpan(trivia.VirtualChars)); } }
public void RegisterClassifications(EmbeddedLanguageClassificationContext context) { if (context.Project is null) { return; } var classifiers = AspNetCoreClassifierExtensionProvider.GetExtensions(context.Project); var aspContext = new AspNetCoreEmbeddedLanguageClassificationContext(context); foreach (var classifier in classifiers) { classifier.RegisterClassifications(aspContext); } }
private void ClassifyToken(SyntaxToken token) { if (token.Span.IntersectsWith(_textSpan) && _service._syntaxTokenKinds.Contains(token.RawKind)) { _classifierBuffer.Clear(); var context = new EmbeddedLanguageClassificationContext( _project, _semanticModel, token, _options, _result, _cancellationToken); // First, see if this is a string annotated with either a comment or [StringSyntax] attribute. If // so, delegate to the first classifier we have registered for whatever language ID we find. if (_service._detector.IsEmbeddedLanguageToken(token, _semanticModel, _cancellationToken, out var identifier, out _) && _service._identifierToClassifiers.TryGetValue(identifier, out var classifiers)) { foreach (var classifier in classifiers) { // keep track of what classifiers we've run so we don't call into them multiple times. _classifierBuffer.Add(classifier.Value); // If this classifier added values then need to check the other ones. if (TryClassify(classifier.Value, context)) { return; } } } // It wasn't an annotated API. See if it's some legacy API our historical classifiers have direct // support for (for example, .net APIs prior to Net6). foreach (var legacyClassifier in _service._legacyClassifiers) { // don't bother trying to classify again if we already tried above. if (_classifierBuffer.Contains(legacyClassifier.Value)) { continue; } // If this classifier added values then need to check the other ones. if (TryClassify(legacyClassifier.Value, context)) { return; } } // Finally, give the fallback classifier a chance to classify basic language escapes. TryClassify(_service._fallbackClassifier, context); } }
private static void AddClassifications(RegexNode node, Visitor visitor, EmbeddedLanguageClassificationContext context) { node.Accept(visitor); foreach (var child in node) { if (child.IsNode) { AddClassifications(child.Node, visitor, context); } else { AddTriviaClassifications(child.Token, context); } } }
public void RegisterClassifications(EmbeddedLanguageClassificationContext context) { var info = context.Project.GetRequiredLanguageService <IEmbeddedLanguagesProvider>().EmbeddedLanguageInfo; var token = context.SyntaxToken; if (!info.IsAnyStringLiteral(token.RawKind)) { return; } if (!context.Options.ColorizeRegexPatterns) { return; } var semanticModel = context.SemanticModel; var cancellationToken = context.CancellationToken; var detector = RegexLanguageDetector.GetOrCreate(semanticModel.Compilation, info); var tree = detector.TryParseString(token, semanticModel, cancellationToken); if (tree == null) { return; } var visitor = s_visitorPool.Allocate(); try { visitor.Context = context; AddClassifications(tree.Root, visitor, context); } finally { visitor.Context = default; s_visitorPool.Free(visitor); } }
public AspNetCoreEmbeddedLanguageClassificationContext(EmbeddedLanguageClassificationContext context) { _context = context; }