提交 bb5f0b6a 编写于 作者: C Cyrus Najmabadi

Use a real stack object instead of recursion to prevent stack overflows in large trees.

上级 21f3b5c6
......@@ -12,19 +12,22 @@ internal abstract class AbstractEmbeddedLanguageDiagnosticAnalyzer : DiagnosticA
private readonly ImmutableArray<IEmbeddedDiagnosticAnalyzer> _analyzers;
protected AbstractEmbeddedLanguageDiagnosticAnalyzer(
IEmbeddedLanguagesProvider embeddedLanguagesProvider)
IEmbeddedLanguagesProvider languagesProvider)
{
var supportedDiagnostics = ArrayBuilder<DiagnosticDescriptor>.GetInstance();
var analyzers = ArrayBuilder<IEmbeddedDiagnosticAnalyzer>.GetInstance();
foreach (var language in embeddedLanguagesProvider.GetEmbeddedLanguages())
if (languagesProvider != null)
{
var analyzer = language.DiagnosticAnalyzer;
if (analyzer != null)
foreach (var language in languagesProvider.GetEmbeddedLanguages())
{
analyzers.Add(analyzer);
supportedDiagnostics.AddRange(analyzer.SupportedDiagnostics);
var analyzer = language.DiagnosticAnalyzer;
if (analyzer != null)
{
analyzers.Add(analyzer);
supportedDiagnostics.AddRange(analyzer.SupportedDiagnostics);
}
}
}
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Threading;
using Microsoft.CodeAnalysis.Diagnostics;
......@@ -52,38 +54,47 @@ public void Analyze(SemanticModelAnalysisContext context, OptionSet optionSet)
return;
}
// Use an actual stack object so that we don't blow the actual stack through recursion.
var root = syntaxTree.GetRoot(cancellationToken);
Analyze(context, detector, root, cancellationToken);
}
private void Analyze(
SemanticModelAnalysisContext context, RegexPatternDetector detector,
SyntaxNode node, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
var stack = new Stack<SyntaxNodeOrToken>();
stack.Push(root);
foreach (var child in node.ChildNodesAndTokens())
while (stack.Count != 0)
{
if (child.IsNode)
cancellationToken.ThrowIfCancellationRequested();
var current = stack.Pop();
if (current.IsNode)
{
Analyze(context, detector, child.AsNode(), cancellationToken);
var node = current.AsNode();
foreach (var child in node.ChildNodesAndTokens())
{
stack.Push(child);
}
}
else
{
var token = child.AsToken();
if (token.RawKind == _language.StringLiteralKind)
AnalyzeToken(context, detector, current.AsToken(), cancellationToken);
}
}
}
private void AnalyzeToken(
SemanticModelAnalysisContext context, RegexPatternDetector detector,
SyntaxToken token, CancellationToken cancellationToken)
{
if (token.RawKind == _language.StringLiteralKind)
{
var tree = detector.TryParseRegexPattern(token, cancellationToken);
if (tree != null)
{
foreach (var diag in tree.Diagnostics)
{
var tree = detector.TryParseRegexPattern(token, cancellationToken);
if (tree != null)
{
foreach (var diag in tree.Diagnostics)
{
context.ReportDiagnostic(Diagnostic.Create(
_descriptor,
Location.Create(context.SemanticModel.SyntaxTree, diag.Span),
diag.Message));
}
}
context.ReportDiagnostic(Diagnostic.Create(
_descriptor,
Location.Create(context.SemanticModel.SyntaxTree, diag.Span),
diag.Message));
}
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册