aspnetcore/src/Microsoft.AspNetCore.Razor..../Legacy/ParserContext.cs

109 lines
3.3 KiB
C#

// Copyright (c) .NET Foundation. 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.Diagnostics;
using System.IO;
namespace Microsoft.AspNetCore.Razor.Language.Legacy
{
internal partial class ParserContext
{
public ParserContext(RazorSourceDocument source, RazorParserOptions options)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
SourceDocument = source;
var chars = new char[source.Length];
source.CopyTo(0, chars, 0, source.Length);
Source = new SeekableTextReader(chars, source.FilePath);
DesignTimeMode = options.DesignTime;
ParseLeadingDirectives = options.ParseLeadingDirectives;
Builder = new SyntaxTreeBuilder();
ErrorSink = new ErrorSink();
SeenDirectives = new HashSet<string>(StringComparer.Ordinal);
}
public SyntaxTreeBuilder Builder { get; }
public ErrorSink ErrorSink { get; set; }
public HashSet<string> SeenDirectives { get; }
public ITextDocument Source { get; }
public RazorSourceDocument SourceDocument { get; }
public bool DesignTimeMode { get; }
public bool ParseLeadingDirectives { get; }
public bool WhiteSpaceIsSignificantToAncestorBlock { get; set; }
public bool NullGenerateWhitespaceAndNewLine { get; set; }
public bool EndOfFile
{
get { return Source.Peek() == -1; }
}
}
// Debug Helpers
#if DEBUG
[DebuggerDisplay("{" + nameof(DebuggerToString) + "(),nq}")]
internal partial class ParserContext
{
private const int InfiniteLoopCountThreshold = 1000;
private int _infiniteLoopGuardCount = 0;
private SourceLocation? _infiniteLoopGuardLocation = null;
internal string Unparsed
{
get
{
var remaining = ((TextReader)Source).ReadToEnd();
Source.Position -= remaining.Length;
return remaining;
}
}
private bool CheckInfiniteLoop()
{
// Infinite loop guard
// Basically, if this property is accessed 1000 times in a row without having advanced the source reader to the next position, we
// cause a parser error
if (_infiniteLoopGuardLocation != null)
{
if (Source.Location.Equals(_infiniteLoopGuardLocation.Value))
{
_infiniteLoopGuardCount++;
if (_infiniteLoopGuardCount > InfiniteLoopCountThreshold)
{
Debug.Fail("An internal parser error is causing an infinite loop at this location.");
return true;
}
}
else
{
_infiniteLoopGuardCount = 0;
}
}
_infiniteLoopGuardLocation = Source.Location;
return false;
}
private string DebuggerToString()
{
return Unparsed;
}
}
#endif
}