private void AnalyzeToken( SemanticModelAnalysisContext context, RegexPatternDetector detector, SyntaxToken token, CancellationToken cancellationToken ) { if (token.RawKind == _info.StringLiteralTokenKind) { var tree = detector.TryParseRegexPattern( token, context.SemanticModel, cancellationToken ); if (tree != null) { foreach (var diag in tree.Diagnostics) { context.ReportDiagnostic( DiagnosticHelper.Create( Descriptor, Location.Create(context.SemanticModel.SyntaxTree, diag.Span), ReportDiagnostic.Warn, additionalLocations: null, properties: null, diag.Message ) ); } } } }
internal async Task <(RegexTree tree, SyntaxToken token)> TryGetTreeAndTokenAtPositionAsync( Document document, int position, CancellationToken cancellationToken) { var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var token = root.FindToken(position); var syntaxFacts = document.GetLanguageService <ISyntaxFactsService>(); if (!RegexPatternDetector.IsPossiblyPatternToken(token, syntaxFacts)) { return(default);
public void Analyze(SemanticModelAnalysisContext context) { var semanticModel = context.SemanticModel; var syntaxTree = semanticModel.SyntaxTree; var cancellationToken = context.CancellationToken; var options = context.Options; var optionSet = options.GetDocumentOptionSetAsync( semanticModel.SyntaxTree, cancellationToken).GetAwaiter().GetResult(); if (optionSet == null) { return; } var option = optionSet.GetOption(RegularExpressionsOptions.ReportInvalidRegexPatterns, syntaxTree.Options.Language); if (!option) { return; } var detector = RegexPatternDetector.TryGetOrCreate(semanticModel, _info); if (detector == null) { return; } // Use an actual stack object so that we don't blow the actual stack through recursion. var root = syntaxTree.GetRoot(cancellationToken); var stack = new Stack <SyntaxNode>(); stack.Push(root); while (stack.Count != 0) { cancellationToken.ThrowIfCancellationRequested(); var current = stack.Pop(); foreach (var child in current.ChildNodesAndTokens()) { if (child.IsNode) { stack.Push(child.AsNode()); } else { AnalyzeToken(context, detector, child.AsToken(), cancellationToken); } } } }