| File: Syntax\CSharpSyntaxTree.LazySyntaxTree.cs | Web Access |
| Project: src\roslyn\src\Compilers\CSharp\Portable\Microsoft.CodeAnalysis.CSharp.csproj (Microsoft.CodeAnalysis.CSharp) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Collections.Immutable; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Text; using System.Threading; using Microsoft.CodeAnalysis.Text; namespace Microsoft.CodeAnalysis.CSharp { public partial class CSharpSyntaxTree { private sealed class LazySyntaxTree : CSharpSyntaxTree { private readonly SourceText _text; private readonly CSharpParseOptions _options; private readonly string _path; private readonly ImmutableDictionary<string, ReportDiagnostic> _diagnosticOptions; private CSharpSyntaxNode? _lazyRoot; internal LazySyntaxTree( SourceText text, CSharpParseOptions options, string path, ImmutableDictionary<string, ReportDiagnostic>? diagnosticOptions) { Debug.Assert(options != null); _text = text; _options = options; _path = path ?? string.Empty; _diagnosticOptions = diagnosticOptions ?? EmptyDiagnosticOptions; } public override string FilePath { get { return _path; } } public override SourceText GetText(CancellationToken cancellationToken) { return _text; } public override bool TryGetText([NotNullWhen(true)] out SourceText? text) { text = _text; return true; } public override Encoding? Encoding { get { return _text.Encoding; } } public override int Length { get { return _text.Length; } } public override CSharpSyntaxNode GetRoot(CancellationToken cancellationToken) { if (_lazyRoot == null) { // Parse the syntax tree var tree = SyntaxFactory.ParseSyntaxTree(_text, _options, _path, cancellationToken); var root = CloneNodeAsRoot((CSharpSyntaxNode)tree.GetRoot(cancellationToken)); Interlocked.CompareExchange(ref _lazyRoot, root, null); } return _lazyRoot; } public override bool TryGetRoot([NotNullWhen(true)] out CSharpSyntaxNode? root) { root = _lazyRoot; return root != null; } public override bool HasCompilationUnitRoot { get { return true; } } public override CSharpParseOptions Options { get { return _options; } } [Obsolete("Obsolete due to performance problems, use CompilationOptions.SyntaxTreeOptionsProvider instead", error: false)] public override ImmutableDictionary<string, ReportDiagnostic> DiagnosticOptions => _diagnosticOptions; public override SyntaxReference GetReference(SyntaxNode node) { return new SimpleSyntaxReference(node); } public override SyntaxTree WithRootAndOptions(SyntaxNode root, ParseOptions options) { if (ReferenceEquals(_lazyRoot, root) && ReferenceEquals(_options, options)) { return this; } return new ParsedSyntaxTree( textOpt: null, _text.Encoding, _text.ChecksumAlgorithm, _path, (CSharpParseOptions)options, (CSharpSyntaxNode)root, _lazyDirectives, _diagnosticOptions, cloneRoot: true); } public override SyntaxTree WithFilePath(string path) { if (_path == path) { return this; } if (TryGetRoot(out var root)) { return new ParsedSyntaxTree( _text, _text.Encoding, _text.ChecksumAlgorithm, path, _options, root, directives: default, _diagnosticOptions, cloneRoot: true); } else { return new LazySyntaxTree(_text, _options, path, _diagnosticOptions); } } [Obsolete("Obsolete due to performance problems, use CompilationOptions.SyntaxTreeOptionsProvider instead", error: false)] public override SyntaxTree WithDiagnosticOptions(ImmutableDictionary<string, ReportDiagnostic> options) { if (options is null) { options = EmptyDiagnosticOptions; } if (ReferenceEquals(_diagnosticOptions, options)) { return this; } if (TryGetRoot(out var root)) { return new ParsedSyntaxTree( _text, _text.Encoding, _text.ChecksumAlgorithm, _path, _options, root, directives: default, options, cloneRoot: true); } else { return new LazySyntaxTree(_text, _options, _path, options); } } } } }