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

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

上级 21f3b5c6
......@@ -12,13 +12,15 @@ 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)
{
foreach (var language in languagesProvider.GetEmbeddedLanguages())
{
var analyzer = language.DiagnosticAnalyzer;
if (analyzer != null)
......@@ -27,6 +29,7 @@ internal abstract class AbstractEmbeddedLanguageDiagnosticAnalyzer : DiagnosticA
supportedDiagnostics.AddRange(analyzer.SupportedDiagnostics);
}
}
}
_analyzers = analyzers.ToImmutableAndFree();
this.SupportedDiagnostics = supportedDiagnostics.ToImmutableAndFree();
......
// 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,25 +54,36 @@ 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);
}
var stack = new Stack<SyntaxNodeOrToken>();
stack.Push(root);
private void Analyze(
SemanticModelAnalysisContext context, RegexPatternDetector detector,
SyntaxNode node, CancellationToken cancellationToken)
while (stack.Count != 0)
{
cancellationToken.ThrowIfCancellationRequested();
var current = stack.Pop();
foreach (var child in node.ChildNodesAndTokens())
if (current.IsNode)
{
if (child.IsNode)
var node = current.AsNode();
foreach (var child in node.ChildNodesAndTokens())
{
Analyze(context, detector, child.AsNode(), cancellationToken);
stack.Push(child);
}
}
else
{
var token = child.AsToken();
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);
......@@ -87,6 +100,4 @@ public void Analyze(SemanticModelAnalysisContext context, OptionSet optionSet)
}
}
}
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册