using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Linq; using System.Numerics; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using Esprima.Ast; using Esprima.Ast.Jsx; using Esprima.Utils; using Esprima.Utils.Jsx; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: InternalsVisibleTo("Esprima.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100bf2553c9f214cb21f1f64ed62cadad8fe4f2fa11322a5dfa1d650743145c6085aba05b145b29867af656e0bb9bfd32f5d0deb1668263a38233e7e8e5bad1a3c6edd3f2ec6c512668b4aa797283101444628650949641b4f7cb16707efba542bb754afe87ce956f3a5d43f450d14364eb9571cbf213d1061852fb9dd47a6c05c4")] [assembly: InternalsVisibleTo("Esprima.Benchmark, PublicKey=0024000004800000940000000602000000240000525341310004000001000100bf2553c9f214cb21f1f64ed62cadad8fe4f2fa11322a5dfa1d650743145c6085aba05b145b29867af656e0bb9bfd32f5d0deb1668263a38233e7e8e5bad1a3c6edd3f2ec6c512668b4aa797283101444628650949641b4f7cb16707efba542bb754afe87ce956f3a5d43f450d14364eb9571cbf213d1061852fb9dd47a6c05c4")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Sebastien Ros")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Sebastien Ros")] [assembly: AssemblyDescription("Standard-compliant ECMAScript 2022 parser (also known as JavaScript).")] [assembly: AssemblyFileVersion("3.0.5.0")] [assembly: AssemblyInformationalVersion("3.0.5+4661614f09d4bb476a552f8dae82a5887060d570")] [assembly: AssemblyProduct("Esprima")] [assembly: AssemblyTitle("Esprima .NET")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/sebastienros/esprima-dotnet")] [assembly: NeutralResourcesLanguage("en-US")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("3.0.5.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [module: SkipLocalsInit] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace System { internal static class HexConverter { public static ReadOnlySpan CharToHexLookup => new byte[256] { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255, 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool IsHexChar(int c) { if (IntPtr.Size == 8) { ulong num = (uint)(c - 48); long num2 = -17875860044349952L << (int)num; ulong num3 = num - 64; return (long)((ulong)num2 & num3) < 0L; } return FromChar(c) != 255; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int FromChar(int c) { if (c < CharToHexLookup.Length) { return CharToHexLookup[c]; } return 255; } } } namespace System.Runtime.CompilerServices { [EditorBrowsable(EditorBrowsableState.Never)] [ExcludeFromCodeCoverage] internal static class IsExternalInit { } [AttributeUsage(AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Interface, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class SkipLocalsInitAttribute : Attribute { } } namespace Esprima { internal struct ArrayList : IReadOnlyList, IEnumerable, IEnumerable, IReadOnlyCollection { public struct Enumerator : IEnumerator, IEnumerator, IDisposable { private readonly T[]? _items; private readonly int _count; private int _index; private T? _current; public T Current => _current; object? IEnumerator.Current { get { if (_index == 0 || _index == _count + 1) { EsprimaExceptionHelper.ThrowInvalidOperationException(); } return Current; } } internal Enumerator(T[]? items, int count) { this = default(Enumerator); _index = 0; _items = items; _count = count; } public void Dispose() { } public bool MoveNext() { if (_index < _count) { _current = _items[_index]; _index++; return true; } return MoveNextRare(); } private bool MoveNextRare() { _index = _count + 1; _current = default(T); return false; } public void Reset() { _index = 0; _current = default(T); } } private const int MinAllocatedCount = 4; private T[]? _items; private int _count; public int Capacity { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { T[]? items = _items; if (items == null) { return 0; } return items.Length; } set { if (value < _count) { EsprimaExceptionHelper.ThrowArgumentOutOfRangeException("value", value); return; } T[]? items = _items; if (value == ((items != null) ? items.Length : 0)) { return; } if (value > 0) { T[] array = new T[value]; if (_count > 0) { Array.Copy(_items, 0, array, 0, _count); } _items = array; } else { _items = null; } } } public int Count { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _count; } } public T this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { if ((uint)index < (uint)_count) { return _items[index]; } return EsprimaExceptionHelper.ThrowIndexOutOfRangeException(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] set { if ((uint)index < (uint)_count) { _items[index] = value; } else { EsprimaExceptionHelper.ThrowIndexOutOfRangeException(); } } } public ArrayList(int initialCapacity) { if (initialCapacity < 0) { ThrowInvalidInitialCapacity(); } _items = ((initialCapacity > 0) ? new T[initialCapacity] : null); _count = 0; [MethodImpl(MethodImplOptions.NoInlining)] static void ThrowInvalidInitialCapacity() { EsprimaExceptionHelper.ThrowArgumentException("Invalid initial capacity", "initialCapacity"); } } internal ArrayList(T[] items) { _items = items; _count = items.Length; } [Conditional("DEBUG")] private void AssertUnchanged() { } [Conditional("DEBUG")] private void OnChanged() { } public void AddRange(ReadOnlySpan items) { int length = items.Length; if (length != 0) { int count = _count; int num = count + length; if (Capacity < num) { Array.Resize(ref _items, Math.Max(num, 4)); } items.CopyTo(_items.AsSpan(count, length)); _count = num; } } public void AddRange(ArrayList list) where TSource : class, T { T[] items = (T[])(object)list._items; AddRange(new ReadOnlySpan(items, 0, list._count)); } public void Add(T item) { int capacity = Capacity; if (_count == capacity) { Array.Resize(ref _items, Math.Max(capacity * 2, 4)); } _items[_count] = item; _count++; } public void Clear() { if (_count > 0) { Array.Clear(_items, 0, _count); _count = 0; } } public void Insert(int index, T item) { if ((uint)index > (uint)_count) { EsprimaExceptionHelper.ThrowIndexOutOfRangeException(); } int capacity = Capacity; if (_count == capacity) { Array.Resize(ref _items, Math.Max(capacity * 2, 4)); } Array.Copy(_items, index, _items, index + 1, Count - index); _items[index] = item; _count++; } public void RemoveAt(int index) { if ((uint)index >= (uint)_count) { EsprimaExceptionHelper.ThrowIndexOutOfRangeException(); } _count--; if (index < _count) { Array.Copy(_items, index + 1, _items, index, Count - index); } _items[_count] = default(T); } public void Sort(IComparer? comparer = null) { if (_count > 1) { Array.Sort(_items, 0, _count, comparer); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Push(T item) { Add(item); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public T Pop() { int index = _count - 1; T result = this[index]; RemoveAt(index); return result; } public void Yield(out T[]? items, out int count) { items = _items; count = _count; this = default(ArrayList); } public void TrimExcess(int threshold = 4) { if (Capacity - _count > threshold) { Capacity = _count; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public Span AsSpan() { return new Span(_items, 0, _count); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ReadOnlySpan AsReadOnlySpan() { return new ReadOnlySpan(_items, 0, _count); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public T[] ToArray() { return AsReadOnlySpan().ToArray(); } public Enumerator GetEnumerator() { return new Enumerator(_items, _count); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } internal static class ArrayList { public static ArrayList Create(in NodeList source) where T : Node { return new ArrayList(source.ToArray()); } public static void AddRange(this ref ArrayList destination, in NodeList source) where T : Node { foreach (T item in source) { destination.Add(item); } } } [Flags] internal enum CharacterMask : byte { None = 0, WhiteSpace = 1, IdentifierStart = 2, IdentifierPart = 4 } public static class Character { internal const int UnicodeLastCodePoint = 1114111; internal static readonly Func IsDecimalDigitFunc = IsDecimalDigit; internal static readonly Func IsHexDigitFunc = IsHexDigit; internal static readonly Func IsOctalDigitFunc = IsOctalDigit; private static readonly int[] s_identifierStartAstralRanges = new int[281] { 16777217, 16780546, 16787459, 16792580, 16793349, 16797702, 16809991, 16859144, 16941065, 16949258, 16973835, 16985356, 16994317, 17006604, 17014798, 17025039, 17027344, 17039377, 17084430, 17094670, 17104914, 17117203, 17133588, 17136645, 17140757, 17142788, 17143572, 17146629, 17150741, 17152772, 17170454, 17252375, 17260559, 17268760, 17270553, 17281562, 17301528, 17303552, 17304091, 17315588, 17316864, 17317660, 17326108, 17334301, 17358851, 17363972, 17367063, 17375234, 17399838, 17415684, 17432576, 17436703, 17437984, 17438985, 17457161, 17465353, 17481743, 17484065, 17498146, 17514519, 17522691, 17530915, 17563684, 17596453, 17612837, 17629198, 17727513, 17739780, 17760265, 17770240, 17772567, 17788963, 17805350, 17817628, 17826568, 17854724, 17855744, 17859367, 17879080, 17892110, 17908736, 17909504, 17911849, 17921536, 17924906, 17940767, 17947136, 17947648, 17956899, 17961768, 17972996, 17989653, 17991680, 17992223, 17993477, 17997611, 18001964, 18023695, 18026244, 18027287, 18033173, 18035204, 18035984, 18038016, 18042880, 18046224, 18087944, 18106143, 18112288, 18120746, 18138116, 18138880, 18186284, 18208799, 18219050, 18236416, 18251821, 18266112, 18284590, 18300949, 18350107, 18391087, 18415375, 18417920, 18418703, 18420996, 18421808, 18431744, 18432256, 18456591, 18459185, 18473216, 18473728, 18481152, 18483986, 18496000, 18501632, 18504754, 18521344, 18526244, 18612250, 18614835, 18628608, 18641420, 18677781, 18679812, 18680589, 18695680, 18702360, 18704132, 18704907, 18716672, 18800643, 18809344, 18809908, 18813493, 18853888, 18874422, 19136567, 19169336, 19894329, 19923002, 20201752, 21233723, 23593020, 23740445, 23752765, 23777292, 23789610, 23805983, 23814950, 23821571, 24002607, 24051774, 24072192, 24089396, 24109060, 24109824, 24117311, 25690176, 26017818, 28307487, 28308757, 28310788, 28311617, 28389888, 28397600, 28398848, 28402719, 28405826, 29098051, 29126708, 29130778, 29134891, 30670916, 30692933, 30711300, 30712320, 30713092, 30714143, 30715393, 30718720, 30719253, 30721350, 30738207, 30739727, 30742037, 30744097, 30751519, 30752784, 30754304, 30755349, 30757447, 30844968, 30851624, 30858269, 30866472, 30873117, 30881320, 30887965, 30896168, 30902813, 30911016, 30917647, 31391773, 31401240, 31469640, 31522855, 31536917, 31542784, 31625228, 31637531, 31772705, 31973397, 31975455, 31976708, 31977477, 31981641, 32047178, 32066304, 32374815, 32376110, 32383236, 32384000, 32384768, 32385323, 32388127, 32389376, 32389888, 32391680, 32392960, 32393472, 32393984, 32394528, 32395524, 32396288, 32397056, 32397568, 32398080, 32398592, 32399104, 32399620, 32400384, 32401183, 32402453, 32404511, 32405791, 32407040, 32407595, 32410443, 32416032, 32417040, 32418635, 33554508, 44499021, 45563982, 45621327, 47099984, 49807441, 50331730, 51597395 }; private static readonly int[] s_identifierPartAstralRanges = new int[340] { 16777217, 16780546, 16787459, 16792580, 16793349, 16797702, 16809991, 16859144, 16907520, 16941065, 16949258, 16965632, 16973835, 16985356, 16994349, 17006604, 17014798, 17025039, 17027344, 17039377, 17080363, 17084430, 17094670, 17104914, 17117203, 17133588, 17136645, 17140757, 17142788, 17143572, 17146629, 17150741, 17152772, 17170454, 17252375, 17260559, 17268760, 17270553, 17281562, 17301528, 17303552, 17304091, 17315588, 17316864, 17317660, 17326108, 17334301, 17358851, 17363972, 17367063, 17375234, 17399838, 17415684, 17432607, 17433860, 17435663, 17437984, 17438985, 17446944, 17448704, 17457161, 17465353, 17481743, 17484044, 17498146, 17514519, 17522691, 17530915, 17563684, 17596453, 17612837, 17629202, 17641515, 17727513, 17738500, 17739780, 17759499, 17770240, 17772628, 17788951, 17805350, 17817628, 17825861, 17851989, 17858390, 17875456, 17879080, 17887275, 17891336, 17905195, 17908767, 17911822, 17921536, 17924183, 17942815, 17944116, 17947648, 17956899, 17961779, 17972767, 17989653, 17991680, 17992223, 17993477, 17997611, 18002008, 18018347, 18022431, 18023695, 18026244, 18027287, 18033173, 18035204, 18035984, 18037547, 18040580, 18041632, 18042880, 18044672, 18046229, 18048533, 18051088, 18087998, 18108459, 18112031, 18120793, 18138880, 18141227, 18186274, 18200602, 18208792, 18219078, 18236416, 18239531, 18251866, 18268203, 18284590, 18291973, 18296875, 18300949, 18350168, 18391131, 18415375, 18417920, 18418703, 18420996, 18421772, 18429700, 18430746, 18436139, 18456591, 18459186, 18471439, 18473732, 18481244, 18499328, 18501723, 18521344, 18526244, 18612250, 18614823, 18626586, 18632747, 18641420, 18649623, 18655494, 18677781, 18679812, 18680603, 18692608, 18693124, 18693914, 18698283, 18702360, 18704132, 18704947, 18714628, 18715416, 18718763, 18800668, 18808907, 18813533, 18824720, 18829355, 18853888, 18874422, 19136567, 19169336, 19894329, 19923002, 20201495, 21233723, 23593020, 23740445, 23748651, 23752765, 23773227, 23777292, 23785488, 23789662, 23805983, 23810091, 23814950, 23821571, 24002607, 24051774, 24072026, 24088395, 24109060, 24109828, 24113156, 24117311, 25690176, 26017818, 28307487, 28308757, 28310788, 28311617, 28389888, 28397600, 28398848, 28402719, 28405826, 29098051, 29126708, 29130778, 29134891, 29138180, 30343218, 30355484, 30500112, 30502168, 30505743, 30508309, 30517791, 30556704, 30670916, 30692933, 30711300, 30712320, 30713092, 30714143, 30715393, 30718720, 30719253, 30721350, 30738207, 30739727, 30742037, 30744097, 30751519, 30752784, 30754304, 30755349, 30757447, 30844968, 30851624, 30858269, 30866472, 30873117, 30881320, 30887965, 30896168, 30902813, 30911016, 30917647, 30920287, 31064158, 31079263, 31094016, 31097856, 31103760, 31105285, 31391773, 31401240, 31457301, 31459403, 31464213, 31466244, 31467024, 31469640, 31493888, 31522855, 31535110, 31539243, 31542784, 31625245, 31637600, 31772697, 31973397, 31975455, 31976708, 31977477, 31981641, 32034837, 32047201, 32067627, 32374815, 32376110, 32383236, 32384000, 32384768, 32385323, 32388127, 32389376, 32389888, 32391680, 32392960, 32393472, 32393984, 32394528, 32395524, 32396288, 32397056, 32397568, 32398080, 32398592, 32399104, 32399620, 32400384, 32401183, 32402453, 32404511, 32405791, 32407040, 32407595, 32410443, 32416032, 32417040, 32418635, 33288235, 33554508, 44499021, 45563982, 45621327, 47099984, 49807441, 50331730, 51597395, 234946658 }; private static readonly int[] s_rangeLengthLookup = new int[99] { 0, 11, 25, 18, 1, 14, 13, 122, 52, 28, 48, 31, 29, 37, 35, 7, 4, 157, 39, 51, 10, 6, 310, 21, 5, 41, 8, 43, 22, 30, 55, 3, 2, 27, 53, 17, 72, 50, 20, 44, 24, 34, 47, 9, 46, 42, 26, 63, 23, 38, 45, 36, 12, 33, 921, 110, 195, 96, 1071, 582, 568, 78, 74, 6135, 1237, 290, 395, 106, 84, 70, 64, 339, 61, 196, 67, 16, 42719, 4153, 221, 5761, 7472, 541, 4938, 4191, 32, 15, 59, 68, 58, 69, 56, 73, 62, 40, 54, 49, 57, 75, 239 }; private static ReadOnlySpan s_characterData => new byte[32768] { 0, 0, 0, 0, 16, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 6, 0, 0, 0, 0, 0, 68, 68, 68, 68, 68, 0, 0, 0, 96, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 6, 96, 96, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 6, 0, 0, 0, 0, 96, 64, 0, 6, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 0, 0, 102, 102, 102, 102, 102, 102, 0, 0, 0, 0, 0, 0, 0, 102, 102, 6, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 102, 102, 6, 102, 0, 102, 102, 96, 0, 0, 0, 70, 102, 6, 6, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 96, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 96, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 64, 68, 68, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 96, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 96, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 0, 0, 0, 64, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 64, 64, 4, 68, 64, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 0, 96, 102, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 68, 68, 68, 4, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 70, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 0, 0, 102, 100, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 96, 68, 68, 68, 4, 64, 68, 68, 100, 70, 4, 68, 68, 102, 68, 68, 68, 68, 68, 102, 6, 96, 0, 0, 0, 0, 0, 0, 0, 0, 70, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 4, 96, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 68, 68, 68, 68, 68, 100, 0, 0, 0, 0, 0, 0, 0, 68, 68, 68, 68, 68, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 70, 68, 68, 68, 68, 102, 0, 0, 6, 64, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 68, 68, 70, 68, 68, 68, 68, 70, 68, 70, 68, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 70, 68, 0, 0, 102, 102, 102, 102, 102, 6, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 96, 102, 102, 6, 0, 0, 0, 0, 68, 68, 68, 68, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 64, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 68, 100, 68, 68, 68, 68, 68, 68, 68, 68, 68, 70, 68, 68, 68, 102, 102, 102, 102, 102, 68, 0, 68, 68, 68, 68, 68, 96, 102, 102, 102, 102, 102, 102, 102, 70, 68, 96, 102, 102, 102, 6, 96, 6, 96, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 102, 102, 102, 6, 6, 0, 102, 102, 0, 100, 68, 68, 68, 4, 64, 4, 64, 68, 6, 0, 0, 0, 64, 0, 0, 102, 96, 102, 68, 0, 68, 68, 68, 68, 68, 102, 0, 0, 0, 0, 0, 6, 4, 64, 68, 96, 102, 102, 6, 0, 96, 6, 96, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 102, 102, 102, 6, 102, 96, 6, 102, 0, 4, 68, 68, 4, 0, 64, 4, 64, 68, 0, 64, 0, 0, 0, 96, 102, 6, 6, 0, 0, 0, 68, 68, 68, 68, 68, 68, 102, 70, 0, 0, 0, 0, 0, 64, 68, 96, 102, 102, 102, 102, 96, 102, 96, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 102, 102, 102, 6, 102, 96, 102, 102, 0, 100, 68, 68, 68, 68, 64, 68, 64, 68, 0, 6, 0, 0, 0, 0, 0, 0, 0, 102, 68, 0, 68, 68, 68, 68, 68, 0, 0, 0, 0, 96, 68, 68, 68, 64, 68, 96, 102, 102, 102, 6, 96, 6, 96, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 102, 102, 102, 6, 102, 96, 102, 102, 0, 100, 68, 68, 68, 4, 64, 4, 64, 68, 0, 0, 0, 64, 68, 0, 0, 102, 96, 102, 68, 0, 68, 68, 68, 68, 68, 96, 0, 0, 0, 0, 0, 0, 0, 0, 100, 96, 102, 102, 6, 0, 102, 6, 102, 102, 0, 96, 6, 6, 102, 0, 96, 6, 0, 102, 6, 0, 102, 102, 102, 102, 102, 102, 0, 0, 68, 68, 4, 0, 68, 4, 68, 68, 0, 6, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 68, 68, 68, 68, 68, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 100, 102, 102, 102, 6, 102, 6, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 102, 102, 102, 102, 102, 102, 102, 102, 0, 100, 68, 68, 68, 4, 68, 4, 68, 68, 0, 0, 0, 64, 4, 102, 6, 96, 0, 102, 68, 0, 68, 68, 68, 68, 68, 0, 0, 0, 0, 0, 0, 0, 0, 70, 68, 96, 102, 102, 102, 6, 102, 6, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 102, 102, 102, 102, 102, 96, 102, 102, 0, 100, 68, 68, 68, 4, 68, 4, 68, 68, 0, 0, 0, 64, 4, 0, 0, 96, 6, 102, 68, 0, 68, 68, 68, 68, 68, 96, 70, 0, 0, 0, 0, 0, 0, 68, 68, 102, 102, 102, 102, 6, 102, 6, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 70, 100, 68, 68, 68, 4, 68, 4, 68, 68, 6, 0, 0, 102, 70, 0, 0, 0, 96, 102, 68, 0, 68, 68, 68, 68, 68, 0, 0, 0, 0, 0, 102, 102, 102, 64, 68, 96, 102, 102, 102, 102, 102, 102, 102, 102, 6, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 96, 102, 102, 102, 102, 96, 0, 102, 102, 102, 6, 0, 4, 0, 64, 68, 68, 4, 4, 68, 68, 68, 68, 0, 0, 0, 68, 68, 68, 68, 68, 0, 68, 0, 0, 0, 0, 0, 0, 96, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 70, 102, 68, 68, 68, 4, 0, 0, 102, 102, 102, 70, 68, 68, 68, 4, 68, 68, 68, 68, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 6, 6, 102, 102, 6, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 96, 96, 102, 102, 102, 102, 70, 102, 68, 68, 68, 68, 100, 0, 102, 102, 6, 6, 68, 68, 68, 4, 68, 68, 68, 68, 68, 0, 102, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 68, 68, 68, 68, 0, 0, 0, 0, 0, 64, 64, 64, 0, 0, 68, 102, 102, 102, 102, 96, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 0, 64, 68, 68, 68, 68, 68, 68, 68, 68, 68, 4, 68, 102, 102, 70, 68, 68, 68, 68, 68, 64, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 4, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 70, 68, 68, 68, 68, 68, 68, 68, 68, 68, 100, 68, 68, 68, 68, 68, 0, 0, 0, 102, 102, 102, 68, 68, 102, 102, 68, 100, 68, 100, 70, 68, 68, 68, 102, 70, 68, 100, 102, 102, 102, 102, 102, 102, 68, 68, 68, 68, 68, 68, 70, 68, 68, 68, 68, 68, 68, 68, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 96, 0, 0, 96, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 102, 102, 0, 102, 102, 102, 6, 6, 102, 102, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 102, 102, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 102, 102, 0, 102, 102, 102, 6, 6, 102, 102, 0, 102, 102, 102, 102, 102, 102, 102, 6, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 102, 102, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 64, 68, 0, 0, 0, 0, 64, 68, 68, 68, 68, 0, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 0, 102, 102, 102, 0, 96, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 96, 102, 102, 102, 102, 102, 102, 102, 102, 97, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 0, 102, 102, 102, 102, 102, 6, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 68, 68, 0, 0, 0, 0, 96, 102, 102, 102, 102, 102, 102, 102, 102, 102, 68, 4, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 68, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 6, 102, 6, 68, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 0, 96, 0, 0, 70, 0, 68, 68, 68, 68, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 68, 64, 68, 68, 68, 68, 68, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 70, 6, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 68, 68, 68, 68, 68, 68, 0, 0, 68, 68, 68, 68, 68, 68, 0, 0, 0, 0, 0, 68, 68, 68, 68, 68, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 0, 102, 102, 6, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 0, 0, 0, 68, 68, 68, 68, 68, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 70, 68, 68, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 70, 68, 68, 68, 68, 4, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 4, 64, 68, 68, 68, 68, 68, 0, 0, 0, 68, 68, 68, 68, 68, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 68, 68, 68, 68, 68, 68, 68, 64, 68, 68, 68, 68, 68, 68, 68, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 100, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 68, 68, 68, 68, 68, 68, 68, 68, 100, 102, 102, 102, 6, 0, 68, 68, 68, 68, 68, 0, 0, 0, 0, 0, 0, 0, 0, 64, 68, 68, 68, 68, 0, 0, 0, 0, 0, 0, 68, 100, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 70, 68, 68, 68, 68, 68, 68, 102, 68, 68, 68, 68, 68, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 68, 68, 68, 68, 68, 68, 68, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 0, 0, 0, 0, 68, 68, 68, 68, 68, 0, 96, 102, 68, 68, 68, 68, 68, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 0, 102, 102, 102, 102, 6, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 96, 102, 0, 0, 0, 0, 0, 0, 0, 0, 68, 4, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 100, 102, 70, 102, 102, 102, 100, 70, 68, 6, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 0, 102, 102, 102, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 0, 102, 102, 102, 0, 102, 102, 102, 102, 96, 96, 96, 96, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 102, 102, 102, 6, 6, 0, 102, 6, 102, 102, 102, 6, 0, 102, 102, 0, 102, 102, 102, 0, 0, 102, 102, 102, 102, 102, 102, 6, 0, 0, 102, 6, 102, 102, 102, 6, 0, 17, 17, 17, 17, 17, 1, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 64, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 68, 68, 68, 68, 4, 0, 64, 0, 64, 68, 68, 68, 68, 68, 4, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 96, 0, 102, 102, 102, 102, 102, 96, 0, 102, 102, 102, 0, 0, 0, 6, 6, 6, 102, 102, 102, 102, 102, 102, 102, 102, 0, 102, 102, 0, 0, 96, 102, 102, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 0, 0, 96, 102, 70, 68, 102, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 96, 0, 0, 96, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 64, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 0, 0, 0, 0, 102, 102, 102, 6, 102, 102, 102, 6, 102, 102, 102, 6, 102, 102, 102, 6, 102, 102, 102, 6, 102, 102, 102, 6, 102, 102, 102, 6, 102, 102, 102, 6, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 96, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 102, 102, 102, 102, 68, 68, 68, 96, 102, 102, 0, 102, 102, 6, 0, 96, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 64, 100, 102, 102, 96, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 102, 102, 0, 0, 96, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 96, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 0, 102, 102, 102, 102, 102, 102, 102, 102, 68, 68, 68, 68, 68, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 70, 0, 0, 68, 68, 68, 68, 68, 96, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 68, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 102, 102, 102, 102, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 96, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 0, 0, 102, 96, 96, 102, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 100, 102, 100, 102, 70, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 70, 68, 68, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 0, 0, 0, 0, 0, 0, 68, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 68, 68, 68, 68, 68, 68, 68, 68, 68, 0, 0, 0, 0, 0, 68, 68, 68, 68, 68, 0, 0, 0, 68, 68, 68, 68, 68, 68, 68, 68, 68, 102, 102, 102, 0, 96, 96, 70, 68, 68, 68, 68, 68, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 68, 68, 68, 68, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 70, 68, 68, 68, 68, 68, 68, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 0, 68, 68, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 70, 68, 68, 68, 68, 68, 68, 4, 0, 0, 0, 0, 0, 0, 96, 68, 68, 68, 68, 68, 0, 0, 0, 102, 102, 70, 102, 102, 102, 102, 102, 68, 68, 68, 68, 68, 102, 102, 6, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 70, 68, 68, 68, 68, 68, 68, 4, 0, 0, 0, 0, 102, 70, 102, 102, 102, 102, 68, 0, 68, 68, 68, 68, 68, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 0, 70, 68, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 100, 68, 100, 70, 100, 102, 102, 68, 70, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 102, 0, 102, 102, 102, 102, 102, 70, 68, 68, 0, 102, 70, 4, 0, 0, 0, 0, 96, 102, 102, 6, 96, 102, 102, 6, 96, 102, 102, 6, 0, 0, 0, 0, 102, 102, 102, 6, 102, 102, 102, 6, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 102, 102, 102, 102, 102, 102, 102, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 70, 68, 68, 68, 4, 68, 0, 68, 68, 68, 68, 68, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 0, 96, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 102, 6, 0, 0, 0, 0, 0, 96, 102, 102, 0, 0, 96, 100, 102, 102, 102, 102, 6, 102, 102, 102, 102, 102, 102, 6, 102, 102, 6, 6, 102, 96, 6, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 0, 0, 68, 68, 68, 68, 68, 68, 68, 68, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 68, 68, 68, 68, 68, 68, 0, 64, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 6, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 16, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 68, 68, 68, 0, 0, 0, 96, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 0, 64, 96, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 6, 0, 102, 102, 102, 0, 102, 102, 102, 0, 102, 102, 102, 0, 102, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static bool HasCharacterFlag(char ch, CharacterMask flag) { return (s_characterData[(int)ch >> 1] & ((uint)flag << ((ch & 1) << 2))) != 0; } internal static bool IsLineTerminator(char ch) { if (ch != '\n' && ch != '\r' && ch != '\u2028') { return ch == '\u2029'; } return true; } internal static bool IsWhiteSpace(char ch) { return HasCharacterFlag(ch, CharacterMask.WhiteSpace); } internal static bool IsIdentifierStart(char ch) { return HasCharacterFlag(ch, CharacterMask.IdentifierStart); } internal static bool IsIdentifierStartAstral(int cp) { return CodePointRange.RangesContain(cp, s_identifierStartAstralRanges, s_rangeLengthLookup); } internal static bool IsIdentifierPart(char ch) { return HasCharacterFlag(ch, CharacterMask.IdentifierPart); } internal static bool IsIdentifierPartAstral(int cp) { return CodePointRange.RangesContain(cp, s_identifierPartAstralRanges, s_rangeLengthLookup); } public static bool IsDecimalDigit(char cp) { return IsInRange(cp, '0', '9'); } public static bool IsHexDigit(char cp) { return System.HexConverter.IsHexChar(cp); } public static bool IsOctalDigit(char cp) { return IsInRange(cp, '0', '7'); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool IsInRange(char c, char min, char max) { return (uint)(c - min) <= (uint)(max - min); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void GetSurrogatePair(uint cp, out char highSurrogate, out char lowSurrogate) { highSurrogate = (char)(cp + 56557568 >> 10); lowSurrogate = (char)((cp & 0x3FF) + 56320); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static uint GetCodePoint(char highSurrogate, char lowSurrogate) { return ((uint)highSurrogate << 10) + lowSurrogate - 56613888; } } internal readonly struct CodePointRange : IComparable { public sealed class Cache { internal static readonly KeyValuePair LetterCategory = new KeyValuePair(30, 31); internal static readonly KeyValuePair CasedLetterCategory = new KeyValuePair(31, 7); internal static readonly KeyValuePair MarkCategory = new KeyValuePair(32, 224); internal static readonly KeyValuePair NumberCategory = new KeyValuePair(33, 1792); internal static readonly KeyValuePair PunctuationCategory = new KeyValuePair(34, 33292288); internal static readonly KeyValuePair SymbolCategory = new KeyValuePair(35, 503316480); internal static readonly KeyValuePair SeparatorCategory = new KeyValuePair(36, 14336); internal static readonly KeyValuePair OtherCategory = new KeyValuePair(37, 537116672); private readonly CodePointRange[][] _generalCategories = new CodePointRange[OtherCategory.Key + 1][]; internal CodePointRange[] GetGeneralCategory(UnicodeCategory category) { return GetGeneralCategory(new KeyValuePair((int)category, 1 << (int)category)); } internal CodePointRange[] GetGeneralCategory(KeyValuePair category) { ref CodePointRange[] reference = ref _generalCategories[category.Key]; if (reference == null) { ArrayList ranges = default(ArrayList); AddRanges(ref ranges, (int cp) => (category.Value & (1 << (int)Shims.GetUnicodeCategory(cp))) != 0); ranges.Yield(out reference, out int count); Array.Resize(ref reference, count); } return reference; } } public readonly int Start; public readonly int End; public int Length => End - Start + 1; public CodePointRange(int codePoint) : this(codePoint, codePoint) { } public CodePointRange(int start, int end) { Start = start; End = end; } public bool Contains(int codePoint) { if (Start <= codePoint) { return codePoint <= End; } return false; } public int CompareTo(CodePointRange other) { return Start - other.Start; } public static void NormalizeRanges(ref ArrayList ranges) { if (ranges.Count <= 1) { return; } ranges.Sort(); ArrayList arrayList = new ArrayList(ranges.Count); CodePointRange item = ranges[0]; for (int i = 1; i < ranges.Count; i++) { if (ranges[i].End > item.End) { if (item.End >= ranges[i].Start - 1) { item = new CodePointRange(item.Start, ranges[i].End); continue; } arrayList.Add(item); item = ranges[i]; } } arrayList.Add(item); ranges = arrayList; } public static ArrayList InvertRanges(ReadOnlySpan ranges, int start = 0, int end = 1114111) { if (ranges.Length == 0) { return new ArrayList(new CodePointRange[1] { new CodePointRange(start, end) }); } ArrayList result = default(ArrayList); if (ranges[0].Start > start) { result.Add(new CodePointRange(start, ranges[0].Start - 1)); } for (int i = 1; i < ranges.Length; i++) { result.Add(new CodePointRange(ranges[i - 1].End + 1, ranges[i].Start - 1)); } if (ranges.Last().End < end) { result.Add(new CodePointRange(ranges.Last().End + 1, end)); } return result; } internal static bool RangesContain(int codePoint, int[] ranges, int[] rangeLengthLookup) { int value = codePoint << 8; int num = Array.BinarySearch(ranges, value); if (num >= 0 || ((num = ~num) < ranges.Length && DecodeRange(ranges[num], rangeLengthLookup).Contains(codePoint)) || (num > 0 && DecodeRange(ranges[--num], rangeLengthLookup).Contains(codePoint))) { return true; } return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static CodePointRange DecodeRange(int data, int[] rangeLengths) { int num = data >> 8; return new CodePointRange(num, num + rangeLengths[data & 0xFF]); } internal static void AddRanges(ref ArrayList ranges, Predicate includesCodePoint, int start = 0, int end = 1114111) { for (; start <= end; start++) { int num = start; if (!includesCodePoint(num)) { continue; } if (ranges.Count > 0) { ref CodePointRange reference = ref ranges.AsSpan().Last(); if (reference.End == num - 1) { reference = new CodePointRange(reference.Start, num); continue; } } ranges.Add(new CodePointRange(num)); } } } public sealed class CollectingErrorHandler : ErrorHandler { private readonly List _errors = new List(); public IReadOnlyCollection Errors => _errors; protected internal override void Reset() { _errors.Clear(); if (_errors.Capacity > 16) { _errors.Capacity = 16; } } protected override void RecordError(ParseError error) { _errors.Add(error); } } public enum CommentType { Block, Line } [StructLayout(LayoutKind.Auto)] public readonly record struct Comment { public readonly CommentType Type; public readonly Range Slice; public readonly int Start; public readonly int End; public readonly Position StartPosition; public readonly Position EndPosition; internal Comment(CommentType type, Range slice, int start, int end, Position startPosition, Position endPosition) { Type = type; Slice = slice; Start = start; End = end; StartPosition = startPosition; EndPosition = endPosition; } } public class ErrorHandler { public static readonly ErrorHandler Default = new ErrorHandler(); protected internal virtual void Reset() { } protected virtual void RecordError(ParseError error) { } internal void Tolerate(ParseError error, bool tolerant) { if (tolerant) { RecordError(error); return; } throw error.ToException(); } protected internal virtual ParseError CreateError(string? source, int index, int line, int col, string description) { return new ParseError(description, source, index, new Position(line, col)); } internal ParseError TolerateError(string? source, int index, int line, int col, string description, bool tolerant) { ParseError parseError = CreateError(source, index, line, col, description); Tolerate(parseError, tolerant); return parseError; } } internal static class EsprimaExceptionHelper { [DoesNotReturn] public static T ThrowArgumentNullException(string paramName) { throw new ArgumentNullException(paramName); } [DoesNotReturn] public static void ThrowArgumentOutOfRangeException(string paramName, T actualValue, string? message = null) { throw new ArgumentOutOfRangeException(paramName, actualValue, message); } [DoesNotReturn] public static void ThrowArgumentException(string message, string paramName) { throw new ArgumentException(message, paramName); } [DoesNotReturn] public static T ThrowIndexOutOfRangeException() { throw new ArgumentOutOfRangeException("index"); } [DoesNotReturn] public static T ThrowFormatException(string message) { throw new FormatException(message); } [DoesNotReturn] public static T ThrowInvalidOperationException(string? message = null) { throw new InvalidOperationException(message); } } public class JavaScriptParser { internal sealed class Context { public bool IsModule; public bool AllowIn; public bool AllowStrictDirective; public bool AllowSuperCall; public bool AllowSuperAccess; public bool AllowYield; public bool IsAsync; public bool IsAssignmentTarget; public bool IsBindingElement; public bool InClassFieldInit; public bool InClassStaticBlock; public bool InFunctionBody; public bool InIteration; public bool InSwitch; public bool InClassBody; public bool Strict; public bool AllowIdentifierEscape; public MemberAccessContext MemberAccessContext; public ArrayList Decorators; public HashSet LabelSet; public StrongBox? FirstCoverInitializedNameError; public Context() { LabelSet = new HashSet(); Reset(); } public void Reset() { IsModule = false; AllowIn = true; AllowStrictDirective = true; AllowSuperCall = false; AllowSuperAccess = false; AllowYield = true; IsAsync = false; FirstCoverInitializedNameError = null; IsAssignmentTarget = false; IsBindingElement = false; InClassFieldInit = false; InClassStaticBlock = false; InFunctionBody = false; InIteration = false; InSwitch = false; Strict = false; AllowIdentifierEscape = false; MemberAccessContext = MemberAccessContext.Unknown; Decorators.Clear(); LabelSet.Clear(); } public void ReleaseLargeBuffers() { Decorators.Clear(); if (Decorators.Capacity > 64) { Decorators.Capacity = 64; } if (LabelSet.Count > 64) { LabelSet = new HashSet(); } } } internal enum MemberAccessContext : byte { Unknown, NewExpressionCallee, Decorator } private struct ParsedParameters { private HashSet? paramSet; public Token? FirstRestricted; public string? Message; public ArrayList Parameters; public Token? Stricted; public bool Simple; public bool HasDuplicateParameterNames; public ParsedParameters() { Parameters = default(ArrayList); paramSet = null; FirstRestricted = null; Message = null; Stricted = null; Simple = false; HasDuplicateParameterNames = false; } public readonly bool ParamSetContains(string? key) { if (paramSet != null) { return paramSet.Contains(key); } return false; } public void ParamSetAdd(string? key) { (paramSet ?? (paramSet = new HashSet())).Add(key); } } private readonly Func _parseAssignmentExpression; private readonly Func _parseBinaryExpressionOperand; private readonly Func _parseUnaryExpression; private readonly Func _parseExpression; private readonly Func _parseNewExpression; private readonly Func _parsePrimaryExpression; private readonly Func _parseGroupExpression; private readonly Func _parseArrayInitializer; private readonly Func _parseObjectInitializer; private readonly Func _parseBinaryExpression; private readonly Func _parseLeftHandSideExpression; private readonly Func _parseLeftHandSideExpressionAllowCall; private readonly Func _parseStatement; private readonly Func _parseFunctionSourceElements; private readonly Func _parseAsyncArgument; private protected Token _lookahead; private protected readonly Context _context; private protected Marker _startMarker; private protected Marker _lastMarker; private protected readonly ErrorHandler _errorHandler; private protected readonly bool _tolerant; private protected readonly bool _allowReturnOutsideFunction; private protected readonly int _maxAssignmentDepth; private readonly Action? _onNodeCreated; private protected readonly Scanner _scanner; private protected bool _hasLineTerminator; private protected List? _tokens; private protected List? _comments; private Stack? _markersStack; private Stack? _precedencesStack; private ArrayList? _sharedStack; private int _assignmentDepth; private ArrayList? _parseVariableBindingParameters; [StringMatcher(new string[] { "=", "*=", "**=", "/=", "%=", "+=", "-=", "<<=", ">>=", ">>>=", "&=", "^=", "|=", "&&=", "||=", "??=" })] private static bool IsAssignmentOperator(string id) { return id.Length switch { 1 => id == "=", 2 => id[0] switch { '-' => id == "-=", '*' => id == "*=", '/' => id == "/=", '&' => id == "&=", '%' => id == "%=", '^' => id == "^=", '+' => id == "+=", '|' => id == "|=", _ => false, }, 3 => id[0] switch { '?' => id == "??=", '*' => id == "**=", '&' => id == "&&=", '<' => id == "<<=", '>' => id == ">>=", '|' => id == "||=", _ => false, }, 4 => id == ">>>=", _ => false, }; } public JavaScriptParser() : this(ParserOptions.Default) { } public JavaScriptParser(ParserOptions options) { if (options == null) { throw new ArgumentNullException("options"); } _errorHandler = options.ErrorHandler; _tolerant = options.Tolerant; _allowReturnOutsideFunction = options.AllowReturnOutsideFunction; _tokens = (options.Tokens ? new List() : null); _comments = (options.Comments ? new List() : null); _maxAssignmentDepth = options.MaxAssignmentDepth; _onNodeCreated = options.OnNodeCreated; _scanner = new Scanner(options.GetScannerOptions()); _context = new Context(); _parseAssignmentExpression = ParseAssignmentExpression; _parseBinaryExpressionOperand = ParseBinaryExpressionOperand; _parseUnaryExpression = ParseUnaryExpression; _parseExpression = ParseExpression; _parseNewExpression = ParseNewExpression; _parsePrimaryExpression = ParsePrimaryExpression; _parseGroupExpression = ParseGroupExpression; _parseArrayInitializer = ParseArrayInitializer; _parseObjectInitializer = ParseObjectInitializer; _parseBinaryExpression = ParseBinaryExpression; _parseLeftHandSideExpression = ParseLeftHandSideExpression; _parseLeftHandSideExpressionAllowCall = ParseLeftHandSideExpressionAllowCall; _parseStatement = ParseStatement; _parseFunctionSourceElements = ParseFunctionSourceElements; _parseAsyncArgument = ParseAsyncArgument; } private void Reset(string code, string? source) { _assignmentDepth = 0; _hasLineTerminator = false; _lookahead = default(Token); _markersStack = null; _precedencesStack = null; _sharedStack = null; _parseVariableBindingParameters = null; _tokens?.Clear(); _comments?.Clear(); _scanner.Reset(code, source); _context.Reset(); _startMarker = new Marker(0, _scanner._lineNumber, 0); NextToken(); _lastMarker = _scanner.GetMarker(); } private void ReleaseLargeBuffers() { _scanner.ReleaseLargeBuffers(); _context.ReleaseLargeBuffers(); } public Esprima.Ast.Module ParseModule(string code, string? source = null) { Reset(code, source); try { _context.Strict = true; _context.IsAsync = true; _context.IsModule = true; _scanner._isModule = true; Marker marker = CreateNode(); ArrayList arrayList = ParseDirectivePrologues(); while (_lookahead.Type != TokenType.EOF) { arrayList.Push(ParseStatementListItem()); } return FinalizeRoot(Finalize(in marker, new Esprima.Ast.Module(NodeList.From(ref arrayList)))); } finally { ReleaseLargeBuffers(); } } public Script ParseScript(string code, string? source = null, bool strict = false) { Reset(code, source); try { _context.Strict = strict; Marker marker = CreateNode(); ArrayList arrayList = ParseDirectivePrologues(); while (_lookahead.Type != TokenType.EOF) { arrayList.Push(ParseStatementListItem()); } return FinalizeRoot(Finalize(in marker, new Script(NodeList.From(ref arrayList), _context.Strict))); } finally { ReleaseLargeBuffers(); } } private protected void CollectComments() { if (_comments == null) { _scanner.ScanCommentsInternal(); return; } ReadOnlySpan readOnlySpan = _scanner.ScanCommentsInternal().AsReadOnlySpan(); for (int i = 0; i < readOnlySpan.Length; i++) { Comment comment = readOnlySpan[i]; string value = _scanner._source.AsSpan(comment.Slice.Start, comment.Slice.Length).ToInternedString(ref _scanner._stringPool, 20); SyntaxComment item = new SyntaxComment(comment.Type, value) { Range = new Range(comment.Start, comment.End), Location = new Location(comment.StartPosition, comment.EndPosition, _scanner._sourceLocation) }; _comments.Add(item); } } private protected string GetTokenRaw(in Token token) { switch (token.Type) { case TokenType.Punctuator: return (string)token.Value; case TokenType.BooleanLiteral: case TokenType.Identifier: case TokenType.Keyword: case TokenType.NullLiteral: { string text = (string)token.Value; if (!token.IsEscaped(text)) { return text; } break; } case TokenType.StringLiteral: case TokenType.RegularExpression: case TokenType.Template: return _scanner._source.Between(token.Start, token.End).ToInternedString(ref _scanner._stringPool, 20); } return _scanner._source.Between(token.Start, token.End).ToInternedString(ref _scanner._stringPool); } private protected SyntaxToken FinalizeToken(int start, int end, SyntaxToken token) { Position start2 = new Position(_startMarker.Line, _startMarker.Column); Position end2 = new Position(_scanner._lineNumber, _scanner._index - _scanner._lineStart); token.Range = new Range(start, end); token.Location = new Location(start2, end2); return token; } private protected SyntaxToken ConvertToken(in Token token) { return FinalizeToken(token.Start, token.End, new SyntaxToken(token.Type, GetTokenRaw(in token), token.RegexValue)); } private protected Token NextToken(bool allowIdentifierEscape = false) { Token lookahead = _lookahead; _lastMarker = _scanner.GetMarker(); CollectComments(); if (_scanner._index != _startMarker.Index) { _startMarker = _scanner.GetMarker(); } Token token = _scanner.Lex(new LexOptions(_context.Strict, allowIdentifierEscape)); _hasLineTerminator = lookahead.Type != TokenType.Unknown && token.Type != TokenType.Unknown && lookahead.LineNumber != token.LineNumber; if (_context.Strict && token.Type == TokenType.Identifier && Scanner.IsStrictModeReservedWord((string)token.Value)) { token = token.ChangeType(TokenType.Keyword); } _lookahead = token; if (_tokens != null && token.Type != TokenType.Unknown && token.Type != TokenType.EOF) { _tokens.Add(ConvertToken(in token)); } return lookahead; } private Token NextRegExpToken() { CollectComments(); Token token = _scanner.ScanRegExp(); if (_tokens != null) { _tokens.RemoveAt(_tokens.Count - 1); _tokens.Add(ConvertToken(in token)); } _lookahead = token; NextToken(); return token; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private Marker CreateNode() { return new Marker(_startMarker.Index, _startMarker.Line, _startMarker.Column); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Marker StartNode(in Token token, int lastLineStart = 0) { int num = token.Start - token.LineStart; int num2 = token.LineNumber; if (num < 0) { num += lastLineStart; num2--; } return new Marker(token.Start, num2, num); } private protected T Finalize(in Marker marker, T node) where T : Node { node.Range = new Range(marker.Index, _lastMarker.Index); Position start = new Position(marker.Line, marker.Column); Position end = new Position(_lastMarker.Line, _lastMarker.Column); node.Location = new Location(start, end, _scanner._sourceLocation); _onNodeCreated?.Invoke(node); return node; } private T FinalizeRoot(T node) where T : Node, ISyntaxTreeRoot { if (_tokens != null) { _tokens.TrimExcess(); node.Tokens = _tokens; _tokens = new List(); } if (_comments != null) { _comments.TrimExcess(); node.Comments = _comments; _comments = new List(); } return node; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void Expect(string value) { Token token = NextToken(allowIdentifierEscape: true); if (token.Type != TokenType.Punctuator || !value.Equals((string)token.Value, StringComparison.Ordinal)) { ThrowUnexpectedToken(in token); } } private void ExpectCommaSeparator() { if (_tolerant) { Token token = _lookahead; if (token.Type == TokenType.Punctuator && ",".Equals(token.Value)) { NextToken(); } else if (token.Type == TokenType.Punctuator && ";".Equals(token.Value)) { NextToken(); TolerateUnexpectedToken(in token); } else { TolerateUnexpectedToken(in token, "Unexpected token {0}"); } } else { Expect(","); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void ExpectKeyword(string keyword) { Token token = NextToken(); if (token.Type != TokenType.Keyword || !keyword.Equals((string)token.Value, StringComparison.Ordinal)) { ThrowUnexpectedToken(in token); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private protected bool Match(string value) { ref Token lookahead = ref _lookahead; if (lookahead.Type == TokenType.Punctuator) { return value.Equals((string)lookahead.Value, StringComparison.Ordinal); } return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private protected bool ConsumeMatch(string value) { if (Match(value)) { NextToken(); return true; } return false; } private bool MatchAny(char value1, char value2, char value3, char value4) { ref Token lookahead = ref _lookahead; if (lookahead.Type != TokenType.Punctuator || lookahead.End - lookahead.Start != 1) { return false; } char c = ((string)lookahead.Value)[0]; if (c != value1 && c != value2 && c != value3) { return c == value4; } return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private bool MatchKeyword(string keyword) { ref Token lookahead = ref _lookahead; if (lookahead.Type == TokenType.Keyword) { return keyword.Equals((string)lookahead.Value, StringComparison.Ordinal); } return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private bool MatchContextualKeyword(string keyword) { ref Token lookahead = ref _lookahead; if (lookahead.Type == TokenType.Identifier) { return keyword.Equals((string)lookahead.Value, StringComparison.Ordinal); } return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private bool MatchAssign() { ref Token lookahead = ref _lookahead; if (lookahead.Type == TokenType.Punctuator) { return IsAssignmentOperator((string)lookahead.Value); } return false; } private T IsolateCoverGrammar(Func parseFunction) where T : Node { bool isBindingElement = _context.IsBindingElement; bool isAssignmentTarget = _context.IsAssignmentTarget; StrongBox firstCoverInitializedNameError = _context.FirstCoverInitializedNameError; _context.IsBindingElement = true; _context.IsAssignmentTarget = true; _context.FirstCoverInitializedNameError = null; T result = parseFunction(); if (_context.FirstCoverInitializedNameError != null) { ThrowUnexpectedToken(in _context.FirstCoverInitializedNameError.Value); } _context.IsBindingElement = isBindingElement; _context.IsAssignmentTarget = isAssignmentTarget; _context.FirstCoverInitializedNameError = firstCoverInitializedNameError; return result; } [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] private T InheritCoverGrammar(Func parseFunction) where T : Node { bool isBindingElement = _context.IsBindingElement; bool isAssignmentTarget = _context.IsAssignmentTarget; StrongBox firstCoverInitializedNameError = _context.FirstCoverInitializedNameError; _context.IsBindingElement = true; _context.IsAssignmentTarget = true; _context.FirstCoverInitializedNameError = null; T result = parseFunction(); _context.IsBindingElement = _context.IsBindingElement && isBindingElement; _context.IsAssignmentTarget = _context.IsAssignmentTarget && isAssignmentTarget; _context.FirstCoverInitializedNameError = firstCoverInitializedNameError ?? _context.FirstCoverInitializedNameError; return result; } private void ConsumeSemicolon() { if (Match(";")) { NextToken(!_context.Strict); } else if (!_hasLineTerminator) { if (_lookahead.Type != TokenType.EOF && !Match("}")) { ThrowUnexpectedToken(in _lookahead); } _lastMarker = _startMarker; } } [MethodImpl(MethodImplOptions.AggressiveOptimization)] private protected virtual Expression ParsePrimaryExpression() { Marker marker = CreateNode(); Expression expression; Token token; string tokenRaw; switch (_lookahead.Type) { case TokenType.Identifier: if (_context.IsAsync && "await".Equals(_lookahead.Value)) { TolerateUnexpectedToken(in _lookahead); } if ((_context.InClassFieldInit || _context.InClassStaticBlock) && "arguments".Equals(_lookahead._value)) { TolerateError("'arguments' is not allowed in class field initializer or static initialization block"); } expression = ((!MatchAsyncFunction()) ? ((Expression)Finalize(in marker, new Identifier((string)NextToken().Value))) : ((Expression)ParseFunctionExpression())); break; case TokenType.StringLiteral: _context.IsAssignmentTarget = false; _context.IsBindingElement = false; token = NextToken(); tokenRaw = GetTokenRaw(in token); expression = Finalize(in marker, new Literal(TokenType.StringLiteral, token.Value, tokenRaw)); break; case TokenType.NumericLiteral: _context.IsAssignmentTarget = false; _context.IsBindingElement = false; token = NextToken(); tokenRaw = GetTokenRaw(in token); expression = Finalize(in marker, new Literal(TokenType.NumericLiteral, token.Value, tokenRaw)); break; case TokenType.BigIntLiteral: _context.IsAssignmentTarget = false; _context.IsBindingElement = false; token = NextToken(); tokenRaw = GetTokenRaw(in token); expression = Finalize(in marker, new Literal(TokenType.BigIntLiteral, token.Value, tokenRaw)); break; case TokenType.BooleanLiteral: _context.IsAssignmentTarget = false; _context.IsBindingElement = false; token = NextToken(); tokenRaw = GetTokenRaw(in token); expression = Finalize(in marker, new Literal("true".Equals(token.Value), tokenRaw)); break; case TokenType.NullLiteral: _context.IsAssignmentTarget = false; _context.IsBindingElement = false; tokenRaw = GetTokenRaw(NextToken()); expression = Finalize(in marker, new Literal(tokenRaw)); break; case TokenType.Template: expression = ParseTemplateLiteral(isTagged: false); break; case TokenType.Punctuator: { string text = (string)_lookahead.Value; if (text != null) { int length = text.Length; if (length != 1) { if (length == 2 && text == "/=") { goto IL_032d; } } else { char c = text[0]; if ((uint)c <= 47u) { if (c == '#') { expression = ParsePrivateIdentifier(in marker); if (!_context.InClassBody) { ThrowError("Private field '{0}' must be declared in an enclosing class", "#" + expression.As().Name); } break; } if (c == '(') { _context.IsBindingElement = false; expression = InheritCoverGrammar(_parseGroupExpression); break; } if (c == '/') { goto IL_032d; } } else { if (c == '@') { expression = ParseDecoratedPrimaryExpression(in marker); break; } if (c == '[') { expression = InheritCoverGrammar(_parseArrayInitializer); break; } if (c == '{') { expression = InheritCoverGrammar(_parseObjectInitializer); break; } } } } return ThrowUnexpectedToken(NextToken()); } case TokenType.Keyword: if (!_context.Strict && _context.AllowYield && MatchKeyword("yield")) { expression = ParseIdentifierName(); break; } if (!_context.Strict && MatchKeyword("let")) { expression = Finalize(in marker, new Identifier((string)NextToken().Value)); break; } _context.IsAssignmentTarget = false; _context.IsBindingElement = false; if (MatchKeyword("function")) { expression = ParseFunctionExpression(); break; } if (MatchKeyword("this")) { NextToken(); expression = Finalize(in marker, new ThisExpression()); break; } if (MatchKeyword("class")) { expression = ParseClassExpression(); break; } if (MatchKeyword("new")) { expression = ParseNewExpression(); break; } if (MatchImportCall()) { expression = ParseImportCall(); break; } if (MatchImportMeta()) { if (!_context.IsModule) { ThrowUnexpectedToken(in _lookahead, "Cannot use 'import.meta' outside a module"); } expression = ParseImportMeta(); break; } return ThrowUnexpectedToken(NextToken()); default: { return ThrowUnexpectedToken(NextToken()); } IL_032d: _context.IsAssignmentTarget = false; _context.IsBindingElement = false; _scanner._index = _startMarker.Index; token = NextRegExpToken(); tokenRaw = GetTokenRaw(in token); expression = Finalize(in marker, new RegExpLiteral(token.RegexValue, token.RegExpParseResult, tokenRaw)); break; } return expression; } private Expression ParseDecoratedPrimaryExpression(in Marker node) { ArrayList decorators = _context.Decorators; _context.Decorators = ParseDecorators(); Expression node2 = ParsePrimaryExpression(); _context.Decorators = decorators; return Finalize(in node, node2); } private void ThrowTemplateLiteralEarlyErrors(in Token token) { switch (token.NotEscapeSequenceHead) { case 'u': ThrowUnexpectedToken(in token, "Invalid Unicode escape sequence"); break; case 'v': ThrowUnexpectedToken(in token, "Undefined Unicode code-point"); break; case 'x': ThrowUnexpectedToken(in token, "Invalid hexadecimal escape sequence"); break; case '8': case '9': ThrowUnexpectedToken(in token, "\\8 and \\9 are not allowed in template strings."); break; default: ThrowUnexpectedToken(in token, "Octal literals are not allowed in template strings."); break; } } private SpreadElement ParseSpreadElement() { Marker marker = CreateNode(); Expect("..."); Expression argument = InheritCoverGrammar(_parseAssignmentExpression); return Finalize(in marker, new SpreadElement(argument)); } private ArrayExpression ParseArrayInitializer() { Marker marker = CreateNode(); ArrayList arrayList = default(ArrayList); Expect("["); while (!Match("]")) { if (Match(",")) { NextToken(); arrayList.Add(null); } else if (Match("...")) { SpreadElement item = ParseSpreadElement(); if (!Match("]")) { _context.IsAssignmentTarget = false; _context.IsBindingElement = false; Expect(","); } arrayList.Add(item); } else { arrayList.Add(InheritCoverGrammar(_parseAssignmentExpression)); if (!Match("]")) { Expect(","); } } } Expect("]"); return Finalize(in marker, new ArrayExpression(NodeList.From(ref arrayList))); } private BlockStatement ParsePropertyMethod(ref ParsedParameters parameters, out bool hasStrictDirective) { _context.IsAssignmentTarget = false; _context.IsBindingElement = false; bool inClassStaticBlock = _context.InClassStaticBlock; bool strict = _context.Strict; bool allowStrictDirective = _context.AllowStrictDirective; _context.InClassStaticBlock = false; _context.AllowStrictDirective = parameters.Simple; BlockStatement result = IsolateCoverGrammar(_parseFunctionSourceElements); hasStrictDirective = _context.Strict; if (_context.Strict && parameters.FirstRestricted.HasValue) { TolerateUnexpectedToken(parameters.FirstRestricted.Value, parameters.Message); } if (_context.Strict && parameters.Stricted.HasValue) { TolerateUnexpectedToken(parameters.Stricted.Value, parameters.Message); } _context.Strict = strict; _context.AllowStrictDirective = allowStrictDirective; _context.InClassStaticBlock = inClassStaticBlock; return result; } private FunctionExpression ParsePropertyMethodFunction(bool isAsync, bool isGenerator, bool allowSuperCall) { Marker marker = CreateNode(); bool inClassStaticBlock = _context.InClassStaticBlock; bool isAsync2 = _context.IsAsync; bool allowYield = _context.AllowYield; bool allowSuperAccess = _context.AllowSuperAccess; bool allowSuperCall2 = _context.AllowSuperCall; _context.InClassStaticBlock = false; _context.IsAsync = isAsync; _context.AllowYield = true; _context.AllowSuperAccess = true; _context.AllowSuperCall = allowSuperCall; ParsedParameters parameters = ParseFormalParameters(); _context.AllowYield = !isGenerator; bool hasStrictDirective; BlockStatement body = ParsePropertyMethod(ref parameters, out hasStrictDirective); _context.IsAsync = isAsync2; _context.AllowYield = allowYield; _context.AllowSuperAccess = allowSuperAccess; _context.AllowSuperCall = allowSuperCall2; _context.InClassStaticBlock = inClassStaticBlock; return Finalize(in marker, new FunctionExpression(null, NodeList.From(ref parameters.Parameters), body, isGenerator, hasStrictDirective, isAsync)); } private Expression ParseObjectPropertyKey() { Marker marker = CreateNode(); Token token = NextToken(); Expression result; switch (token.Type) { case TokenType.StringLiteral: { string tokenRaw = GetTokenRaw(in token); result = Finalize(in marker, new Literal((string)token.Value, tokenRaw)); break; } case TokenType.NumericLiteral: { string tokenRaw = GetTokenRaw(in token); result = Finalize(in marker, new Literal(TokenType.NumericLiteral, token.Value, tokenRaw)); break; } case TokenType.BigIntLiteral: { string tokenRaw = GetTokenRaw(in token); result = Finalize(in marker, new Literal(TokenType.BigIntLiteral, token.Value, tokenRaw)); break; } case TokenType.BooleanLiteral: case TokenType.Identifier: case TokenType.Keyword: case TokenType.NullLiteral: result = Finalize(in marker, new Identifier((string)token.Value)); break; case TokenType.Punctuator: if ("[".Equals(token.Value)) { result = IsolateCoverGrammar(_parseAssignmentExpression); Expect("]"); break; } goto default; default: return ThrowUnexpectedToken(in token); } return result; } private PrivateIdentifier ParsePrivateIdentifier() { return ParsePrivateIdentifier(CreateNode()); } private PrivateIdentifier ParsePrivateIdentifier(in Marker node) { int end = _lookahead.End; NextToken(); if (end != _lookahead.Start) { ThrowUnexpectedToken(in _lookahead); } Token token = NextToken(); TokenType type = token.Type; if (type == TokenType.BooleanLiteral || type - 3 <= TokenType.EOF) { return Finalize(in node, new PrivateIdentifier((string)token.Value)); } return ThrowUnexpectedToken(in token); } private static bool IsPropertyKey(Node key, string value) { if (key.Type == Nodes.Identifier) { return value.Equals(key.As().Name, StringComparison.Ordinal); } if (key.Type == Nodes.Literal) { return value.Equals(key.As().StringValue, StringComparison.Ordinal); } return false; } private Property ParseObjectProperty(ref int protoCount) { Marker marker = CreateNode(); Token token = _lookahead; Expression expression = null; bool flag = false; bool method = false; bool shorthand = false; bool flag2 = false; bool flag3 = false; if (token.Type == TokenType.Identifier) { string text = (string)token.Value; NextToken(); flag = Match("["); flag2 = !_hasLineTerminator && text == "async" && !Match(":") && !Match("(") && !Match(","); flag3 = Match("*"); if (flag3) { NextToken(); } expression = (flag2 ? ParseObjectPropertyKey() : Finalize(in marker, new Identifier(text))); } else if (Match("*")) { NextToken(); } else { flag = Match("["); expression = ParseObjectPropertyKey(); } bool flag4 = QualifiedPropertyName(in _lookahead); PropertyKind kind; Node value; if (token.Type == TokenType.Identifier && !flag2 && "get".Equals(token.Value) && flag4) { if (!"get".Equals(GetTokenRaw(in token), StringComparison.Ordinal)) { TolerateError("The `{0}` contextual keyword must not contain Unicode escape sequences.", "get"); } kind = PropertyKind.Get; flag = Match("["); expression = ParseObjectPropertyKey(); value = ParseGetterMethod(); } else if (token.Type == TokenType.Identifier && !flag2 && "set".Equals(token.Value) && flag4) { if (!"set".Equals(GetTokenRaw(in token), StringComparison.Ordinal)) { TolerateError("The `{0}` contextual keyword must not contain Unicode escape sequences.", "set"); } kind = PropertyKind.Set; flag = Match("["); expression = ParseObjectPropertyKey(); value = ParseSetterMethod(); } else if (token.Type == TokenType.Punctuator && "*".Equals(token.Value) && flag4) { kind = PropertyKind.Init; flag = Match("["); expression = ParseObjectPropertyKey(); value = ParseGeneratorMethod(flag2); method = true; } else { if (expression == null) { return ThrowUnexpectedToken(in _lookahead); } kind = PropertyKind.Init; if (Match(":") && !flag2) { if (!flag && IsPropertyKey(expression, "__proto__")) { protoCount++; } NextToken(); value = InheritCoverGrammar(_parseAssignmentExpression); } else if (Match("(")) { value = ParsePropertyMethodFunction(flag2, flag3, allowSuperCall: false); method = true; } else { if (token.Type != TokenType.Identifier) { return ThrowUnexpectedToken(NextToken()); } Identifier identifier = (Identifier)expression; if (Match("=")) { _context.FirstCoverInitializedNameError = new StrongBox(_lookahead); NextToken(); shorthand = true; Expression right = IsolateCoverGrammar(_parseAssignmentExpression); value = Finalize(in marker, new AssignmentPattern(identifier, right)); } else { shorthand = true; value = identifier; } } } return Finalize(in marker, new Property(kind, expression, flag, value, method, shorthand)); } private ObjectExpression ParseObjectInitializer() { Marker marker = CreateNode(); ArrayList arrayList = default(ArrayList); int protoCount = 0; Expect("{"); while (!Match("}")) { Node node = (Match("...") ? ((Node)ParseSpreadElement()) : ((Node)ParseObjectProperty(ref protoCount))); arrayList.Add(node); if (!Match("}") && (!(node is Property { Method: not false }) || Match(","))) { ExpectCommaSeparator(); } } Expect("}"); if (protoCount > 1 && !MatchAssign()) { ThrowError("Duplicate __proto__ fields are not allowed in object literals"); } return Finalize(in marker, new ObjectExpression(NodeList.From(ref arrayList))); } private TemplateElement ParseTemplateHead(bool isTagged) { Marker marker = CreateNode(); Token token = NextToken(); if (!isTagged && token.NotEscapeSequenceHead != 0) { ThrowTemplateLiteralEarlyErrors(in token); } string rawTemplate = token.RawTemplate; TemplateElement.TemplateElementValue value = new TemplateElement.TemplateElementValue((string)token.Value, rawTemplate); return Finalize(in marker, new TemplateElement(value, token.Tail)); } private TemplateElement ParseTemplateElement(bool isTagged) { if (_lookahead.Type != TokenType.Template) { ThrowUnexpectedToken(default(Token)); } Marker marker = CreateNode(); Token token = NextToken(); if (!isTagged && token.NotEscapeSequenceHead != 0) { ThrowTemplateLiteralEarlyErrors(in token); } string rawTemplate = token.RawTemplate; TemplateElement.TemplateElementValue value = new TemplateElement.TemplateElementValue((string)token.Value, rawTemplate); return Finalize(in marker, new TemplateElement(value, token.Tail)); } private TemplateLiteral ParseTemplateLiteral(bool isTagged) { Marker marker = CreateNode(); ArrayList arrayList = default(ArrayList); ArrayList arrayList2 = default(ArrayList); TemplateElement templateElement = ParseTemplateHead(isTagged); arrayList2.Add(templateElement); while (!templateElement.Tail) { arrayList.Add(ParseExpression()); templateElement = ParseTemplateElement(isTagged); arrayList2.Add(templateElement); } return Finalize(in marker, new TemplateLiteral(NodeList.From(ref arrayList2), NodeList.From(ref arrayList))); } private static Node ReinterpretExpressionAsPattern(Node expr) { Node node = expr; switch (expr.Type) { case Nodes.SpreadElement: node = new RestElement(ReinterpretExpressionAsPattern(expr.As().Argument)); node.Range = expr.Range; node.Location = expr.Location; break; case Nodes.ArrayExpression: { ArrayList arrayList2 = default(ArrayList); foreach (Expression element in expr.As().Elements) { if (element != null) { arrayList2.Add(ReinterpretExpressionAsPattern(element)); } else { arrayList2.Add(null); } } node = new ArrayPattern(NodeList.From(ref arrayList2)); node.Range = expr.Range; node.Location = expr.Location; break; } case Nodes.ObjectExpression: { ArrayList arrayList = default(ArrayList); foreach (Node property2 in expr.As().Properties) { if (property2 is Property property) { property._value = ReinterpretExpressionAsPattern(property.Value); arrayList.Add(property); } else { arrayList.Add(ReinterpretExpressionAsPattern(property2)); } } node = new ObjectPattern(NodeList.From(ref arrayList)); node.Range = expr.Range; node.Location = expr.Location; break; } case Nodes.AssignmentExpression: { AssignmentExpression assignmentExpression = expr.As(); node = new AssignmentPattern(assignmentExpression.Left, assignmentExpression.Right); node.Range = expr.Range; node.Location = expr.Location; break; } } return node; } private Expression ParseGroupExpression() { Expect("("); Expression expression; if (Match(")")) { NextToken(); if (!Match("=>")) { Expect("=>"); } expression = ArrowParameterPlaceHolder.Empty; } else { Token startToken = _lookahead; if (Match("...")) { ArrayList parameters = _parseVariableBindingParameters.GetValueOrDefault(); _parseVariableBindingParameters = null; parameters.Clear(); RestElement restElement = ParseRestElement(ref parameters); _parseVariableBindingParameters = parameters; Expect(")"); if (!Match("=>")) { Expect("=>"); } expression = new ArrowParameterPlaceHolder(new NodeList(new Node[1] { restElement }, 1), async: false); } else { bool arrow = false; _context.IsBindingElement = true; expression = InheritCoverGrammar(_parseAssignmentExpression); if (Match(",")) { expression = ParseSequenceExpression(expression, in startToken, ref arrow); } if (!arrow) { Expect(")"); if (Match("=>")) { if (expression.Type == Nodes.Identifier && ((Identifier)expression).Name == "yield") { Node[] items = new Expression[1] { expression }; expression = new ArrowParameterPlaceHolder(new NodeList(items, 1), async: false); } else { if (!_context.IsBindingElement) { ThrowUnexpectedToken(in _lookahead); } if (expression.Type == Nodes.SequenceExpression) { SequenceExpression sequenceExpression = expression.As(); ArrayList arrayList = default(ArrayList); foreach (Expression expression2 in sequenceExpression.Expressions) { arrayList.Add(ReinterpretExpressionAsPattern(expression2)); } expression = new ArrowParameterPlaceHolder(NodeList.From(ref arrayList), async: false); } else { expression = new ArrowParameterPlaceHolder(new NodeList(new Node[1] { ReinterpretExpressionAsPattern(expression) }, 1), async: false); } } } _context.IsBindingElement = false; } } } return expression; } private Expression ParseSequenceExpression(Expression expr, in Token startToken, ref bool arrow) { ArrayList arrayList = default(ArrayList); _context.IsAssignmentTarget = false; arrayList.Add(expr); while (_lookahead.Type != TokenType.EOF && Match(",")) { NextToken(); if (Match(")")) { NextToken(); ArrayList arrayList2 = new ArrayList(arrayList.Count); for (int i = 0; i < arrayList.Count; i++) { arrayList2.Add(ReinterpretExpressionAsPattern(arrayList[i])); } arrow = true; expr = new ArrowParameterPlaceHolder(NodeList.From(ref arrayList2), async: false); break; } if (Match("...")) { if (!_context.IsBindingElement) { ThrowUnexpectedToken(in _lookahead); } ArrayList parameters = _parseVariableBindingParameters.GetValueOrDefault(); _parseVariableBindingParameters = null; parameters.Clear(); RestElement item = ParseRestElement(ref parameters); _parseVariableBindingParameters = parameters; Expect(")"); if (!Match("=>")) { Expect("=>"); } _context.IsBindingElement = false; ArrayList arrayList3 = new ArrayList(arrayList.Count + 1); foreach (Expression item2 in arrayList) { arrayList3.Add(ReinterpretExpressionAsPattern(item2)); } arrayList3.Add(item); arrow = true; expr = new ArrowParameterPlaceHolder(NodeList.From(ref arrayList3), async: false); break; } arrayList.Add(InheritCoverGrammar(_parseAssignmentExpression)); } if (!arrow) { expr = Finalize(StartNode(in startToken), new SequenceExpression(NodeList.From(ref arrayList))); } return expr; } private NodeList ParseArguments() { ArrayList arrayList = default(ArrayList); Expect("("); if (!Match(")")) { do { Expression item = (Match("...") ? ParseSpreadElement() : IsolateCoverGrammar(_parseAssignmentExpression)); arrayList.Add(item); if (Match(")")) { break; } ExpectCommaSeparator(); } while (!Match(")")); } Expect(")"); return NodeList.From(ref arrayList); } private static bool IsIdentifierName(in Token token) { if (token.Type != TokenType.Identifier && token.Type != TokenType.Keyword && token.Type != TokenType.BooleanLiteral) { return token.Type == TokenType.NullLiteral; } return true; } private Identifier ParseIdentifierName() { Marker marker = CreateNode(); Token token = NextToken(); if (!IsIdentifierName(in token)) { return ThrowUnexpectedToken(in token); } return Finalize(in marker, new Identifier((string)token.Value)); } private Expression ParseIdentifierOrPrivateIdentifierName() { Marker marker = CreateNode(); if (Match("#")) { PrivateIdentifier privateIdentifier = ParsePrivateIdentifier(in marker); if (!_context.InClassBody) { TolerateError("Private field '{0}' must be declared in an enclosing class", "#" + privateIdentifier.Name); } return privateIdentifier; } Token token = NextToken(); if (!IsIdentifierName(in token)) { return ThrowUnexpectedToken(in token); } return Finalize(in marker, new Identifier((string)token.Value)); } private Expression ParseNewExpression() { Marker marker = CreateNode(); Identifier meta = ParseIdentifierName(); Expression node; if (Match(".")) { NextToken(); Token lookahead = _lookahead; if (lookahead.Type != TokenType.Identifier || !(lookahead.Value is string text) || !(text == "target")) { return ThrowUnexpectedToken(in _lookahead); } if (!_context.InFunctionBody && !_context.InClassBody) { TolerateError("new.target expression is not allowed here"); } Identifier property = ParseIdentifierName(); node = new MetaProperty(meta, property); } else { if (MatchImportCall()) { return ThrowUnexpectedToken(in _lookahead, "Cannot use new with import"); } MemberAccessContext memberAccessContext = _context.MemberAccessContext; _context.MemberAccessContext = MemberAccessContext.NewExpressionCallee; Expression callee = IsolateCoverGrammar(_parseLeftHandSideExpression); _context.MemberAccessContext = memberAccessContext; node = new NewExpression(callee, Match("(") ? ParseArguments() : default(NodeList)); _context.IsAssignmentTarget = false; _context.IsBindingElement = false; } return Finalize(in marker, node); } private Expression ParseAsyncArgument() { Expression result = ParseAssignmentExpression(); _context.FirstCoverInitializedNameError = null; return result; } private NodeList ParseAsyncArguments() { Expect("("); ArrayList arrayList = default(ArrayList); if (!Match(")")) { do { Expression item = (Match("...") ? ParseSpreadElement() : IsolateCoverGrammar(_parseAsyncArgument)); arrayList.Add(item); if (Match(")")) { break; } ExpectCommaSeparator(); } while (!Match(")")); } Expect(")"); return NodeList.From(ref arrayList); } private bool MatchImportCall() { bool flag = MatchKeyword("import"); if (flag) { ScannerState state = _scanner.SaveState(); _scanner.ScanCommentsInternal(); Token token = _scanner.Lex(new LexOptions(_context)); _scanner.RestoreState(in state); flag = token.Type == TokenType.Punctuator && (string)token.Value == "("; } return flag; } private ImportExpression ParseImportCall() { Marker marker = CreateNode(); ExpectKeyword("import"); Expect("("); bool isAssignmentTarget = _context.IsAssignmentTarget; _context.IsAssignmentTarget = true; Expression source = ParseAssignmentExpression(); Expression options = null; if (Match(",")) { NextToken(); if (!Match(")")) { options = ParseAssignmentExpression(); } } _context.IsAssignmentTarget = isAssignmentTarget; if (!Match(")")) { if (Match(",")) { NextToken(); } Expect(")"); } else { NextToken(); } return Finalize(in marker, new ImportExpression(source, options)); } private bool MatchImportMeta() { bool flag = MatchKeyword("import"); if (flag) { ScannerState state = _scanner.SaveState(); _scanner.ScanCommentsInternal(); LexOptions options = new LexOptions(_context); Token token = _scanner.Lex(in options); if (token.Type == TokenType.Punctuator && object.Equals(token.Value, ".")) { _scanner.ScanCommentsInternal(); Token token2 = _scanner.Lex(in options); flag = token2.Type == TokenType.Identifier && object.Equals(token2.Value, "meta"); if (flag && token2.IsEscaped("meta")) { TolerateUnexpectedToken(in token2, "Keyword must not contain escaped characters"); } } else { flag = false; } _scanner.RestoreState(in state); } return flag; } private MetaProperty ParseImportMeta() { Marker marker = CreateNode(); Identifier meta = ParseIdentifierName(); Expect("."); Identifier property = ParseIdentifierName(); _context.IsAssignmentTarget = false; return Finalize(in marker, new MetaProperty(meta, property)); } private Expression ParseLeftHandSideExpressionAllowCall() { Marker marker = StartNode(in _lookahead); bool maybeAsync = MatchContextualKeyword("async"); bool allowIn = _context.AllowIn; _context.AllowIn = true; bool flag = MatchKeyword("super"); Expression expression; if (flag) { Marker marker2 = CreateNode(); NextToken(); expression = Finalize(in marker2, new Super()); if (Match("(")) { if (!_context.AllowSuperCall) { TolerateError("'super' keyword unexpected here"); } } else if (Match(".") || Match("[")) { if (!_context.AllowSuperAccess) { TolerateError("'super' keyword unexpected here"); } } else { TolerateError("'super' keyword unexpected here"); } } else { expression = (MatchKeyword("new") ? InheritCoverGrammar(_parseNewExpression) : InheritCoverGrammar(_parsePrimaryExpression)); } bool flag2 = false; bool flag3 = false; while (true) { bool flag4 = false; if (Match("?.")) { if (_context.MemberAccessContext == MemberAccessContext.Decorator) { ThrowError("Invalid decorator member expression"); } flag4 = true; flag2 = true; Expect("?."); } if (Match("(")) { if (flag3 && _context.MemberAccessContext == MemberAccessContext.Decorator) { ThrowError("Invalid decorator member expression"); } flag3 = true; expression = ParseCallExpression(maybeAsync, in marker, expression, flag4); continue; } if (Match("[")) { if (_context.MemberAccessContext == MemberAccessContext.Decorator) { ThrowError("Invalid decorator member expression"); } _context.IsBindingElement = false; _context.IsAssignmentTarget = !flag4; Expect("["); Expression property = IsolateCoverGrammar(_parseExpression); Expect("]"); expression = Finalize(in marker, new ComputedMemberExpression(expression, property, flag4)); continue; } if (_lookahead.Type == TokenType.Template && _lookahead.Head) { if (_context.MemberAccessContext == MemberAccessContext.Decorator) { ThrowError("Invalid decorator member expression"); } if (flag4) { ThrowUnexpectedToken(in _lookahead); } if (flag2) { ThrowError("Invalid tagged template on optional chain"); } TemplateLiteral quasi = ParseTemplateLiteral(isTagged: true); expression = Finalize(in marker, new TaggedTemplateExpression(expression, quasi)); continue; } if (!(Match(".") || flag4)) { break; } if (flag3 && _context.MemberAccessContext == MemberAccessContext.Decorator) { ThrowError("Invalid decorator member expression"); } bool allowIdentifierEscape = _context.AllowIdentifierEscape; _context.IsBindingElement = false; _context.IsAssignmentTarget = !flag4; _context.AllowIdentifierEscape = true; if (!flag4) { Expect("."); } Expression expression2 = ParseIdentifierOrPrivateIdentifierName(); if (flag && expression2.Type == Nodes.PrivateIdentifier) { TolerateError("Unexpected private field"); } _context.AllowIdentifierEscape = allowIdentifierEscape; expression = Finalize(in marker, new StaticMemberExpression(expression, expression2, flag4)); } _context.AllowIn = allowIn; if (flag2) { return Finalize(in marker, new ChainExpression(expression)); } return expression; } private Expression ParseCallExpression(bool maybeAsync, in Marker startToken, Expression callee, bool optional) { bool num = maybeAsync && startToken.Line == _lookahead.LineNumber; _context.IsBindingElement = false; _context.IsAssignmentTarget = false; NodeList args = (num ? ParseAsyncArguments() : ParseArguments()); Expression result = Finalize(in startToken, new CallExpression(callee, in args, optional)); if (num && Match("=>")) { ArrayList arrayList = default(ArrayList); for (int i = 0; i < args.Count; i++) { arrayList.Add(ReinterpretExpressionAsPattern(args[i])); } result = new ArrowParameterPlaceHolder(NodeList.From(ref arrayList), async: true); } return result; } private Super ParseSuperAccess() { Marker marker = CreateNode(); ExpectKeyword("super"); if (!Match("[") && !Match(".")) { ThrowUnexpectedToken(in _lookahead); } return Finalize(in marker, new Super()); } private Expression ParseLeftHandSideExpression() { Marker marker = StartNode(in _lookahead); Expression expression = ((MatchKeyword("super") && _context.InFunctionBody) ? ParseSuperAccess() : (MatchKeyword("new") ? InheritCoverGrammar(_parseNewExpression) : InheritCoverGrammar(_parsePrimaryExpression))); bool flag = false; while (true) { bool flag2 = false; if (Match("?.")) { if (_context.MemberAccessContext == MemberAccessContext.NewExpressionCallee) { ThrowError("Invalid optional chain from new expression"); } flag2 = true; flag = true; Expect("?."); } if (Match("[")) { _context.IsBindingElement = false; _context.IsAssignmentTarget = !flag2; Expect("["); Expression property = IsolateCoverGrammar(_parseExpression); Expect("]"); expression = Finalize(in marker, new ComputedMemberExpression(expression, property, flag2)); continue; } if (_lookahead.Type == TokenType.Template && _lookahead.Head) { if (flag2) { ThrowUnexpectedToken(in _lookahead); } if (flag) { ThrowError("Invalid tagged template on optional chain"); } TemplateLiteral quasi = ParseTemplateLiteral(isTagged: true); expression = Finalize(in marker, new TaggedTemplateExpression(expression, quasi)); continue; } if (!(Match(".") || flag2)) { break; } _context.IsBindingElement = false; _context.IsAssignmentTarget = !flag2; if (!flag2) { Expect("."); } Identifier property2 = ParseIdentifierName(); expression = Finalize(in marker, new StaticMemberExpression(expression, property2, flag2)); } if (flag) { return Finalize(in marker, new ChainExpression(expression)); } return expression; } private Expression ParseUpdateExpression() { Marker marker = StartNode(in _lookahead); Expression expression; if (Match("++") || Match("--")) { expression = ParsePrefixUnaryExpression(in marker); } else { MemberAccessContext memberAccessContext = _context.MemberAccessContext; _context.MemberAccessContext = MemberAccessContext.Unknown; expression = InheritCoverGrammar(_parseLeftHandSideExpressionAllowCall); _context.MemberAccessContext = memberAccessContext; if (!_hasLineTerminator && _lookahead.Type == TokenType.Punctuator && (Match("++") || Match("--"))) { expression = ParsePostfixUnaryExpression(expression, in marker); } } return expression; } private Expression ParsePostfixUnaryExpression(Expression expr, in Marker marker) { if (_context.Strict && expr.Type == Nodes.Identifier && Scanner.IsRestrictedWord(expr.As().Name)) { TolerateError("Postfix increment/decrement may not have eval or arguments operand in strict mode"); } if (!_context.IsAssignmentTarget) { TolerateError("Invalid left-hand side in assignment"); } _context.IsAssignmentTarget = false; _context.IsBindingElement = false; object value = NextToken().Value; expr = Finalize(in marker, new UpdateExpression((string)value, expr, prefix: false)); return expr; } private Expression ParsePrefixUnaryExpression(in Marker marker) { Token token = NextToken(); Expression expression = InheritCoverGrammar(_parseUnaryExpression); if (_context.Strict && expression.Type == Nodes.Identifier && Scanner.IsRestrictedWord(expression.As().Name)) { TolerateError("Prefix increment/decrement may not have eval or arguments operand in strict mode"); } if (!_context.IsAssignmentTarget) { TolerateError("Invalid left-hand side in assignment"); } expression = Finalize(in marker, new UpdateExpression((string)token.Value, expression, prefix: true)); _context.IsAssignmentTarget = false; _context.IsBindingElement = false; return expression; } private AwaitExpression ParseAwaitExpression() { Marker marker = CreateNode(); NextToken(); Expression argument = ParseUnaryExpression(); return Finalize(in marker, new AwaitExpression(argument)); } private Expression ParseUnaryExpression() { if (MatchAny('+', '-', '~', '!') || (_lookahead.Type == TokenType.Keyword && MatchUnaryKeyword((string)_lookahead.Value))) { return ParseBasicUnaryExpression(); } if (_context.IsAsync && MatchContextualKeyword("await")) { if (_lookahead.IsEscaped("await")) { TolerateUnexpectedToken(in _lookahead, "Keyword must not contain escaped characters"); } return ParseAwaitExpression(); } return ParseUpdateExpression(); } private UnaryExpression ParseBasicUnaryExpression() { Marker marker = StartNode(in _lookahead); Token token = NextToken(); Expression arg = InheritCoverGrammar(_parseUnaryExpression); UnaryExpression unaryExpression = Finalize(in marker, new UnaryExpression((string)token.Value, arg)); if (_context.Strict && unaryExpression.Operator == UnaryOperator.Delete && unaryExpression.Argument.Type == Nodes.Identifier) { TolerateError("Delete of an unqualified identifier in strict mode."); } if (_context.Strict && unaryExpression.Operator == UnaryOperator.Delete && unaryExpression.Argument is MemberExpression memberExpression && memberExpression.Property is PrivateIdentifier) { TolerateError("Private fields can not be deleted"); } _context.IsAssignmentTarget = false; _context.IsBindingElement = false; return unaryExpression; } [StringMatcher(new string[] { "delete", "void", "typeof" })] private bool MatchUnaryKeyword(string input) { return input.Length switch { 4 => input == "void", 6 => input[0] switch { 'd' => input == "delete", 't' => input == "typeof", _ => false, }, _ => false, }; } private static BinaryExpression CreateBinaryExpression(string op, Expression left, Expression right) { switch (op) { case "&&": case "||": case "??": return new LogicalExpression(op, left, right); default: return new BinaryExpression(op, left, right); } } private Expression ParseBinaryExpressionOperand() { Marker marker = StartNode(in _lookahead); bool flag = Match("("); Expression expression = InheritCoverGrammar(_parseUnaryExpression); if ((expression.Type != Nodes.UnaryExpression || flag) && ConsumeMatch("**")) { expression = ParseExponentiationExpression(expression, in marker); } return expression; } private BinaryExpression ParseExponentiationExpression(Expression expr, in Marker marker) { _context.IsAssignmentTarget = false; _context.IsBindingElement = false; Expression right = IsolateCoverGrammar(_parseBinaryExpressionOperand); return Finalize(in marker, CreateBinaryExpression("**", expr, right)); } private int BinaryPrecedence(in Token token) { int result = 0; object value = token.Value; string text; if (token.Type == TokenType.Punctuator) { text = (string)value; if (text == null) { goto IL_023f; } switch (text.Length) { case 1: break; case 2: goto IL_00c6; case 3: goto IL_010e; default: goto IL_023f; } switch (text[0]) { case ')': case ',': case ';': case '=': case ']': break; case '|': goto IL_0218; case '^': goto IL_021c; case '&': goto IL_0221; case '<': case '>': goto IL_022b; case '+': case '-': goto IL_0235; case '%': case '*': case '/': goto IL_023a; default: goto IL_023f; } result = 0; } else if (token.Type == TokenType.Keyword) { result = (("instanceof".Equals(value) || (_context.AllowIn && "in".Equals(value))) ? 12 : 0); } goto IL_0279; IL_0176: if (text == "==") { goto IL_0226; } goto IL_023f; IL_0226: result = 11; goto IL_0279; IL_0230: result = 13; goto IL_0279; IL_0279: return result; IL_018b: if (text == "!=") { goto IL_0226; } goto IL_023f; IL_023f: result = 0; goto IL_0279; IL_014c: if (!(text == "||")) { goto IL_023f; } result = 6; goto IL_0279; IL_0161: if (!(text == "&&")) { goto IL_023f; } result = 7; goto IL_0279; IL_01bf: if (text == ">=") { goto IL_022b; } if (text == ">>") { goto IL_0230; } goto IL_023f; IL_022b: result = 12; goto IL_0279; IL_021c: result = 9; goto IL_0279; IL_0218: result = 8; goto IL_0279; IL_0221: result = 10; goto IL_0279; IL_0235: result = 14; goto IL_0279; IL_023a: result = 15; goto IL_0279; IL_010e: char c = text[0]; if (c != '!') { if (c != '=') { if (c == '>' && text == ">>>") { goto IL_0230; } } else if (text == "===") { goto IL_0226; } } else if (text == "!==") { goto IL_0226; } goto IL_023f; IL_00c6: switch (text[0]) { case '?': break; case '|': goto IL_014c; case '&': goto IL_0161; case '=': goto IL_0176; case '!': goto IL_018b; case '<': goto IL_01a0; case '>': goto IL_01bf; default: goto IL_023f; } if (!(text == "??")) { goto IL_023f; } result = 5; goto IL_0279; IL_01a0: if (text == "<=") { goto IL_022b; } if (text == "<<") { goto IL_0230; } goto IL_023f; } [MethodImpl(MethodImplOptions.AggressiveOptimization)] private Expression ParseBinaryExpression() { Token lookahead = _lookahead; Expression expression = InheritCoverGrammar(_parseBinaryExpressionOperand); bool allowAndOr = true; bool allowNullishCoalescing = true; Token token = _lookahead; int num = BinaryPrecedence(in token); if (num > 0) { UpdateNullishCoalescingRestrictions(in token, ref allowAndOr, ref allowNullishCoalescing); NextToken(); _context.IsAssignmentTarget = false; _context.IsBindingElement = false; Stack stack = _markersStack ?? new Stack(); _markersStack = null; stack.Clear(); stack.Push(lookahead); stack.Push(_lookahead); Expression item = expression; Expression item2 = IsolateCoverGrammar(_parseBinaryExpressionOperand); ArrayList value = _sharedStack ?? new ArrayList(3); _sharedStack = null; value.Clear(); value.Add(item); value.Add(token.Value); value.Add(item2); Stack stack2 = _precedencesStack ?? new Stack(1); _precedencesStack = null; stack2.Clear(); stack2.Push(num); while (true) { num = BinaryPrecedence(in _lookahead); if (num <= 0) { break; } if ((!allowAndOr && ("&&".Equals(_lookahead.Value) || "||".Equals(_lookahead.Value))) || (!allowNullishCoalescing && "??".Equals(_lookahead.Value))) { ThrowUnexpectedToken(in _lookahead); } UpdateNullishCoalescingRestrictions(in _lookahead, ref allowAndOr, ref allowNullishCoalescing); while (value.Count > 2 && num <= stack2.Peek()) { item2 = (Expression)value.Pop(); string op = (string)value.Pop(); stack2.Pop(); item = (Expression)value.Pop(); stack.Pop(); Token token2 = stack.Peek(); value.Push(Finalize(StartNode(in token2, token2.LineStart), CreateBinaryExpression(op, item, item2))); } value.Push(NextToken().Value); stack2.Push(num); stack.Push(_lookahead); value.Push(IsolateCoverGrammar(_parseBinaryExpressionOperand)); } int num2 = value.Count - 1; expression = (Expression)value[num2]; Token token3 = stack.Pop(); while (num2 > 1) { Token token4 = stack.Pop(); int lineStart = token3.LineStart; Marker marker = StartNode(in token4, lineStart); string op2 = (string)value[num2 - 1]; expression = Finalize(in marker, CreateBinaryExpression(op2, (Expression)value[num2 - 2], expression)); num2 -= 2; token3 = token4; } _markersStack = stack; _sharedStack = value; _precedencesStack = stack2; } return expression; static void UpdateNullishCoalescingRestrictions(in Token t, ref bool reference2, ref bool reference) { object value2 = t.Value; if ("&&".Equals(value2) || "||".Equals(value2)) { reference = false; } if ("??".Equals(value2)) { reference2 = false; } } } private ConditionalExpression ParseConditionalExpression(Expression expr, in Marker marker) { bool allowIn = _context.AllowIn; _context.AllowIn = true; Expression consequent = IsolateCoverGrammar(_parseAssignmentExpression); _context.AllowIn = allowIn; Expect(":"); Expression alternate = IsolateCoverGrammar(_parseAssignmentExpression); ConditionalExpression result = Finalize(in marker, new ConditionalExpression(expr, consequent, alternate)); _context.IsAssignmentTarget = false; _context.IsBindingElement = false; return result; } private void CheckPatternParam(ref ParsedParameters options, Node param) { switch (param.Type) { case Nodes.Identifier: ValidateParam(ref options, param, param.As().Name); break; case Nodes.RestElement: CheckPatternParam(ref options, param.As().Argument); break; case Nodes.AssignmentPattern: CheckPatternParam(ref options, param.As().Left); break; case Nodes.ArrayPattern: { ref readonly NodeList elements = ref param.As().Elements; for (int j = 0; j < elements.Count; j++) { Node node2 = elements[j]; if (node2 != null) { CheckPatternParam(ref options, node2); } } break; } case Nodes.ObjectPattern: { ref readonly NodeList properties = ref param.As().Properties; for (int i = 0; i < properties.Count; i++) { Node node = properties[i]; CheckPatternParam(ref options, (node is Property property) ? property.Value : node); } break; } } options.Simple = options.Simple && param is Identifier; } private ParsedParameters? ReinterpretAsCoverFormalsList(Expression expr) { bool flag = false; ArrayList parameters; switch (expr.Type) { case Nodes.Identifier: parameters = new ArrayList(new Node[1] { expr }); break; case (Nodes)(-2147483648): { ArrowParameterPlaceHolder arrowParameterPlaceHolder = expr.As(); parameters = ArrayList.Create(in arrowParameterPlaceHolder.Params); flag = arrowParameterPlaceHolder.Async; break; } default: return null; } ParsedParameters parsedParameters = new ParsedParameters(); parsedParameters.Simple = true; ParsedParameters options = parsedParameters; for (int i = 0; i < parameters.Count; i++) { Node node = parameters[i]; if (node.Type == Nodes.AssignmentPattern) { AssignmentPattern assignmentPattern = node.As(); if (assignmentPattern.Right.Type == Nodes.YieldExpression) { if (assignmentPattern.Right.As().Argument != null) { ThrowUnexpectedToken(in _lookahead); } assignmentPattern._right = new Identifier("yield") { Location = assignmentPattern.Right.Location, Range = assignmentPattern.Right.Range }; } } else if (flag && node.Type == Nodes.Identifier && node.As().Name == "await") { ThrowUnexpectedToken(in _lookahead); } CheckPatternParam(ref options, node); parameters[i] = node; } if (_context.Strict || !_context.AllowYield) { for (int j = 0; j < parameters.Count; j++) { if (parameters[j].Type == Nodes.YieldExpression) { ThrowUnexpectedToken(in _lookahead); } } } if (options.HasDuplicateParameterNames) { ThrowUnexpectedToken((_context.Strict ? options.Stricted : options.FirstRestricted).GetValueOrDefault(), "Duplicate parameter name not allowed in this context"); } parsedParameters = new ParsedParameters(); parsedParameters.Simple = options.Simple; parsedParameters.Parameters = parameters; parsedParameters.Stricted = options.Stricted; parsedParameters.FirstRestricted = options.FirstRestricted; parsedParameters.Message = options.Message; return parsedParameters; } private protected Expression ParseAssignmentExpression() { if (_assignmentDepth++ > _maxAssignmentDepth) { ThrowUnexpectedToken(in _lookahead, "Maximum statements depth reached"); } Expression expression; if (!_context.AllowYield && MatchKeyword("yield")) { expression = ParseYieldExpression(); } else { Token token = _lookahead; expression = InheritCoverGrammar(_parseBinaryExpression); if (ConsumeMatch("?")) { expression = ParseConditionalExpression(expression, StartNode(in token)); } if (token.Type == TokenType.Identifier && token.LineNumber == _lookahead.LineNumber && (string)token.Value == "async" && (_lookahead.Type == TokenType.Identifier || MatchKeyword("yield"))) { Expression expression2 = ParsePrimaryExpression(); ReinterpretExpressionAsPattern(expression2); Node[] items = new Expression[1] { expression2 }; expression = new ArrowParameterPlaceHolder(new NodeList(items, 1), async: true); } if (expression.Type == (Nodes)(-2147483648) || Match("=>")) { _context.IsAssignmentTarget = false; _context.IsBindingElement = false; bool flag = expression is ArrowParameterPlaceHolder arrowParameterPlaceHolder && arrowParameterPlaceHolder.Async; ParsedParameters? parsedParameters = ReinterpretAsCoverFormalsList(expression); if (parsedParameters.HasValue) { ParsedParameters value = parsedParameters.Value; if (_hasLineTerminator) { TolerateUnexpectedToken(in _lookahead); } _context.FirstCoverInitializedNameError = null; bool strict = _context.Strict; bool allowStrictDirective = _context.AllowStrictDirective; _context.AllowStrictDirective = value.Simple; bool allowYield = _context.AllowYield; bool isAsync = _context.IsAsync; _context.AllowYield = true; _context.IsAsync = flag; Marker marker = StartNode(in token); Expect("=>"); StatementListItem statementListItem; if (Match("{")) { bool allowIn = _context.AllowIn; _context.AllowIn = true; statementListItem = ParseFunctionSourceElements(); _context.AllowIn = allowIn; } else { statementListItem = IsolateCoverGrammar(_parseAssignmentExpression); } bool expression3 = statementListItem.Type != Nodes.BlockStatement; if (_context.Strict && value.FirstRestricted.HasValue) { ThrowUnexpectedToken(value.FirstRestricted.Value, value.Message); } if (_context.Strict && value.Stricted.HasValue) { TolerateUnexpectedToken(value.Stricted.Value, value.Message); } ArrayList arrayList = value.Parameters; expression = Finalize(in marker, new ArrowFunctionExpression(NodeList.From(ref arrayList), statementListItem, expression3, _context.Strict, flag)); _context.Strict = strict; _context.AllowStrictDirective = allowStrictDirective; _context.AllowYield = allowYield; _context.IsAsync = isAsync; } } else if (MatchAssign()) { if (!_context.IsAssignmentTarget) { TolerateError("Invalid left-hand side in assignment"); } if (_context.Strict && expression.Type == Nodes.Identifier) { Identifier identifier = expression.As(); if (Scanner.IsRestrictedWord(identifier.Name)) { ThrowUnexpectedToken(in token, "Assignment to eval or arguments is not allowed in strict mode"); } if (Scanner.IsStrictModeReservedWord(identifier.Name)) { ThrowUnexpectedToken(in token, "Use of future reserved word in strict mode"); } } Node left; if (!Match("=")) { _context.IsAssignmentTarget = false; _context.IsBindingElement = false; left = expression; } else { left = ReinterpretExpressionAsPattern(expression); } Token token2 = NextToken(); Expression right = IsolateCoverGrammar(_parseAssignmentExpression); expression = Finalize(StartNode(in token), new AssignmentExpression((string)token2.Value, left, right)); _context.FirstCoverInitializedNameError = null; } } _assignmentDepth--; return expression; } private Expression ParseExpression() { Token token = _lookahead; Expression expression = IsolateCoverGrammar(_parseAssignmentExpression); if (Match(",")) { ArrayList arrayList = default(ArrayList); arrayList.Push(expression); while (_lookahead.Type != TokenType.EOF && Match(",")) { NextToken(); arrayList.Push(IsolateCoverGrammar(_parseAssignmentExpression)); } expression = Finalize(StartNode(in token), new SequenceExpression(NodeList.From(ref arrayList))); } return expression; } public Expression ParseExpression(string code, bool strict = false) { Reset(code, null); try { _context.Strict = strict; _context.IsAsync = true; return FinalizeRoot(ParseExpression()); } finally { ReleaseLargeBuffers(); } } private Statement ParseStatementListItem() { _context.IsAssignmentTarget = true; _context.IsBindingElement = true; if (_lookahead.Type == TokenType.Keyword) { switch ((string)_lookahead.Value) { case "export": if (!_context.IsModule) { ThrowUnexpectedToken(in _lookahead, "Unexpected token"); } return ParseExportDeclaration(); case "import": if (MatchImportCall()) { return ParseExpressionStatement(); } if (MatchImportMeta()) { return ParseStatement(); } if (!_context.IsModule) { ThrowUnexpectedToken(in _lookahead, "Unexpected token"); } return ParseImportDeclaration(); case "const": return ParseLexicalDeclaration(); case "function": return ParseFunctionDeclaration(); case "class": return ParseClassDeclaration(); case "let": return IsLexicalDeclaration() ? ParseLexicalDeclaration() : ParseStatement(); default: return ParseStatement(); } } return ParseStatement(); } private BlockStatement ParseBlock() { Marker marker = CreateNode(); Expect("{"); ArrayList arrayList = default(ArrayList); while (!Match("}")) { arrayList.Add(ParseStatementListItem()); } Expect("}"); return Finalize(in marker, new BlockStatement(NodeList.From(ref arrayList))); } private VariableDeclarator ParseLexicalBinding(VariableDeclarationKind kind, bool inFor) { Marker marker = CreateNode(); ArrayList parameters = _parseVariableBindingParameters.GetValueOrDefault(); _parseVariableBindingParameters = null; parameters.Clear(); Node node = ParsePattern(ref parameters, kind); _parseVariableBindingParameters = parameters; if (_context.Strict && node.Type == Nodes.Identifier && Scanner.IsRestrictedWord(node.As().Name)) { TolerateError("Variable name may not be eval or arguments in strict mode"); } Expression init = null; if (kind == VariableDeclarationKind.Const) { if (!MatchKeyword("in") && !MatchContextualKeyword("of")) { if (!Match("=")) { return ThrowError("Missing initializer in {0} declaration", new object[1] { "const" }); } NextToken(); init = IsolateCoverGrammar(_parseAssignmentExpression); } } else if ((!inFor && node.Type != Nodes.Identifier) || Match("=")) { Expect("="); init = IsolateCoverGrammar(_parseAssignmentExpression); } return Finalize(in marker, new VariableDeclarator(node, init)); } private NodeList ParseBindingList(VariableDeclarationKind kind, bool inFor) { ArrayList arrayList = new ArrayList(new VariableDeclarator[1] { ParseLexicalBinding(kind, inFor) }); while (Match(",")) { NextToken(); arrayList.Add(ParseLexicalBinding(kind, inFor)); } return NodeList.From(ref arrayList); } private bool IsLexicalDeclaration() { ScannerState state = _scanner.SaveState(); _scanner.ScanCommentsInternal(); Token token = _scanner.Lex(new LexOptions(_context)); _scanner.RestoreState(in state); if (token.Type != TokenType.Identifier && (token.Type != TokenType.Punctuator || !((string)token.Value == "[")) && (token.Type != TokenType.Punctuator || !((string)token.Value == "{")) && (token.Type != TokenType.Keyword || !((string)token.Value == "let"))) { if (token.Type == TokenType.Keyword) { return (string)token.Value == "yield"; } return false; } return true; } private VariableDeclaration ParseLexicalDeclaration() { Marker marker = CreateNode(); string kindString = (string)NextToken().Value; VariableDeclarationKind kind = ParseVariableDeclarationKind(kindString); NodeList declarations = ParseBindingList(kind, inFor: false); ConsumeSemicolon(); return Finalize(in marker, new VariableDeclaration(in declarations, kind)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private VariableDeclarationKind ParseVariableDeclarationKind(string? kindString) { return kindString switch { "const" => VariableDeclarationKind.Const, "let" => VariableDeclarationKind.Let, "var" => VariableDeclarationKind.Var, _ => ThrowError("Unknown declaration kind '{0}'", new object[1] { kindString }), }; } private RestElement ParseBindingRestElement(ref ArrayList parameters, VariableDeclarationKind? kind) { Marker marker = CreateNode(); Expect("..."); Node argument = ParsePattern(ref parameters, kind); return Finalize(in marker, new RestElement(argument)); } private ArrayPattern ParseArrayPattern(ref ArrayList parameters, VariableDeclarationKind? kind) { Marker marker = CreateNode(); Expect("["); ArrayList arrayList = default(ArrayList); while (!Match("]")) { if (Match(",")) { NextToken(); arrayList.Push(null); continue; } if (Match("...")) { arrayList.Push(ParseBindingRestElement(ref parameters, kind)); break; } arrayList.Push(ParsePatternWithDefault(ref parameters, kind)); if (!Match("]")) { Expect(","); } } Expect("]"); return Finalize(in marker, new ArrayPattern(NodeList.From(ref arrayList))); } private Property ParsePropertyPattern(ref ArrayList parameters, VariableDeclarationKind? kind) { Marker marker = CreateNode(); bool computed = false; bool shorthand = false; bool method = false; Expression expression; Node value; if (_lookahead.Type == TokenType.Identifier) { Token token = _lookahead; expression = ParseVariableIdentifier(); if (Match("=")) { parameters.Push(token); shorthand = true; NextToken(); bool isAssignmentTarget = _context.IsAssignmentTarget; _context.IsAssignmentTarget = true; Expression right = ParseAssignmentExpression(); _context.IsAssignmentTarget = isAssignmentTarget; value = Finalize(StartNode(in token), new AssignmentPattern(expression, right)); } else if (!Match(":")) { parameters.Push(token); shorthand = true; value = expression; } else { Expect(":"); value = ParsePatternWithDefault(ref parameters, kind); } } else { computed = Match("["); expression = ParseObjectPropertyKey(); Expect(":"); value = ParsePatternWithDefault(ref parameters, kind); } return Finalize(in marker, new Property(PropertyKind.Init, expression, computed, value, method, shorthand)); } private RestElement ParseRestProperty(ref ArrayList parameters, VariableDeclarationKind? kind) { Marker marker = CreateNode(); Expect("..."); Node argument = ParsePattern(ref parameters); if (Match("=")) { ThrowError("Unexpected token ="); } if (!Match("}")) { ThrowError("Unexpected token"); } return Finalize(in marker, new RestElement(argument)); } private ObjectPattern ParseObjectPattern(ref ArrayList parameters, VariableDeclarationKind? kind) { Marker marker = CreateNode(); ArrayList arrayList = default(ArrayList); Expect("{"); while (!Match("}")) { arrayList.Push(Match("...") ? ((Node)ParseRestProperty(ref parameters, kind)) : ((Node)ParsePropertyPattern(ref parameters, kind))); if (!Match("}")) { Expect(","); } } Expect("}"); return Finalize(in marker, new ObjectPattern(NodeList.From(ref arrayList))); } private Node ParsePattern(ref ArrayList parameters, VariableDeclarationKind? kind = null) { if (Match("[")) { return ParseArrayPattern(ref parameters, kind); } if (Match("{")) { return ParseObjectPattern(ref parameters, kind); } bool flag; if (kind.HasValue) { VariableDeclarationKind valueOrDefault = kind.GetValueOrDefault(); if ((uint)(valueOrDefault - 1) <= 1u) { flag = true; goto IL_004d; } } flag = false; goto IL_004d; IL_004d: if (flag && MatchKeyword("let")) { TolerateUnexpectedToken(in _lookahead, "let is disallowed as a lexically bound name"); } parameters.Push(_lookahead); return ParseVariableIdentifier(kind); } private Node ParsePatternWithDefault(ref ArrayList parameters, VariableDeclarationKind? kind = null) { Token token = _lookahead; Node node = ParsePattern(ref parameters, kind); if (Match("=")) { NextToken(); bool allowYield = _context.AllowYield; _context.AllowYield = true; Expression right = IsolateCoverGrammar(_parseAssignmentExpression); _context.AllowYield = allowYield; node = Finalize(StartNode(in token), new AssignmentPattern(node, right)); } return node; } private Identifier ParseVariableIdentifier(VariableDeclarationKind? kind = null, bool allowAwaitKeyword = false) { Marker marker = CreateNode(); Token token = NextToken(); if (token.Type == TokenType.Keyword && (string)token.Value == "yield") { if (_context.Strict) { TolerateUnexpectedToken(in token, "Use of future reserved word in strict mode"); } if (!_context.AllowYield) { ThrowUnexpectedToken(in token); } } else if (token.Type != TokenType.Identifier) { if (_context.Strict && token.Type == TokenType.Keyword && Scanner.IsStrictModeReservedWord((string)token.Value)) { ThrowUnexpectedToken(in token, "Use of future reserved word in strict mode"); } else { string text = token.Value as string; if (_context.Strict || text == null || text != "let" || kind != VariableDeclarationKind.Var) { ThrowUnexpectedToken(in token); } } } else if (_context.IsAsync && !allowAwaitKeyword && token.Type == TokenType.Identifier && (string)token.Value == "await") { TolerateUnexpectedToken(in token); } return Finalize(in marker, new Identifier((string)token.Value)); } private VariableDeclarator ParseVariableDeclaration(bool inFor) { Marker marker = CreateNode(); ArrayList parameters = _parseVariableBindingParameters.GetValueOrDefault(); _parseVariableBindingParameters = null; parameters.Clear(); Node node = ParsePattern(ref parameters, VariableDeclarationKind.Var); _parseVariableBindingParameters = parameters; if (_context.Strict && node.Type == Nodes.Identifier && Scanner.IsRestrictedWord(node.As().Name)) { ThrowError("Variable name may not be eval or arguments in strict mode"); } Expression init = null; if (Match("=")) { NextToken(); init = IsolateCoverGrammar(_parseAssignmentExpression); } else if (node.Type != Nodes.Identifier && !inFor) { Expect("="); } return Finalize(in marker, new VariableDeclarator(node, init)); } private NodeList ParseVariableDeclarationList(bool inFor) { ArrayList arrayList = new ArrayList(new VariableDeclarator[1] { ParseVariableDeclaration(inFor) }); while (Match(",")) { NextToken(); arrayList.Push(ParseVariableDeclaration(inFor)); } return NodeList.From(ref arrayList); } private VariableDeclaration ParseVariableStatement() { Marker marker = CreateNode(); ExpectKeyword("var"); NodeList declarations = ParseVariableDeclarationList(inFor: false); ConsumeSemicolon(); return Finalize(in marker, new VariableDeclaration(in declarations, VariableDeclarationKind.Var)); } private EmptyStatement ParseEmptyStatement() { Marker marker = CreateNode(); Expect(";"); return Finalize(in marker, new EmptyStatement()); } private ExpressionStatement ParseExpressionStatement() { Marker marker = CreateNode(); Expression expression = ParseExpression(); ConsumeSemicolon(); return Finalize(in marker, new ExpressionStatement(expression)); } private Statement ParseIfClause() { if (_context.Strict && MatchKeyword("function")) { TolerateError("In strict mode code, functions can only be declared at top level or inside a block"); } return ParseStatement(); } private IfStatement ParseIfStatement() { Marker marker = CreateNode(); Statement alternate = null; ExpectKeyword("if"); Expect("("); Expression test = ParseExpression(); Statement consequent; if (!Match(")") && _tolerant) { TolerateUnexpectedToken(NextToken()); consequent = Finalize(CreateNode(), new EmptyStatement()); } else { Expect(")"); consequent = ParseIfClause(); if (MatchKeyword("else")) { NextToken(); alternate = ParseIfClause(); } } return Finalize(in marker, new IfStatement(test, consequent, alternate)); } private DoWhileStatement ParseDoWhileStatement() { Marker marker = CreateNode(); ExpectKeyword("do"); if (MatchKeyword("class") || MatchKeyword("function")) { TolerateUnexpectedToken(in _lookahead); } bool inIteration = _context.InIteration; _context.InIteration = true; Statement body = ParseStatement(); _context.InIteration = inIteration; ExpectKeyword("while"); Expect("("); Expression test = ParseExpression(); if (!Match(")") && _tolerant) { TolerateUnexpectedToken(NextToken()); } else { Expect(")"); if (Match(";")) { NextToken(); } } return Finalize(in marker, new DoWhileStatement(body, test)); } private WhileStatement ParseWhileStatement() { Marker marker = CreateNode(); ExpectKeyword("while"); Expect("("); Expression test = ParseExpression(); Statement body; if (!Match(")") && _tolerant) { TolerateUnexpectedToken(NextToken()); body = Finalize(CreateNode(), new EmptyStatement()); } else { Expect(")"); bool inIteration = _context.InIteration; _context.InIteration = true; body = ParseStatement(); _context.InIteration = inIteration; } return Finalize(in marker, new WhileStatement(test, body)); } private Statement ParseForStatement() { StatementListItem statementListItem = null; Expression test = null; Expression update = null; bool flag = true; Node node = null; Expression right = null; bool flag2 = false; Marker marker = CreateNode(); ExpectKeyword("for"); if (MatchContextualKeyword("await")) { if (!_context.IsAsync) { TolerateUnexpectedToken(in _lookahead); } flag2 = true; NextToken(); } Expect("("); if (Match(";")) { if (flag2) { TolerateUnexpectedToken(in _lookahead); } NextToken(); } else if (MatchKeyword("var")) { Marker marker2 = CreateNode(); NextToken(); bool allowIn = _context.AllowIn; _context.AllowIn = false; NodeList declarations = ParseVariableDeclarationList(inFor: true); _context.AllowIn = allowIn; if (declarations.Count == 1 && MatchKeyword("in")) { if (flag2) { TolerateUnexpectedToken(in _lookahead); } VariableDeclarator variableDeclarator = declarations[0]; if (variableDeclarator.Init != null && (variableDeclarator.Id.Type == Nodes.ArrayPattern || variableDeclarator.Id.Type == Nodes.ObjectPattern || _context.Strict)) { TolerateError("'{0} loop variable declaration may not have an initializer", "for-in"); } node = Finalize(in marker2, new VariableDeclaration(in declarations, VariableDeclarationKind.Var)); NextToken(); right = ParseExpression(); statementListItem = null; } else if (declarations.Count == 1 && declarations[0].Init == null && MatchContextualKeyword("of")) { node = Finalize(in marker2, new VariableDeclaration(in declarations, VariableDeclarationKind.Var)); NextToken(); right = ParseAssignmentExpression(); statementListItem = null; flag = false; } else { if (flag2) { TolerateUnexpectedToken(in _lookahead); } statementListItem = Finalize(in marker2, new VariableDeclaration(in declarations, VariableDeclarationKind.Var)); Expect(";"); } } else if (MatchKeyword("const") || MatchKeyword("let")) { Marker marker3 = CreateNode(); string text = (string)NextToken().Value; VariableDeclarationKind kind = ParseVariableDeclarationKind(text); if (!_context.Strict && (string)_lookahead.Value == "in") { if (flag2) { TolerateUnexpectedToken(in _lookahead); } node = Finalize(in marker3, new Identifier(text)); NextToken(); right = ParseExpression(); statementListItem = null; } else { bool allowIn2 = _context.AllowIn; _context.AllowIn = false; NodeList declarations2 = ParseBindingList(kind, inFor: true); _context.AllowIn = allowIn2; if (declarations2.Count == 1 && declarations2[0].Init == null && MatchKeyword("in")) { if (flag2) { TolerateUnexpectedToken(in _lookahead); } node = Finalize(in marker3, new VariableDeclaration(in declarations2, kind)); NextToken(); right = ParseExpression(); statementListItem = null; } else if (declarations2.Count == 1 && declarations2[0].Init == null && MatchContextualKeyword("of")) { node = Finalize(in marker3, new VariableDeclaration(in declarations2, kind)); NextToken(); right = ParseAssignmentExpression(); statementListItem = null; flag = false; } else { if (flag2) { TolerateUnexpectedToken(in _lookahead); } ConsumeSemicolon(); statementListItem = Finalize(in marker3, new VariableDeclaration(in declarations2, kind)); } } } else { Token token = _lookahead; bool isBindingElement = _context.IsBindingElement; bool isAssignmentTarget = _context.IsAssignmentTarget; StrongBox firstCoverInitializedNameError = _context.FirstCoverInitializedNameError; bool allowIn3 = _context.AllowIn; _context.AllowIn = false; statementListItem = InheritCoverGrammar(_parseAssignmentExpression); _context.AllowIn = allowIn3; if (MatchKeyword("in")) { if (flag2) { TolerateUnexpectedToken(in _lookahead); } if (!_context.IsAssignmentTarget || statementListItem.Type == Nodes.AssignmentExpression) { TolerateError("Invalid left-hand side in for-in"); } NextToken(); node = ReinterpretExpressionAsPattern(statementListItem); right = ParseExpression(); statementListItem = null; } else if (MatchContextualKeyword("of")) { if (!_context.IsAssignmentTarget || statementListItem.Type == Nodes.AssignmentExpression) { TolerateError("Invalid left-hand side in for-loop"); } NextToken(); node = ReinterpretExpressionAsPattern(statementListItem); right = ParseAssignmentExpression(); statementListItem = null; flag = false; } else { if (flag2) { TolerateUnexpectedToken(in _lookahead); } _context.IsBindingElement = isBindingElement; _context.IsAssignmentTarget = isAssignmentTarget; _context.FirstCoverInitializedNameError = firstCoverInitializedNameError; if (Match(",")) { ArrayList arrayList = new ArrayList(new Expression[1] { (Expression)statementListItem }); while (Match(",")) { NextToken(); arrayList.Push(IsolateCoverGrammar(_parseAssignmentExpression)); } statementListItem = Finalize(StartNode(in token), new SequenceExpression(NodeList.From(ref arrayList))); } Expect(";"); } } if (node == null) { if (!Match(";")) { test = IsolateCoverGrammar(_parseExpression); } Expect(";"); if (!Match(")")) { update = IsolateCoverGrammar(_parseExpression); } } Statement body; if (!Match(")") && _tolerant) { TolerateUnexpectedToken(NextToken()); body = Finalize(CreateNode(), new EmptyStatement()); } else { Expect(")"); TolerateInvalidLoopStatement(); bool inIteration = _context.InIteration; _context.InIteration = true; body = IsolateCoverGrammar(_parseStatement); _context.InIteration = inIteration; } if (node != null) { if (!flag) { return Finalize(in marker, new ForOfStatement(node, right, body, flag2)); } return Finalize(in marker, new ForInStatement(node, right, body)); } return Finalize(in marker, new ForStatement(statementListItem, test, update, body)); } private ContinueStatement ParseContinueStatement() { Marker marker = CreateNode(); ExpectKeyword("continue"); Identifier identifier = null; if (_lookahead.Type == TokenType.Identifier && !_hasLineTerminator) { identifier = ParseVariableIdentifier(); string name = identifier.Name; if (!_context.LabelSet.Contains(name)) { return ThrowError("Undefined label \"{0}\"", new object[1] { identifier.Name }); } } ConsumeSemicolon(); if (identifier == null && !_context.InIteration) { return ThrowError("Illegal continue statement", Array.Empty()); } return Finalize(in marker, new ContinueStatement(identifier)); } private BreakStatement ParseBreakStatement() { Marker marker = CreateNode(); ExpectKeyword("break"); Identifier identifier = null; if (_lookahead.Type == TokenType.Identifier && !_hasLineTerminator) { identifier = ParseVariableIdentifier(); string name = identifier.Name; if (!_context.LabelSet.Contains(name)) { return ThrowError("Undefined label \"{0}\"", new object[1] { identifier.Name }); } } ConsumeSemicolon(); if (identifier == null && !_context.InIteration && !_context.InSwitch) { return ThrowError("Illegal break statement", Array.Empty()); } return Finalize(in marker, new BreakStatement(identifier)); } private ReturnStatement ParseReturnStatement() { if (!_context.InFunctionBody && !_allowReturnOutsideFunction) { ThrowError("Illegal return statement"); } Marker marker = CreateNode(); ExpectKeyword("return"); Expression argument = (((!Match(";") && !Match("}") && !_hasLineTerminator && _lookahead.Type != TokenType.EOF) || _lookahead.Type == TokenType.StringLiteral || _lookahead.Type == TokenType.Template) ? ParseExpression() : null); ConsumeSemicolon(); return Finalize(in marker, new ReturnStatement(argument)); } private WithStatement ParseWithStatement() { if (_context.Strict) { ThrowError("Strict mode code may not include a with statement"); } Marker marker = CreateNode(); ExpectKeyword("with"); Expect("("); Expression obj = ParseExpression(); Statement body; if (!Match(")") && _tolerant) { TolerateUnexpectedToken(NextToken()); body = Finalize(CreateNode(), new EmptyStatement()); } else { Expect(")"); body = ParseStatement(); } return Finalize(in marker, new WithStatement(obj, body)); } private SwitchCase ParseSwitchCase() { Marker marker = CreateNode(); Expression test; if (MatchKeyword("default")) { NextToken(); test = null; } else { ExpectKeyword("case"); test = ParseExpression(); } Expect(":"); ArrayList arrayList = default(ArrayList); while (!Match("}") && !MatchKeyword("default") && !MatchKeyword("case")) { arrayList.Push(ParseStatementListItem()); } return Finalize(in marker, new SwitchCase(test, NodeList.From(ref arrayList))); } private SwitchStatement ParseSwitchStatement() { Marker marker = CreateNode(); ExpectKeyword("switch"); Expect("("); Expression discriminant = ParseExpression(); Expect(")"); bool inSwitch = _context.InSwitch; _context.InSwitch = true; ArrayList arrayList = default(ArrayList); bool flag = false; Expect("{"); while (!Match("}")) { SwitchCase switchCase = ParseSwitchCase(); if (switchCase.Test == null) { if (flag) { ThrowError("More than one default clause in switch statement"); } flag = true; } arrayList.Push(switchCase); } Expect("}"); _context.InSwitch = inSwitch; return Finalize(in marker, new SwitchStatement(discriminant, NodeList.From(ref arrayList))); } private Statement ParseLabelledStatement() { Marker marker = CreateNode(); Expression expression = ParseExpression(); Statement node; if (expression.Type == Nodes.Identifier && Match(":")) { NextToken(); Identifier identifier = expression.As(); string name = identifier.Name; if (!_context.LabelSet.Add(name)) { ThrowError("{0} \"{1}\" has already been declared", "Label", identifier.Name); } Statement body; if (MatchKeyword("class")) { TolerateUnexpectedToken(in _lookahead); body = ParseClassDeclaration(); } else if (Match("@")) { TolerateUnexpectedToken(in _lookahead); body = ParseDecoratedClassDeclaration(); } else if (MatchKeyword("function")) { Token token = _lookahead; FunctionDeclaration functionDeclaration = ParseFunctionDeclaration(); if (_context.Strict) { TolerateUnexpectedToken(in token, "In strict mode code, functions can only be declared at top level or inside a block"); } else if (functionDeclaration.Generator) { TolerateUnexpectedToken(in token, "Generator declarations are not allowed in legacy contexts"); } body = functionDeclaration; } else { body = ParseStatement(); } _context.LabelSet.Remove(name); node = new LabeledStatement(identifier, body); } else { ConsumeSemicolon(); node = new ExpressionStatement(expression); } return Finalize(in marker, node); } private ThrowStatement ParseThrowStatement() { Marker marker = CreateNode(); ExpectKeyword("throw"); if (_hasLineTerminator) { ThrowError("Illegal newline after throw"); } Expression argument = ParseExpression(); ConsumeSemicolon(); return Finalize(in marker, new ThrowStatement(argument)); } private CatchClause ParseCatchClause() { Marker marker = CreateNode(); ExpectKeyword("catch"); Node node = null; if (Match("(")) { Expect("("); if (Match(")")) { ThrowUnexpectedToken(in _lookahead); } ArrayList parameters = _parseVariableBindingParameters.GetValueOrDefault(); _parseVariableBindingParameters = null; parameters.Clear(); node = ParsePattern(ref parameters); Dictionary dictionary = new Dictionary(); for (int i = 0; i < parameters.Count; i++) { string key = (string)parameters[i].Value; if (dictionary.ContainsKey(key)) { TolerateError("Duplicate binding {0}", parameters[i].Value); } dictionary[key] = true; } _parseVariableBindingParameters = parameters; if (_context.Strict && node.Type == Nodes.Identifier && Scanner.IsRestrictedWord(node.As().Name)) { ThrowError("Catch variable may not be eval or arguments in strict mode"); } Expect(")"); } BlockStatement body = ParseBlock(); return Finalize(in marker, new CatchClause(node, body)); } private BlockStatement ParseFinallyClause() { ExpectKeyword("finally"); return ParseBlock(); } private TryStatement ParseTryStatement() { Marker marker = CreateNode(); ExpectKeyword("try"); BlockStatement block = ParseBlock(); CatchClause catchClause = (MatchKeyword("catch") ? ParseCatchClause() : null); BlockStatement blockStatement = (MatchKeyword("finally") ? ParseFinallyClause() : null); if (catchClause == null && blockStatement == null) { return ThrowError("Missing catch or finally after try", Array.Empty()); } return Finalize(in marker, new TryStatement(block, catchClause, blockStatement)); } private DebuggerStatement ParseDebuggerStatement() { Marker marker = CreateNode(); ExpectKeyword("debugger"); ConsumeSemicolon(); return Finalize(in marker, new DebuggerStatement()); } private Statement ParseStatement() { switch (_lookahead.Type) { case TokenType.BooleanLiteral: case TokenType.NullLiteral: case TokenType.NumericLiteral: case TokenType.StringLiteral: case TokenType.RegularExpression: case TokenType.Template: case TokenType.BigIntLiteral: return ParseExpressionStatement(); case TokenType.Punctuator: return (string)_lookahead.Value switch { "{" => ParseBlock(), "@" => ParseDecoratedClassDeclaration(), ";" => ParseEmptyStatement(), "#!" => ThrowUnexpectedToken(in _lookahead), _ => ParseExpressionStatement(), }; case TokenType.Identifier: return MatchAsyncFunction() ? ParseFunctionDeclaration() : ParseLabelledStatement(); case TokenType.Keyword: return (string)_lookahead.Value switch { "break" => ParseBreakStatement(), "continue" => ParseContinueStatement(), "debugger" => ParseDebuggerStatement(), "do" => ParseDoWhileStatement(), "for" => ParseForStatement(), "function" => ParseFunctionDeclaration(), "if" => ParseIfStatement(), "return" => ParseReturnStatement(), "switch" => ParseSwitchStatement(), "throw" => ParseThrowStatement(), "try" => ParseTryStatement(), "var" => ParseVariableStatement(), "while" => ParseWhileStatement(), "with" => ParseWithStatement(), _ => ParseExpressionStatement(), }; default: return ThrowUnexpectedToken(in _lookahead); } } private BlockStatement ParseFunctionSourceElements() { Marker marker = CreateNode(); Expect("{"); ArrayList arrayList = ParseDirectivePrologues(); bool flag = _context.LabelSet.Count == 0; HashSet labelSet = _context.LabelSet; bool inIteration = _context.InIteration; bool inSwitch = _context.InSwitch; bool inFunctionBody = _context.InFunctionBody; _context.LabelSet = (flag ? labelSet : new HashSet()); _context.InIteration = false; _context.InSwitch = false; _context.InFunctionBody = true; while (_lookahead.Type != TokenType.EOF && !Match("}")) { arrayList.Push(ParseStatementListItem()); } Expect("}"); _context.LabelSet = labelSet; if (flag) { _context.LabelSet.Clear(); } _context.InIteration = inIteration; _context.InSwitch = inSwitch; _context.InFunctionBody = inFunctionBody; return Finalize(in marker, new BlockStatement(NodeList.From(ref arrayList))); } private void ValidateParam(ref ParsedParameters options, Node param, string? name) { if (_context.Strict) { if (name != null && Scanner.IsRestrictedWord(name)) { options.Stricted = default(Token); options.Message = "Parameter name eval or arguments is not allowed in strict mode"; } if (options.ParamSetContains(name)) { options.Stricted = default(Token); options.HasDuplicateParameterNames = true; } } else if (!options.FirstRestricted.HasValue) { if (name != null && Scanner.IsRestrictedWord(name)) { options.FirstRestricted = default(Token); options.Message = "Parameter name eval or arguments is not allowed in strict mode"; } else if (name != null && Scanner.IsStrictModeReservedWord(name)) { options.FirstRestricted = default(Token); options.Message = "Use of future reserved word in strict mode"; } else if (options.ParamSetContains(name)) { options.Stricted = default(Token); options.HasDuplicateParameterNames = true; } } options.ParamSetAdd(name); } private void ValidateParam2(ref ParsedParameters options, in Token param, string? name) { if (_context.Strict) { if (name != null && Scanner.IsRestrictedWord(name)) { options.Stricted = param; options.Message = "Parameter name eval or arguments is not allowed in strict mode"; } if (options.ParamSetContains(name)) { options.Stricted = param; options.HasDuplicateParameterNames = true; } } else if (!options.FirstRestricted.HasValue) { if (name != null && Scanner.IsRestrictedWord(name)) { options.FirstRestricted = param; options.Message = "Parameter name eval or arguments is not allowed in strict mode"; } else if (name != null && Scanner.IsStrictModeReservedWord(name)) { options.FirstRestricted = param; options.Message = "Use of future reserved word in strict mode"; } else if (options.ParamSetContains(name)) { options.Stricted = param; options.HasDuplicateParameterNames = true; } } options.ParamSetAdd(name); } private RestElement ParseRestElement(ref ArrayList parameters) { Marker marker = CreateNode(); Expect("..."); Node argument = ParsePattern(ref parameters); if (Match("=")) { ThrowError("Unexpected token ="); } if (!Match(")")) { ThrowError("Rest parameter must be last formal parameter"); } return Finalize(in marker, new RestElement(argument)); } private void ParseFormalParameter(ref ParsedParameters options) { ArrayList parameters = _parseVariableBindingParameters.GetValueOrDefault(); _parseVariableBindingParameters = null; parameters.Clear(); Node node = (Match("...") ? ParseRestElement(ref parameters) : ParsePatternWithDefault(ref parameters)); for (int i = 0; i < parameters.Count; i++) { ValidateParam2(ref options, parameters[i], (string)parameters[i].Value); } options.Simple = options.Simple && node is Identifier; options.Parameters.Push(node); _parseVariableBindingParameters = parameters; } private ParsedParameters ParseFormalParameters(Token? firstRestricted = null) { ParsedParameters parsedParameters = new ParsedParameters(); parsedParameters.Simple = true; parsedParameters.FirstRestricted = firstRestricted; ParsedParameters options = parsedParameters; Expect("("); if (!Match(")")) { options.Parameters = default(ArrayList); while (_lookahead.Type != TokenType.EOF) { ParseFormalParameter(ref options); if (Match(")")) { break; } Expect(","); if (Match(")")) { break; } } } Expect(")"); if (options.HasDuplicateParameterNames && (_context.Strict || !options.Simple)) { ThrowError("Duplicate parameter name not allowed in this context"); } parsedParameters = new ParsedParameters(); parsedParameters.Simple = options.Simple; parsedParameters.Parameters = options.Parameters; parsedParameters.Stricted = options.Stricted; parsedParameters.FirstRestricted = options.FirstRestricted; parsedParameters.Message = options.Message; return parsedParameters; } private bool MatchAsyncFunction() { if (MatchContextualKeyword("async")) { return ValidateMatch(_scanner, _context); } return false; [MethodImpl(MethodImplOptions.NoInlining)] static bool ValidateMatch(Scanner scanner, Context context) { ScannerState state = scanner.SaveState(); scanner.ScanCommentsInternal(); Token token = scanner.Lex(new LexOptions(context)); scanner.RestoreState(in state); if (state.LineNumber == token.LineNumber && token.Type == TokenType.Keyword) { return (string)token.Value == "function"; } return false; } } private FunctionDeclaration ParseFunctionDeclaration(bool identifierIsOptional = false) { Marker marker = CreateNode(); bool flag = MatchContextualKeyword("async"); if (flag) { if (_context.InIteration) { TolerateError("Async functions can only be declared at the top level or inside a block."); } NextToken(); } ExpectKeyword("function"); bool flag2 = Match("*"); if (flag2) { NextToken(); } string message = null; Identifier id = null; Token? firstRestricted = null; if (!identifierIsOptional || !Match("(")) { Token token = _lookahead; id = ParseVariableIdentifier(); string text = (string)token.Value; if (_context.Strict) { if (text != null && Scanner.IsRestrictedWord(text)) { ThrowUnexpectedToken(in token, "Function name may not be eval or arguments in strict mode"); } } else if (text != null && Scanner.IsRestrictedWord(text)) { firstRestricted = token; message = "Function name may not be eval or arguments in strict mode"; } else if (text != null && Scanner.IsStrictModeReservedWord(text)) { firstRestricted = token; message = "Use of future reserved word in strict mode"; } } bool inClassStaticBlock = _context.InClassStaticBlock; bool isAsync = _context.IsAsync; bool allowYield = _context.AllowYield; _context.InClassStaticBlock = false; _context.IsAsync = flag; _context.AllowYield = !flag2; ParsedParameters parsedParameters = ParseFormalParameters(firstRestricted); NodeList parameters = NodeList.From(ref parsedParameters.Parameters); Token? stricted = parsedParameters.Stricted; firstRestricted = parsedParameters.FirstRestricted; if (parsedParameters.Message != null) { message = parsedParameters.Message; } bool strict = _context.Strict; bool allowStrictDirective = _context.AllowStrictDirective; _context.AllowStrictDirective = parsedParameters.Simple; BlockStatement body = ParseFunctionSourceElements(); if (_context.Strict && firstRestricted.HasValue) { ThrowUnexpectedToken(firstRestricted.Value, message); } if (_context.Strict && stricted.HasValue) { ThrowUnexpectedToken(stricted.Value, message); } bool strict2 = _context.Strict; _context.AllowStrictDirective = allowStrictDirective; _context.Strict = strict; _context.IsAsync = isAsync; _context.AllowYield = allowYield; _context.InClassStaticBlock = inClassStaticBlock; return Finalize(in marker, new FunctionDeclaration(id, in parameters, body, flag2, strict2, flag)); } private FunctionExpression ParseFunctionExpression() { Marker marker = CreateNode(); bool flag = MatchContextualKeyword("async"); if (flag) { NextToken(); } ExpectKeyword("function"); bool flag2 = Match("*"); if (flag2) { NextToken(); } string message = null; Expression expression = null; Token? firstRestricted = null; bool inClassStaticBlock = _context.InClassStaticBlock; bool isAsync = _context.IsAsync; bool allowYield = _context.AllowYield; _context.InClassStaticBlock = false; _context.IsAsync = flag; _context.AllowYield = !flag2; if (!Match("(")) { Token token = _lookahead; expression = ((!_context.Strict && !flag2 && MatchKeyword("yield")) ? ParseIdentifierName() : ParseVariableIdentifier()); if (_context.Strict) { if (token.Value != null && Scanner.IsRestrictedWord((string)token.Value)) { ThrowUnexpectedToken(in token, "Function name may not be eval or arguments in strict mode"); } } else if (token.Value != null && Scanner.IsRestrictedWord((string)token.Value)) { firstRestricted = token; message = "Function name may not be eval or arguments in strict mode"; } else if (token.Value != null && Scanner.IsStrictModeReservedWord((string)token.Value)) { firstRestricted = token; message = "Use of future reserved word in strict mode"; } } ParsedParameters parsedParameters = ParseFormalParameters(firstRestricted); NodeList parameters = NodeList.From(ref parsedParameters.Parameters); Token? stricted = parsedParameters.Stricted; firstRestricted = parsedParameters.FirstRestricted; if (parsedParameters.Message != null) { message = parsedParameters.Message; } bool strict = _context.Strict; bool allowStrictDirective = _context.AllowStrictDirective; _context.AllowStrictDirective = parsedParameters.Simple; BlockStatement body = ParseFunctionSourceElements(); if (_context.Strict && firstRestricted.HasValue) { ThrowUnexpectedToken(firstRestricted.Value, message); } if (_context.Strict && stricted.HasValue) { ThrowUnexpectedToken(stricted.Value, message); } bool strict2 = _context.Strict; _context.Strict = strict; _context.AllowStrictDirective = allowStrictDirective; _context.IsAsync = isAsync; _context.AllowYield = allowYield; _context.InClassStaticBlock = inClassStaticBlock; return Finalize(in marker, new FunctionExpression((Identifier)expression, in parameters, body, flag2, strict2, flag)); } private ExpressionStatement ParseDirective() { Token lookahead = _lookahead; string text = null; Marker marker = CreateNode(); Expression expression = ParseExpression(); if (expression.Type == Nodes.Literal) { text = _scanner._source.Between(lookahead.Start + 1, lookahead.End - 1).ToInternedString(ref _scanner._stringPool); } ConsumeSemicolon(); return Finalize(in marker, (text != null) ? new Directive(expression, text) : new ExpressionStatement(expression)); } private ArrayList ParseDirectivePrologues() { Token? token = null; ArrayList result = default(ArrayList); while (true) { Token token2 = _lookahead; if (!token.HasValue && token2.OctalKind != LegacyOctalKind.None) { token = token2; } if (token2.Type != TokenType.StringLiteral) { break; } ExpressionStatement expressionStatement = ParseDirective(); result.Push(expressionStatement); string text = (expressionStatement as Directive)?.Value; if (text == null) { break; } if (text == "use strict") { _context.Strict = true; if (!_context.AllowStrictDirective) { TolerateUnexpectedToken(in token2, "Illegal 'use strict' directive in function with non-simple parameter list"); } } } if (_context.Strict && token.HasValue) { TolerateUnexpectedToken(token.Value, (token.Value.OctalKind == LegacyOctalKind.Escaped8or9) ? "\\8 and \\9 are not allowed in strict mode." : "Octal literals are not allowed in strict mode."); } return result; } private static bool QualifiedPropertyName(in Token token) { switch (token.Type) { case TokenType.BooleanLiteral: case TokenType.Identifier: case TokenType.Keyword: case TokenType.NullLiteral: case TokenType.NumericLiteral: case TokenType.StringLiteral: return true; case TokenType.Punctuator: return "[".Equals(token.Value) || "#".Equals(token.Value); default: return false; } } private FunctionExpression ParseGetterMethod() { FunctionExpression functionExpression = ParseMethod(isAsync: false, generator: false); if (functionExpression.Params.Count > 0) { TolerateError("Getter must not have any formal parameters"); } return functionExpression; } private FunctionExpression ParseSetterMethod() { FunctionExpression functionExpression = ParseMethod(isAsync: false, generator: false); ref readonly NodeList reference = ref functionExpression.Params; if (reference.Count != 1) { TolerateError("Setter must have exactly one formal parameter"); return functionExpression; } if (reference[0] is RestElement) { TolerateError("Setter function argument must not be a rest parameter"); } return functionExpression; } private FunctionExpression ParseGeneratorMethod(bool isAsync) { return ParseMethod(isAsync, generator: true); } private FunctionExpression ParseMethod(bool isAsync, bool generator) { Marker marker = CreateNode(); bool inClassStaticBlock = _context.InClassStaticBlock; bool isAsync2 = _context.IsAsync; bool allowYield = _context.AllowYield; bool allowSuperAccess = _context.AllowSuperAccess; bool allowSuperCall = _context.AllowSuperCall; _context.InClassStaticBlock = false; _context.IsAsync = isAsync; _context.AllowYield = true; _context.AllowSuperAccess = true; _context.AllowSuperCall = false; ParsedParameters parameters = ParseFormalParameters(); _context.AllowYield = !generator; bool hasStrictDirective; BlockStatement body = ParsePropertyMethod(ref parameters, out hasStrictDirective); _context.IsAsync = isAsync2; _context.AllowYield = allowYield; _context.AllowSuperAccess = allowSuperAccess; _context.AllowSuperCall = allowSuperCall; _context.InClassStaticBlock = inClassStaticBlock; return Finalize(in marker, new FunctionExpression(null, NodeList.From(ref parameters.Parameters), body, generator, hasStrictDirective, isAsync)); } [StringMatcher(new string[] { "[", "(", "{", "+", "-", "!", "~", "++", "--", "/", "/=" })] private static bool IsPunctuatorExpressionStart(string input) { return input.Length switch { 1 => input[0] switch { '-' => input == "-", '!' => input == "!", '(' => input == "(", '[' => input == "[", '{' => input == "{", '/' => input == "/", '+' => input == "+", '~' => input == "~", _ => false, }, 2 => input[0] switch { '-' => input == "--", '/' => input == "/=", '+' => input == "++", _ => false, }, _ => false, }; } [StringMatcher(new string[] { "class", "delete", "function", "import", "new", "super", "this", "typeof", "void", "yield" })] private static bool IsKeywordExpressionStart(string input) { return input.Length switch { 3 => input == "new", 4 => input[0] switch { 't' => input == "this", 'v' => input == "void", _ => false, }, 5 => input[0] switch { 'c' => input == "class", 's' => input == "super", 'y' => input == "yield", _ => false, }, 6 => input[0] switch { 'd' => input == "delete", 'i' => input == "import", 't' => input == "typeof", _ => false, }, 8 => input == "function", _ => false, }; } private protected virtual bool IsStartOfExpression() { bool result = true; if (!(_lookahead.Value is string text)) { return result; } if (_lookahead.Type == TokenType.Punctuator) { result = IsPunctuatorExpressionStart(text); } else if (_lookahead.Type == TokenType.Keyword) { result = IsKeywordExpressionStart(text) || (!_context.IsModule && text == "let"); } return result; } private YieldExpression ParseYieldExpression() { Marker marker = CreateNode(); ExpectKeyword("yield"); Expression argument = null; bool flag = false; if (!_hasLineTerminator) { bool allowYield = _context.AllowYield; _context.AllowYield = false; flag = Match("*"); if (flag) { NextToken(); argument = ParseAssignmentExpression(); } else if (IsStartOfExpression()) { argument = ParseAssignmentExpression(); } _context.AllowYield = allowYield; } return Finalize(in marker, new YieldExpression(argument, flag)); } private StaticBlock ParseStaticBlock() { Marker marker = CreateNode(); Expect("{"); bool inClassStaticBlock = _context.InClassStaticBlock; bool allowSuperAccess = _context.AllowSuperAccess; bool allowSuperCall = _context.AllowSuperCall; _context.InClassStaticBlock = true; _context.AllowSuperAccess = true; _context.AllowSuperCall = false; ArrayList arrayList = default(ArrayList); while (!Match("}")) { arrayList.Add(ParseStatementListItem()); } _context.AllowSuperAccess = allowSuperAccess; _context.AllowSuperCall = allowSuperCall; _context.InClassStaticBlock = inClassStaticBlock; Expect("}"); return Finalize(in marker, new StaticBlock(NodeList.From(ref arrayList))); } private Decorator ParseDecorator() { Marker marker = CreateNode(); Expect("@"); bool strict = _context.Strict; bool allowYield = _context.AllowYield; bool isAsync = _context.IsAsync; _context.Strict = false; _context.AllowYield = true; _context.IsAsync = false; MemberAccessContext memberAccessContext = _context.MemberAccessContext; _context.MemberAccessContext = MemberAccessContext.Decorator; Expression expression = IsolateCoverGrammar(_parseLeftHandSideExpressionAllowCall); _context.MemberAccessContext = memberAccessContext; _context.Strict = strict; _context.AllowYield = allowYield; _context.IsAsync = isAsync; if (Match(";")) { ThrowError("Decorators must not be followed by a semicolon."); } return Finalize(in marker, new Decorator(expression)); } private ArrayList ParseDecorators() { ArrayList result = default(ArrayList); while (Match("@")) { result.Add(ParseDecorator()); } return result; } private ClassElement ParseClassElement(bool hasSuperClass, ref bool hasConstructor) { Marker marker = CreateNode(); ArrayList arrayList = ParseDecorators(); PropertyKind propertyKind = PropertyKind.None; bool flag = false; bool flag2 = false; bool flag3 = false; bool flag4 = false; bool flag5 = false; bool flag6 = false; bool flag7 = false; flag4 = Match("*"); Token token; Expression key; if (flag4) { NextToken(); propertyKind = PropertyKind.Method; } else { TokenType type = _lookahead.Type; if (type - 3 <= TokenType.BooleanLiteral) { if ((string)_lookahead.Value == "static") { token = _lookahead; key = ParseObjectPropertyKey(); if (Match("{")) { return ParseStaticBlock(); } flag4 = Match("*"); if (flag4) { NextToken(); flag2 = true; flag7 = token.IsEscaped("static"); propertyKind = PropertyKind.Method; goto IL_0250; } if (!QualifiedPropertyName(in _lookahead)) { goto IL_0284; } flag7 = token.IsEscaped("static"); flag2 = true; } type = _lookahead.Type; if (type - 3 <= TokenType.BooleanLiteral) { if (MatchContextualKeyword("async") && _lookahead.IsEscaped("async")) { TolerateError("Keyword must not contain escaped characters"); } switch ((string)_lookahead.Value) { case "async": break; case "get": case "set": goto IL_01ee; case "accessor": goto IL_0227; default: goto IL_0250; } token = _lookahead; key = ParseObjectPropertyKey(); if (_hasLineTerminator) { goto IL_0284; } flag4 = Match("*"); if (flag4) { NextToken(); flag3 = true; propertyKind = PropertyKind.Method; } else { if (!QualifiedPropertyName(in _lookahead)) { goto IL_0284; } flag3 = true; } } } } goto IL_0250; IL_0250: token = _lookahead; flag = Match("["); flag5 = Match("#"); key = ((!flag5) ? ParseObjectPropertyKey() : ParsePrivateIdentifier()); goto IL_0284; IL_0227: token = _lookahead; key = ParseObjectPropertyKey(); if (QualifiedPropertyName(in _lookahead) && !_hasLineTerminator) { flag6 = true; propertyKind = PropertyKind.Property; goto IL_0250; } goto IL_0284; IL_0284: if (propertyKind == PropertyKind.None) { propertyKind = (Match("(") ? PropertyKind.Method : PropertyKind.Property); } if (flag2 && flag7) { TolerateError("Keyword must not contain escaped characters"); } if (!flag && !flag5) { if (flag2) { if (IsPropertyKey(key, "prototype")) { ThrowUnexpectedToken(in token, "Classes may not have static property named prototype"); } else if (IsPropertyKey(key, "constructor") && propertyKind == PropertyKind.Property && !flag6) { ThrowUnexpectedToken(in token, "Classes may not have a field named 'constructor'"); } } else if (IsPropertyKey(key, "constructor")) { if (propertyKind == PropertyKind.Property && !flag6) { ThrowUnexpectedToken(in token, "Classes may not have a field named 'constructor'"); } else { bool flag8 = (uint)(propertyKind - 1) <= 1u; if (flag8 || (propertyKind == PropertyKind.Property && flag6)) { ThrowUnexpectedToken(in token, "Class constructor may not be an accessor"); } else if (flag4) { TolerateUnexpectedToken(in token, "Class constructor may not be a generator"); } else if (flag3) { TolerateUnexpectedToken(in token, "Class constructor may not be an async method"); } } if (hasConstructor) { ThrowUnexpectedToken(in token, "A class may only have one constructor"); } else { hasConstructor = true; } propertyKind = PropertyKind.Constructor; } } FunctionExpression functionExpression; Expression value; switch (propertyKind) { case PropertyKind.Set: functionExpression = ParseSetterMethod(); goto IL_03de; case PropertyKind.Get: functionExpression = ParseGetterMethod(); goto IL_03de; case PropertyKind.Constructor: case PropertyKind.Method: value = ((!flag4) ? ParsePropertyMethodFunction(flag3, flag4, propertyKind == PropertyKind.Constructor && hasSuperClass) : ParseGeneratorMethod(flag3)); return Finalize(in marker, new MethodDefinition(key, flag, (FunctionExpression)value, propertyKind, flag2, NodeList.From(ref arrayList))); case PropertyKind.Property: if (Match("=")) { NextToken(); bool allowSuperAccess = _context.AllowSuperAccess; bool allowSuperCall = _context.AllowSuperCall; bool inClassFieldInit = _context.InClassFieldInit; _context.AllowSuperAccess = true; _context.AllowSuperCall = false; _context.InClassFieldInit = true; value = IsolateCoverGrammar(_parseAssignmentExpression); _context.InClassFieldInit = inClassFieldInit; _context.AllowSuperAccess = allowSuperAccess; _context.AllowSuperCall = allowSuperCall; } else { value = null; } ConsumeSemicolon(); if (flag6) { return Finalize(in marker, new AccessorProperty(key, flag, value, flag2, NodeList.From(ref arrayList))); } return Finalize(in marker, new PropertyDefinition(key, flag, value, flag2, NodeList.From(ref arrayList))); default: { return ThrowError("Unknown property kind '{0}'", new object[1] { propertyKind }); } IL_03de: value = functionExpression; return Finalize(in marker, new MethodDefinition(key, flag, (FunctionExpression)value, propertyKind, flag2, NodeList.From(ref arrayList))); } IL_01ee: token = _lookahead; key = ParseObjectPropertyKey(); if (QualifiedPropertyName(in _lookahead)) { propertyKind = ((((string)token.Value)[0] == 'g') ? PropertyKind.Get : PropertyKind.Set); goto IL_0250; } goto IL_0284; } private ArrayList ParseClassElementList(bool hasSuperClass) { ArrayList result = default(ArrayList); bool hasConstructor = false; Expect("{"); while (!Match("}")) { if (Match(";")) { NextToken(); } else { result.Push(ParseClassElement(hasSuperClass, ref hasConstructor)); } } Expect("}"); return result; } private ClassBody ParseClassBody(bool hasSuperClass) { Marker marker = CreateNode(); bool inClassBody = _context.InClassBody; _context.InClassBody = true; ArrayList arrayList = ParseClassElementList(hasSuperClass); _context.InClassBody = inClassBody; return Finalize(in marker, new ClassBody(NodeList.From(ref arrayList))); } private ClassDeclaration ParseClassDeclarationCore(in Marker node, bool identifierIsOptional = false) { bool strict = _context.Strict; _context.Strict = true; ExpectKeyword("class"); Identifier id = ((identifierIsOptional && _lookahead.Type != TokenType.Identifier) ? null : ParseVariableIdentifier()); Expression expression = null; if (MatchKeyword("extends")) { NextToken(); MemberAccessContext memberAccessContext = _context.MemberAccessContext; _context.MemberAccessContext = MemberAccessContext.Unknown; expression = IsolateCoverGrammar(_parseLeftHandSideExpressionAllowCall); _context.MemberAccessContext = memberAccessContext; } ClassBody body = ParseClassBody(expression != null); _context.Strict = strict; return Finalize(in node, new ClassDeclaration(id, expression, body, NodeList.From(ref _context.Decorators))); } private ClassDeclaration ParseClassDeclaration(bool identifierIsOptional = false) { return ParseClassDeclarationCore(CreateNode(), identifierIsOptional); } private ClassDeclaration ParseDecoratedClassDeclaration(bool identifierIsOptional = false) { Marker node = CreateNode(); ArrayList decorators = _context.Decorators; _context.Decorators = ParseDecorators(); ClassDeclaration result = ParseClassDeclarationCore(in node, identifierIsOptional); _context.Decorators = decorators; return result; } private ClassExpression ParseClassExpression() { Marker marker = CreateNode(); bool strict = _context.Strict; _context.Strict = true; ExpectKeyword("class"); Identifier id = ((_lookahead.Type == TokenType.Identifier) ? ParseVariableIdentifier() : null); Expression expression = null; if (MatchKeyword("extends")) { NextToken(); MemberAccessContext memberAccessContext = _context.MemberAccessContext; _context.MemberAccessContext = MemberAccessContext.Unknown; expression = IsolateCoverGrammar(_parseLeftHandSideExpressionAllowCall); _context.MemberAccessContext = memberAccessContext; } ClassBody body = ParseClassBody(expression != null); _context.Strict = strict; return Finalize(in marker, new ClassExpression(id, expression, body, NodeList.From(ref _context.Decorators))); } private Literal ParseModuleSpecifier() { Marker marker = CreateNode(); if (_lookahead.Type != TokenType.StringLiteral) { ThrowError("Unexpected token"); } Token token = NextToken(); string tokenRaw = GetTokenRaw(in token); return Finalize(in marker, new Literal((string)token.Value, tokenRaw)); } private ArrayList ParseImportAttributes() { ArrayList result = default(ArrayList); if (!MatchKeyword("with")) { return result; } NextToken(); Expect("{"); HashSet hashSet = new HashSet(); while (!Match("}")) { ImportAttribute importAttribute = ParseImportAttribute(); string text = string.Empty; Expression key = importAttribute.Key; if (!(key is Identifier identifier)) { if (key is Literal literal) { text = literal.StringValue; } } else { text = identifier.Name; } if (!hashSet.Add(text)) { ThrowError("Import attributes has duplicate key '{0}'", text); } result.Add(importAttribute); if (!Match("}")) { ExpectCommaSeparator(); } } Expect("}"); return result; } private ImportAttribute ParseImportAttribute() { Marker marker = CreateNode(); Expression key = ParseObjectPropertyKey(); if (!Match(":")) { ThrowUnexpectedToken(NextToken()); } NextToken(); Token token = NextToken(); string tokenRaw = GetTokenRaw(in token); Literal value = Finalize(in marker, new Literal((string)token.Value, tokenRaw)); return Finalize(in marker, new ImportAttribute(key, value)); } private ImportSpecifier ParseImportSpecifier() { Marker marker = CreateNode(); Expression imported; Identifier local; if (_lookahead.Type == TokenType.Identifier) { imported = (local = ParseVariableIdentifier(null, allowAwaitKeyword: true)); if (MatchContextualKeyword("as")) { NextToken(); local = ParseVariableIdentifier(); } } else { imported = ((_lookahead.Type == TokenType.StringLiteral) ? ((Expression)ParseModuleSpecifier()) : ((Expression)ParseIdentifierName())); if (MatchContextualKeyword("as")) { NextToken(); local = ParseVariableIdentifier(); } else { ThrowUnexpectedToken(NextToken()); local = null; } } return Finalize(in marker, new ImportSpecifier(local, imported)); } private ArrayList ParseNamedImports() { Expect("{"); ArrayList result = default(ArrayList); while (!Match("}")) { result.Push(ParseImportSpecifier()); if (!Match("}")) { Expect(","); } } Expect("}"); return result; } private ImportDefaultSpecifier ParseImportDefaultSpecifier() { Marker marker = CreateNode(); Identifier local = ParseIdentifierName(); return Finalize(in marker, new ImportDefaultSpecifier(local)); } private ImportNamespaceSpecifier ParseImportNamespaceSpecifier() { Marker marker = CreateNode(); Expect("*"); if (!MatchContextualKeyword("as")) { ThrowError("Unexpected token"); } NextToken(); Identifier local = ParseIdentifierName(); return Finalize(in marker, new ImportNamespaceSpecifier(local)); } private ImportDeclaration ParseImportDeclaration() { if (_context.InFunctionBody) { ThrowError("Unexpected token"); } Marker marker = CreateNode(); ExpectKeyword("import"); ArrayList arrayList = default(ArrayList); Literal source; if (_lookahead.Type == TokenType.StringLiteral) { source = ParseModuleSpecifier(); } else { if (Match("{")) { arrayList.AddRange(ParseNamedImports()); } else if (Match("*")) { arrayList.Push(ParseImportNamespaceSpecifier()); } else if (IsIdentifierName(in _lookahead) && !MatchKeyword("default")) { arrayList.Push(ParseImportDefaultSpecifier()); if (Match(",")) { NextToken(); if (Match("*")) { arrayList.Push(ParseImportNamespaceSpecifier()); } else if (Match("{")) { arrayList.AddRange(ParseNamedImports()); } else { ThrowUnexpectedToken(in _lookahead); } } } else { ThrowUnexpectedToken(NextToken()); } if (!MatchContextualKeyword("from")) { string messageFormat = ((_lookahead.Value != null) ? "Unexpected token {0}" : "Unexpected token"); ThrowError(messageFormat, _lookahead.Value); } NextToken(); source = ParseModuleSpecifier(); } ArrayList arrayList2 = ParseImportAttributes(); ConsumeSemicolon(); return Finalize(in marker, new ImportDeclaration(NodeList.From(ref arrayList), source, NodeList.From(ref arrayList2))); } private ExportSpecifier ParseExportSpecifier() { Marker marker = CreateNode(); Expression expression = ((_lookahead.Type == TokenType.StringLiteral) ? ((Expression)ParseModuleSpecifier()) : ((Expression)ParseIdentifierName())); Expression exported = expression; if (MatchContextualKeyword("as")) { NextToken(); exported = ((_lookahead.Type == TokenType.StringLiteral) ? ((Expression)ParseModuleSpecifier()) : ((Expression)ParseIdentifierName())); } return Finalize(in marker, new ExportSpecifier(expression, exported)); } private ExportDeclaration ParseExportDeclaration() { if (_context.InFunctionBody) { ThrowError("Unexpected token"); } Marker marker = CreateNode(); ExpectKeyword("export"); if (MatchKeyword("default")) { NextToken(); if (MatchKeyword("function")) { FunctionDeclaration declaration = ParseFunctionDeclaration(identifierIsOptional: true); return Finalize(in marker, new ExportDefaultDeclaration(declaration)); } if (MatchKeyword("class")) { ClassDeclaration declaration2 = ParseClassDeclaration(identifierIsOptional: true); return Finalize(in marker, new ExportDefaultDeclaration(declaration2)); } if (Match("@")) { ClassDeclaration declaration3 = ParseDecoratedClassDeclaration(identifierIsOptional: true); return Finalize(in marker, new ExportDefaultDeclaration(declaration3)); } if (MatchContextualKeyword("async")) { StatementListItem declaration4; if (MatchAsyncFunction()) { declaration4 = ParseFunctionDeclaration(identifierIsOptional: true); } else { declaration4 = ParseAssignmentExpression(); ConsumeSemicolon(); } return Finalize(in marker, new ExportDefaultDeclaration(declaration4)); } if (MatchContextualKeyword("from")) { ThrowError("Unexpected token {0}", _lookahead.Value); } Expression declaration5 = ParseAssignmentExpression(); ConsumeSemicolon(); return Finalize(in marker, new ExportDefaultDeclaration(declaration5)); } if (Match("*")) { NextToken(); Expression exported = null; if (MatchContextualKeyword("as")) { NextToken(); exported = ((_lookahead.Type == TokenType.StringLiteral) ? ((Expression)ParseModuleSpecifier()) : ((Expression)ParseIdentifierName())); } if (!MatchContextualKeyword("from")) { string messageFormat = ((_lookahead.Value != null) ? "Unexpected token {0}" : "Unexpected token"); ThrowError(messageFormat, _lookahead.Value); } NextToken(); Literal source = ParseModuleSpecifier(); ArrayList arrayList = ParseImportAttributes(); ConsumeSemicolon(); return Finalize(in marker, new ExportAllDeclaration(source, exported, NodeList.From(ref arrayList))); } if (_lookahead.Type == TokenType.Keyword) { StatementListItem node; switch (_lookahead.Value as string) { case "let": case "const": node = ParseLexicalDeclaration(); break; case "var": case "class": case "function": node = ParseStatementListItem(); break; default: node = ThrowUnexpectedToken(in _lookahead); break; } return Finalize(in marker, new ExportNamedDeclaration(node.As(), default(NodeList), null, default(NodeList))); } if (MatchAsyncFunction()) { FunctionDeclaration declaration6 = ParseFunctionDeclaration(); return Finalize(in marker, new ExportNamedDeclaration(declaration6, default(NodeList), null, default(NodeList))); } ArrayList arrayList2 = default(ArrayList); Literal source2 = null; bool flag = false; ArrayList arrayList3 = default(ArrayList); Expect("{"); while (!Match("}")) { flag = flag || MatchKeyword("default"); arrayList2.Push(ParseExportSpecifier()); if (!Match("}")) { Expect(","); } } Expect("}"); if (MatchContextualKeyword("from")) { NextToken(); source2 = ParseModuleSpecifier(); arrayList3 = ParseImportAttributes(); ConsumeSemicolon(); } else if (flag) { string messageFormat2 = ((_lookahead.Value != null) ? "Unexpected token {0}" : "Unexpected token"); ThrowError(messageFormat2, _lookahead.Value); } else { ConsumeSemicolon(); } return Finalize(in marker, new ExportNamedDeclaration(null, NodeList.From(ref arrayList2), source2, NodeList.From(ref arrayList3))); } [DoesNotReturn] internal void ThrowError(string messageFormat, params object?[] values) { throw CreateError(messageFormat, values).ToException(); } [DoesNotReturn] internal T ThrowError(string messageFormat, params object?[] values) { throw CreateError(messageFormat, values).ToException(); } private ParseError CreateError(string messageFormat, params object?[] values) { string description = string.Format(CultureInfo.InvariantCulture, messageFormat, values); int index = _lastMarker.Index; int line = _lastMarker.Line; int column = _lastMarker.Column; return _errorHandler.CreateError(_scanner._sourceLocation, index, line, column, description); } private protected void TolerateError(string messageFormat, params object?[] values) { string description = string.Format(CultureInfo.InvariantCulture, messageFormat, values); int index = _lastMarker.Index; int lineNumber = _scanner._lineNumber; int column = _lastMarker.Column; _errorHandler.TolerateError(_scanner._sourceLocation, index, lineNumber, column, description, _tolerant); } private ParseError UnexpectedTokenError(in Token token, string? message = null) { string format = message ?? "Unexpected token {0}"; string arg; if (token.Type != TokenType.Unknown) { if (message == null) { format = ((token.Type == TokenType.EOF) ? "Unexpected end of input" : ((token.Type == TokenType.Identifier) ? "Unexpected identifier" : ((token.Type == TokenType.NumericLiteral) ? "Unexpected number" : ((token.Type == TokenType.StringLiteral) ? "Unexpected string" : ((token.Type == TokenType.Template) ? "Unexpected quasi {0}" : "Unexpected token {0}"))))); if (token.Type == TokenType.Keyword) { if (Scanner.IsFutureReservedWord((string)token.Value)) { format = "Unexpected reserved word"; } else if (_context.Strict && Scanner.IsStrictModeReservedWord((string)token.Value)) { format = "Use of future reserved word in strict mode"; } } } arg = ((token.Type == TokenType.Template) ? token.RawTemplate : Convert.ToString(token.Value, CultureInfo.InvariantCulture)); } else { arg = "ILLEGAL"; } format = string.Format(CultureInfo.InvariantCulture, format, arg); if (token.Type != TokenType.Unknown && token.LineNumber > 0) { int start = token.Start; int lineNumber = token.LineNumber; int num = _lastMarker.Index - _lastMarker.Column; int col = token.Start - num; return _errorHandler.CreateError(_scanner._sourceLocation, start, lineNumber, col, format); } int index = _lastMarker.Index; int line = _lastMarker.Line; int column = _lastMarker.Column; return _errorHandler.CreateError(_scanner._sourceLocation, index, line, column, format); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] private protected T ThrowUnexpectedToken(in Token token = default(Token), string? message = null) { throw UnexpectedTokenError(in token, message).ToException(); } [MethodImpl(MethodImplOptions.NoInlining)] [DoesNotReturn] private protected void ThrowUnexpectedToken(in Token token = default(Token), string? message = null) { throw UnexpectedTokenError(in token, message).ToException(); } private protected void TolerateUnexpectedToken(in Token token, string? message = null) { _errorHandler.Tolerate(UnexpectedTokenError(in token, message), _tolerant); } private void TolerateInvalidLoopStatement() { if (MatchKeyword("class") || MatchKeyword("function")) { TolerateUnexpectedToken(in _lookahead); } } } public class JsxParser : JavaScriptParser { private sealed class MetaJsxElement { public readonly Marker Node; public readonly JsxExpression Opening; public JsxExpression? Closing; public readonly List Children; public MetaJsxElement(in Marker node, JsxExpression opening, JsxExpression? closing, List children) { Node = node; Opening = opening; Closing = closing; Children = children; } } private static readonly Dictionary XHTMLEntities = new Dictionary(StringComparer.InvariantCulture) { { "quot", "\"" }, { "amp", "&" }, { "apos", "'" }, { "gt", ">" }, { "nbsp", "\u00a0" }, { "iexcl", "¡" }, { "cent", "¢" }, { "pound", "£" }, { "curren", "¤" }, { "yen", "¥" }, { "brvbar", "¦" }, { "sect", "§" }, { "uml", "\u00a8" }, { "copy", "©" }, { "ordf", "ª" }, { "laquo", "«" }, { "not", "¬" }, { "shy", "\u00ad" }, { "reg", "®" }, { "macr", "\u00af" }, { "deg", "°" }, { "plusmn", "±" }, { "sup2", "²" }, { "sup3", "³" }, { "acute", "\u00b4" }, { "micro", "µ" }, { "para", "¶" }, { "middot", "·" }, { "cedil", "\u00b8" }, { "sup1", "¹" }, { "ordm", "º" }, { "raquo", "»" }, { "frac14", "¼" }, { "frac12", "½" }, { "frac34", "¾" }, { "iquest", "¿" }, { "Agrave", "À" }, { "Aacute", "Á" }, { "Acirc", "Â" }, { "Atilde", "Ã" }, { "Auml", "Ä" }, { "Aring", "Å" }, { "AElig", "Æ" }, { "Ccedil", "Ç" }, { "Egrave", "È" }, { "Eacute", "É" }, { "Ecirc", "Ê" }, { "Euml", "Ë" }, { "Igrave", "Ì" }, { "Iacute", "Í" }, { "Icirc", "Î" }, { "Iuml", "Ï" }, { "ETH", "Ð" }, { "Ntilde", "Ñ" }, { "Ograve", "Ò" }, { "Oacute", "Ó" }, { "Ocirc", "Ô" }, { "Otilde", "Õ" }, { "Ouml", "Ö" }, { "times", "×" }, { "Oslash", "Ø" }, { "Ugrave", "Ù" }, { "Uacute", "Ú" }, { "Ucirc", "Û" }, { "Uuml", "Ü" }, { "Yacute", "Ý" }, { "THORN", "Þ" }, { "szlig", "ß" }, { "agrave", "à" }, { "aacute", "á" }, { "acirc", "â" }, { "atilde", "ã" }, { "auml", "ä" }, { "aring", "å" }, { "aelig", "æ" }, { "ccedil", "ç" }, { "egrave", "è" }, { "eacute", "é" }, { "ecirc", "ê" }, { "euml", "ë" }, { "igrave", "ì" }, { "iacute", "í" }, { "icirc", "î" }, { "iuml", "ï" }, { "eth", "ð" }, { "ntilde", "ñ" }, { "ograve", "ò" }, { "oacute", "ó" }, { "ocirc", "ô" }, { "otilde", "õ" }, { "ouml", "ö" }, { "divide", "÷" }, { "oslash", "ø" }, { "ugrave", "ù" }, { "uacute", "ú" }, { "ucirc", "û" }, { "uuml", "ü" }, { "yacute", "ý" }, { "thorn", "þ" }, { "yuml", "ÿ" }, { "OElig", "Œ" }, { "oelig", "œ" }, { "Scaron", "Š" }, { "scaron", "š" }, { "Yuml", "Ÿ" }, { "fnof", "ƒ" }, { "circ", "ˆ" }, { "tilde", "\u02dc" }, { "Alpha", "Α" }, { "Beta", "Β" }, { "Gamma", "Γ" }, { "Delta", "Δ" }, { "Epsilon", "Ε" }, { "Zeta", "Ζ" }, { "Eta", "Η" }, { "Theta", "Θ" }, { "Iota", "Ι" }, { "Kappa", "Κ" }, { "Lambda", "Λ" }, { "Mu", "Μ" }, { "Nu", "Ν" }, { "Xi", "Ξ" }, { "Omicron", "Ο" }, { "Pi", "Π" }, { "Rho", "Ρ" }, { "Sigma", "Σ" }, { "Tau", "Τ" }, { "Upsilon", "Υ" }, { "Phi", "Φ" }, { "Chi", "Χ" }, { "Psi", "Ψ" }, { "Omega", "Ω" }, { "alpha", "α" }, { "beta", "β" }, { "gamma", "γ" }, { "delta", "δ" }, { "epsilon", "ε" }, { "zeta", "ζ" }, { "eta", "η" }, { "theta", "θ" }, { "iota", "ι" }, { "kappa", "κ" }, { "lambda", "λ" }, { "mu", "μ" }, { "nu", "ν" }, { "xi", "ξ" }, { "omicron", "ο" }, { "pi", "π" }, { "rho", "ρ" }, { "sigmaf", "ς" }, { "sigma", "σ" }, { "tau", "τ" }, { "upsilon", "υ" }, { "phi", "φ" }, { "chi", "χ" }, { "psi", "ψ" }, { "omega", "ω" }, { "thetasym", "ϑ" }, { "upsih", "ϒ" }, { "piv", "ϖ" }, { "ensp", "\u2002" }, { "emsp", "\u2003" }, { "thinsp", "\u2009" }, { "zwnj", "\u200c" }, { "zwj", "\u200d" }, { "lrm", "\u200e" }, { "rlm", "\u200f" }, { "ndash", "–" }, { "mdash", "—" }, { "lsquo", "‘" }, { "rsquo", "’" }, { "sbquo", "‚" }, { "ldquo", "“" }, { "rdquo", "”" }, { "bdquo", "„" }, { "dagger", "†" }, { "Dagger", "‡" }, { "bull", "•" }, { "hellip", "…" }, { "permil", "‰" }, { "prime", "′" }, { "Prime", "″" }, { "lsaquo", "‹" }, { "rsaquo", "›" }, { "oline", "‾" }, { "frasl", "⁄" }, { "euro", "€" }, { "image", "ℑ" }, { "weierp", "℘" }, { "real", "ℜ" }, { "trade", "™" }, { "alefsym", "ℵ" }, { "larr", "←" }, { "uarr", "↑" }, { "rarr", "→" }, { "darr", "↓" }, { "harr", "↔" }, { "crarr", "↵" }, { "lArr", "⇐" }, { "uArr", "⇑" }, { "rArr", "⇒" }, { "dArr", "⇓" }, { "hArr", "⇔" }, { "forall", "∀" }, { "part", "∂" }, { "exist", "∃" }, { "empty", "∅" }, { "nabla", "∇" }, { "isin", "∈" }, { "notin", "∉" }, { "ni", "∋" }, { "prod", "∏" }, { "sum", "∑" }, { "minus", "−" }, { "lowast", "∗" }, { "radic", "√" }, { "prop", "∝" }, { "infin", "∞" }, { "ang", "∠" }, { "and", "∧" }, { "or", "∨" }, { "cap", "∩" }, { "cup", "∪" }, { "int", "∫" }, { "there4", "∴" }, { "sim", "∼" }, { "cong", "≅" }, { "asymp", "≈" }, { "ne", "≠" }, { "equiv", "≡" }, { "le", "≤" }, { "ge", "≥" }, { "sub", "⊂" }, { "sup", "⊃" }, { "nsub", "⊄" }, { "sube", "⊆" }, { "supe", "⊇" }, { "oplus", "⊕" }, { "otimes", "⊗" }, { "perp", "⊥" }, { "sdot", "⋅" }, { "lceil", "⌈" }, { "rceil", "⌉" }, { "lfloor", "⌊" }, { "rfloor", "⌋" }, { "loz", "◊" }, { "spades", "♠" }, { "clubs", "♣" }, { "hearts", "♥" }, { "diams", "♦" }, { "lang", "⟨" }, { "rang", "⟩" } }; public JsxParser() : this(JsxParserOptions.Default) { } public JsxParser(JsxParserOptions options) : base(options) { } private protected override Expression ParsePrimaryExpression() { if (!Match("<")) { return base.ParsePrimaryExpression(); } return ParseJsxRoot(); } private protected override bool IsStartOfExpression() { if (!Match("<")) { return base.IsStartOfExpression(); } return true; } private void StartJsx() { _scanner._index = _startMarker.Index; _scanner._lineNumber = _startMarker.Line; _scanner._lineStart = _startMarker.Index - _startMarker.Column; } private void FinishJsx() { NextToken(); } private void ReEnterJsx() { StartJsx(); ExpectJsx("}"); if (_tokens != null) { _tokens.RemoveAt(_tokens.Count - 1); } } private Marker CreateJsxNode() { CollectComments(); return new Marker(_scanner._index, _scanner._lineNumber, _scanner._index - _scanner._lineStart); } private Marker CreateJsxChildNode() { return new Marker(_scanner._index, _scanner._lineNumber, _scanner._index - _scanner._lineStart); } private string ScanXHTMLEntity(char quote) { string text = "&"; bool flag = true; bool flag2 = false; bool flag3 = false; bool flag4 = false; while (!_scanner.Eof() && flag && !flag2) { char c = _scanner._source[_scanner._index]; if (c == quote) { break; } flag2 = c == ';'; text += c; _scanner._index++; if (flag2) { continue; } switch (text.Length) { case 2: flag3 = c == '#'; break; case 3: if (flag3) { flag4 = c == 'x'; flag = flag4 || Character.IsDecimalDigit(c); flag3 = flag3 && !flag4; } break; default: flag = flag && (!flag3 || Character.IsDecimalDigit(c)) && (!flag4 || Character.IsHexDigit(c)); break; } } if (flag && flag2 && text.Length > 2) { string text2 = text.Substring(1, text.Length - 2); string value; if (flag3 && text2.Length > 1) { text = ((char)int.Parse(text2.AsSpan(1).ToParsable(), NumberStyles.None, CultureInfo.InvariantCulture)).ToString(); } else if (flag4 && text2.Length > 2) { text = ((char)int.Parse(text2.AsSpan(2).ToParsable(), NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture)).ToString(); } else if (!flag3 && !flag4 && XHTMLEntities.TryGetValue(text2, out value)) { text = value; } } return text; } private Token LexJsx() { int num = _scanner._source[_scanner._index]; bool flag; switch (num) { case 47: case 58: case 60: case 61: case 62: case 123: case 125: flag = true; break; default: flag = false; break; } if (flag) { return Token.CreatePunctuator(_scanner._source[_scanner._index++].ToString(), _scanner._index - 1, _scanner._index, _scanner._lineNumber, _scanner._lineStart); } if ((num == 34 || num == 39) ? true : false) { int index = _scanner._index; char c = _scanner._source[_scanner._index++]; string text = ""; while (!_scanner.Eof()) { char c2 = _scanner._source[_scanner._index++]; if (c2 == c) { break; } text = ((c2 != '&') ? (text + c2) : (text + ScanXHTMLEntity(c))); } return Token.CreateStringLiteral(text, LegacyOctalKind.None, index, _scanner._index, _scanner._lineNumber, _scanner._lineStart); } switch (num) { case 46: { char num2 = _scanner._source[_scanner._index + 1]; char c4 = _scanner._source[_scanner._index + 2]; string text2 = ((num2 == '.' && c4 == '.') ? "..." : "."); int index3 = _scanner._index; _scanner._index += text2.Length; return Token.CreatePunctuator(text2, index3, _scanner._index, _scanner._lineNumber, _scanner._lineStart); } case 96: return Token.CreateTemplate(null, "", head: false, tail: false, ' ', _scanner._index, _scanner._index, _scanner._lineNumber, _scanner._lineStart); default: if (Character.IsIdentifierStart((char)num) && num != 92) { int index2 = _scanner._index; _scanner._index++; while (!_scanner.Eof()) { char c3 = _scanner._source[_scanner._index]; if (Character.IsIdentifierPart(c3) && c3 != '\\') { _scanner._index++; continue; } if (c3 != '-') { break; } _scanner._index++; } return JsxToken.CreateIdentifier(_scanner._source.Between(index2, _scanner._index).ToInternedString(ref _scanner._stringPool), index2, _scanner._index, _scanner._lineNumber, _scanner._lineStart); } return _scanner.Lex(); } } private SyntaxToken ConvertJsxToken(in Token token) { JsxTokenType jsxTokenType = token.JsxTokenType(); if (jsxTokenType != JsxTokenType.Unknown) { return FinalizeToken(token.Start, token.End, new JsxSyntaxToken(jsxTokenType, GetTokenRaw(in token))); } return ConvertToken(in token); } private Token NextJsxToken() { CollectComments(); _startMarker = _scanner.GetMarker(); Token token = LexJsx(); _lastMarker = _scanner.GetMarker(); if (_tokens != null) { _tokens.Add(ConvertJsxToken(in token)); } return token; } private Token NextJsxText() { _startMarker = _scanner.GetMarker(); int index = _scanner._index; string text = ""; while (!_scanner.Eof()) { char c = _scanner._source[_scanner._index]; if ((c == '<' || c == '{') ? true : false) { break; } _scanner._index++; text += c; if (Character.IsLineTerminator(c)) { _scanner._lineNumber++; if (c == '\r' && _scanner._source[_scanner._index] == '\n') { _scanner._index++; } _scanner._lineStart = _scanner._index; } } _lastMarker = _scanner.GetMarker(); Token token = JsxToken.CreateText(text, index, _scanner._index, _scanner._lineNumber, _scanner._lineStart); if (text.Length > 0 && _tokens != null) { _tokens.Add(ConvertJsxToken(in token)); } return token; } private Token PeekJsxToken() { ScannerState state = _scanner.SaveState(); _scanner.ScanCommentsInternal(); Token result = LexJsx(); _scanner.RestoreState(in state); return result; } private void ExpectJsx(string value) { Token token = NextJsxToken(); if (token.Type != TokenType.Punctuator || (token.Value is string text && text != value)) { ThrowUnexpectedToken(in token); } } private bool MatchJsx(string value) { Token token = PeekJsxToken(); if (token.Type == TokenType.Punctuator && token.Value is string text) { return text == value; } return false; } private JsxIdentifier ParseJsxIdentifier() { Marker marker = CreateJsxNode(); Token token = NextJsxToken(); if (token.JsxTokenType() != JsxTokenType.Identifier) { ThrowUnexpectedToken(in token); } return Finalize(in marker, new JsxIdentifier((string)token.Value)); } private JsxExpression ParseJsxElementName() { Marker marker = CreateJsxNode(); JsxExpression jsxExpression = ParseJsxIdentifier(); if (MatchJsx(":")) { JsxIdentifier jsxIdentifier = (JsxIdentifier)jsxExpression; ExpectJsx(":"); JsxIdentifier name = ParseJsxIdentifier(); jsxExpression = Finalize(in marker, new JsxNamespacedName(jsxIdentifier, name)); } else if (MatchJsx(".")) { while (MatchJsx(".")) { JsxExpression obj = jsxExpression; ExpectJsx("."); JsxIdentifier property = ParseJsxIdentifier(); jsxExpression = Finalize(in marker, new JsxMemberExpression(obj, property)); } } return jsxExpression; } private JsxExpression ParseJsxAttributeName() { Marker marker = CreateJsxNode(); JsxExpression jsxExpression = ParseJsxIdentifier(); if (MatchJsx(":")) { JsxIdentifier jsxIdentifier = (JsxIdentifier)jsxExpression; ExpectJsx(":"); JsxIdentifier name = ParseJsxIdentifier(); return Finalize(in marker, new JsxNamespacedName(jsxIdentifier, name)); } return jsxExpression; } private Literal ParseJsxStringLiteralAttribute() { Marker marker = CreateJsxNode(); Token token = NextJsxToken(); if (token.Type != TokenType.StringLiteral) { ThrowUnexpectedToken(in token); } string tokenRaw = GetTokenRaw(in token); return Finalize(in marker, new Literal((string)token.Value, tokenRaw)); } private JsxExpressionContainer ParseJsxExpressionAttribute() { Marker marker = CreateJsxNode(); ExpectJsx("{"); FinishJsx(); if (Match("}")) { TolerateError("JSX attributes must only be assigned a non-empty expression"); } Expression expression = ParseAssignmentExpression(); ReEnterJsx(); return Finalize(in marker, new JsxExpressionContainer(expression)); } private Expression ParseJsxAttributeValue() { if (MatchJsx("{")) { return ParseJsxExpressionAttribute(); } if (!MatchJsx("<")) { return ParseJsxStringLiteralAttribute(); } return ParseJsxElement(); } private JsxAttribute ParseJsxNameValueAttribute() { Marker marker = CreateJsxNode(); JsxExpression name = ParseJsxAttributeName(); Expression value = null; if (MatchJsx("=")) { ExpectJsx("="); value = ParseJsxAttributeValue(); } return Finalize(in marker, new JsxAttribute(name, value)); } private JsxSpreadAttribute ParseJsxSpreadAttribute() { Marker marker = CreateJsxNode(); ExpectJsx("{"); ExpectJsx("..."); FinishJsx(); Expression argument = ParseAssignmentExpression(); ReEnterJsx(); return Finalize(in marker, new JsxSpreadAttribute(argument)); } private NodeList ParseJsxAttributes() { List list = new List(); while (!MatchJsx("/") && !MatchJsx(">")) { JsxExpression item = (MatchJsx("{") ? ((JsxExpression)ParseJsxSpreadAttribute()) : ((JsxExpression)ParseJsxNameValueAttribute())); list.Add(item); } return new NodeList(list); } private JsxExpression ParseJsxOpeningElement() { Marker marker = CreateJsxNode(); ExpectJsx("<"); if (MatchJsx(">")) { ExpectJsx(">"); return Finalize(in marker, new JsxOpeningFragment(selfClosing: false)); } JsxExpression name = ParseJsxElementName(); NodeList attributes = ParseJsxAttributes(); bool flag = MatchJsx("/"); if (flag) { ExpectJsx("/"); } ExpectJsx(">"); return Finalize(in marker, new JsxOpeningElement(name, flag, in attributes)); } private JsxExpression ParseJsxBoundartElement() { Marker marker = CreateJsxNode(); ExpectJsx("<"); if (MatchJsx("/")) { ExpectJsx("/"); if (MatchJsx(">")) { ExpectJsx(">"); return Finalize(in marker, new JsxClosingFragment()); } JsxExpression name = ParseJsxElementName(); ExpectJsx(">"); return Finalize(in marker, new JsxClosingElement(name)); } JsxExpression name2 = ParseJsxElementName(); NodeList attributes = ParseJsxAttributes(); bool flag = MatchJsx("/"); if (flag) { ExpectJsx("/"); } ExpectJsx(">"); return Finalize(in marker, new JsxOpeningElement(name2, flag, in attributes)); } private JsxEmptyExpression ParseJsxEmptyExpression() { Marker marker = CreateJsxChildNode(); CollectComments(); _lastMarker = _scanner.GetMarker(); return Finalize(in marker, new JsxEmptyExpression()); } private JsxExpressionContainer ParseJsxExpressionContainer() { Marker marker = CreateJsxNode(); ExpectJsx("{"); Expression expression; if (MatchJsx("}")) { expression = ParseJsxEmptyExpression(); ExpectJsx("}"); } else { FinishJsx(); expression = ParseAssignmentExpression(); ReEnterJsx(); } return Finalize(in marker, new JsxExpressionContainer(expression)); } private ArrayList ParseJsxChildren() { ArrayList result = default(ArrayList); while (!_scanner.Eof()) { Marker marker = CreateJsxChildNode(); Token token = NextJsxText(); if (token.Start < token.End) { string tokenRaw = GetTokenRaw(in token); JsxText item = Finalize(in marker, new JsxText((string)token.Value, tokenRaw)); result.Add(item); } if (_scanner.Eof()) { ThrowUnexpectedToken(Token.CreateEof(_scanner._index, _scanner._lineNumber, _scanner._lineStart)); } if (_scanner._source[_scanner._index] != '{') { break; } JsxExpressionContainer item2 = ParseJsxExpressionContainer(); result.Add(item2); } return result; } private MetaJsxElement ParseComplexJsxElement(MetaJsxElement el) { List list = new List(); while (!_scanner.Eof()) { el.Children.AddRange(ParseJsxChildren()); Marker node = CreateJsxChildNode(); JsxExpression jsxExpression = ParseJsxBoundartElement(); if (jsxExpression.Type == JsxNodeType.OpeningElement) { JsxOpeningElement jsxOpeningElement = (JsxOpeningElement)jsxExpression; if (jsxOpeningElement.SelfClosing) { JsxElement item = Finalize(in node, new JsxElement(jsxOpeningElement, NodeList.Create(Enumerable.Empty()), null)); el.Children.Add(item); } else { list.Add(el); el = new MetaJsxElement(in node, jsxOpeningElement, null, new List()); } } if (jsxExpression.Type == JsxNodeType.ClosingElement) { el.Closing = jsxExpression as JsxClosingElement; string qualifiedElementName = GetQualifiedElementName(((JsxOpeningElement)el.Opening).Name); string qualifiedElementName2 = GetQualifiedElementName(((JsxClosingElement)el.Closing).Name); if (qualifiedElementName != qualifiedElementName2) { TolerateError("Expected corresponding JSX closing tag for " + qualifiedElementName); } if (list.Count <= 0) { break; } JsxElement item2 = Finalize(in el.Node, new JsxElement(el.Opening, NodeList.Create(el.Children), el.Closing)); el = list[list.Count - 1]; el.Children.Add(item2); list.RemoveAt(list.Count - 1); } if (jsxExpression.Type == JsxNodeType.ClosingFragment) { el.Closing = jsxExpression as JsxClosingFragment; if (el.Opening.Type == JsxNodeType.OpeningFragment) { break; } TolerateError("Expected corresponding JSX closing tag for jsx fragment"); } } return el; } private JsxElement ParseJsxElement() { Marker node = CreateJsxNode(); JsxExpression jsxExpression = ParseJsxOpeningElement(); List list = new List(); JsxExpression jsxExpression2 = null; if (jsxExpression is JsxOpeningElement jsxOpeningElement) { if (!jsxOpeningElement.SelfClosing) { goto IL_0042; } } else if (jsxExpression is JsxOpeningFragment { SelfClosing: false }) { goto IL_0042; } bool flag = false; goto IL_004a; IL_0042: flag = true; goto IL_004a; IL_004a: if (flag) { MetaJsxElement metaJsxElement = ParseComplexJsxElement(new MetaJsxElement(in node, jsxExpression, jsxExpression2, list)); list = metaJsxElement.Children; jsxExpression2 = metaJsxElement.Closing; } return Finalize(in node, new JsxElement(jsxExpression, NodeList.Create(list), jsxExpression2)); } private JsxElement ParseJsxRoot() { if (_tokens != null) { _tokens.RemoveAt(_tokens.Count - 1); } StartJsx(); JsxElement result = ParseJsxElement(); FinishJsx(); return result; } private static string? GetQualifiedElementName(JsxExpression elementName) { switch (elementName.Type) { case JsxNodeType.Identifier: return ((JsxIdentifier)elementName).Name; case JsxNodeType.NamespacedName: { JsxNamespacedName jsxNamespacedName = (JsxNamespacedName)elementName; return GetQualifiedElementName(jsxNamespacedName.Namespace) + ":" + GetQualifiedElementName(jsxNamespacedName.Name); } case JsxNodeType.MemberExpression: { JsxMemberExpression jsxMemberExpression = (JsxMemberExpression)elementName; return GetQualifiedElementName(jsxMemberExpression.Object) + "." + GetQualifiedElementName(jsxMemberExpression.Property); } default: return null; } } } public record JsxParserOptions : ParserOptions { public new static readonly JsxParserOptions Default = new JsxParserOptions(); [CompilerGenerated] protected JsxParserOptions(JsxParserOptions original) : base(original) { } public JsxParserOptions() { } } public enum JsxTokenType { Unknown, Identifier, Text } public static class JsxToken { private sealed record JsxHolder : Token.ValueHolder { public JsxTokenType Type { get; init; } public JsxHolder(JsxTokenType Type, object? Value) { this.Type = Type; base..ctor(Value); } [CompilerGenerated] public void Deconstruct(out JsxTokenType Type, out object? Value) { Type = this.Type; Value = base.Value; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static Token CreateIdentifier(string value, int start, int end, int lineNumber, int lineStart) { return new Token(TokenType.Extension, new JsxHolder(Esprima.JsxTokenType.Identifier, value), start, end, lineNumber, lineStart); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static Token CreateText(string value, int start, int end, int lineNumber, int lineStart) { return new Token(TokenType.Extension, new JsxHolder(Esprima.JsxTokenType.Text, value), start, end, lineNumber, lineStart); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static JsxTokenType JsxTokenType(this in Token token) { if (token.Type != TokenType.Extension || !(token._value is JsxHolder jsxHolder)) { return Esprima.JsxTokenType.Unknown; } return jsxHolder.Type; } } public readonly struct Location : IEquatable { public readonly Position Start; public readonly Position End; public readonly string? Source; private static bool Validate(Position start, Position end, bool throwOnError) { if (start == default(Position) && end != default(Position)) { if (throwOnError) { throw new ArgumentOutOfRangeException("start", start, null); } return false; } if ((end == default(Position)) ? (start != default(Position)) : (end < start)) { if (throwOnError) { throw new ArgumentOutOfRangeException("end", end, null); } return false; } return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Location From(Position start, Position end, string? source = null) { Validate(start, end, throwOnError: true); return new Location(start, end, source); } internal Location(Position start, Position end) : this(start, end, null) { } internal Location(Position start, Position end, string? source) { Start = start; End = end; Source = source; } public Location WithPosition(Position start, Position end) { return From(start, end, Source); } public Location WithSource(string source) { return new Location(Start, End, source); } public override bool Equals(object obj) { if (obj is Location other) { return Equals(in other); } return false; } public bool Equals(in Location other) { if (Start.Equals(other.Start) && End.Equals(other.End)) { return string.Equals(Source, other.Source, StringComparison.Ordinal); } return false; } bool IEquatable.Equals(Location other) { return Equals(in other); } public static bool operator ==(in Location left, in Location right) { return left.Equals(in right); } public static bool operator !=(in Location left, in Location right) { return !left.Equals(in right); } public override int GetHashCode() { return (Start.GetHashCode() * 397) ^ (End.GetHashCode() * 397) ^ (Source?.GetHashCode() ?? 0); } public override string ToString() { string text = ((Start.Line == End.Line) ? ((Start.Column != End.Column) ? string.Format(CultureInfo.InvariantCulture, "[{0},{1}..{2})", Start.Line, Start.Column, End.Column) : string.Format(CultureInfo.InvariantCulture, "[{0},{1})", Start.Line, Start.Column)) : ((Start.Column != End.Column) ? string.Format(CultureInfo.InvariantCulture, "[{0},{1}..{2},{3})", Start.Line, Start.Column, End.Line, End.Column) : string.Format(CultureInfo.InvariantCulture, "[{0}..{1},{2})", Start.Line, End.Line, Start.Column))); if (Source == null) { return text; } return text + ": " + Source; } private static bool TryParseCore(ReadOnlySpan s, bool throwIfInvalid, out Location result) { int num; ReadOnlySpan readOnlySpan; int result2; int result3; int line; int result4; if (s[0] == '[' && (num = s.IndexOf(')')) >= 0 && ++num >= 5) { readOnlySpan = s.Slice(num); if (readOnlySpan.Length <= 0 || readOnlySpan[0] == ':') { s = s.Slice(1, num - 2); if (s.TryConsumeInt(out result2)) { if (s.Length >= 5 && s[0] == '.' && s[1] == '.') { result3 = -1; goto IL_0107; } if (s.Length >= 2 && s[0] == ',') { s = s.Slice(1); if (s.TryConsumeInt(out result3)) { if (s.Length == 0) { line = result2; result4 = result3; goto IL_0178; } if (s.Length >= 3 && s[0] == '.' && s[1] == '.') { goto IL_0107; } } } } } } goto IL_01e4; IL_0107: s = s.Slice(2); if (s.TryConsumeInt(out var result5)) { if (s.Length == 0) { line = result2; result4 = result5; goto IL_0178; } if (s.Length >= 2 && s[0] == ',') { line = result5; s = s.Slice(1); if (s.TryConsumeInt(out result4) && s.Length <= 0) { if (result3 < 0) { result3 = result4; } goto IL_0178; } } } goto IL_01e4; IL_01e4: result = default(Location); return false; IL_0178: if (readOnlySpan.Length > 0) { readOnlySpan = readOnlySpan.Slice(1).Trim(); if (readOnlySpan.Length == 0) { goto IL_01e4; } } Position start = new Position(result2, result3); Position end = new Position(line, result4); if (Validate(start, end, throwIfInvalid)) { result = new Location(start, end, (readOnlySpan.Length > 0) ? readOnlySpan.ToString() : null); return true; } goto IL_01e4; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryParse(ReadOnlySpan s, out Location result) { return TryParseCore(s, throwIfInvalid: false, out result); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryParse(string s, out Location result) { return TryParse(s.AsSpan(), out result); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Location Parse(ReadOnlySpan s) { if (!TryParseCore(s, throwIfInvalid: true, out var result)) { return EsprimaExceptionHelper.ThrowFormatException("Input string was not in a correct format."); } return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Location Parse(string s) { return Parse(s.AsSpan()); } [EditorBrowsable(EditorBrowsableState.Never)] public void Deconstruct(out Position start, out Position end) { start = Start; end = End; } [EditorBrowsable(EditorBrowsableState.Never)] public void Deconstruct(out Position start, out Position end, out string? source) { start = Start; end = End; source = Source; } } internal readonly record struct Marker(int Index, int Line, int Column); internal static class Messages { public const string ArgumentsNotAllowedInClassField = "'arguments' is not allowed in class field initializer or static initialization block"; public const string AsyncFunctionInSingleStatementContext = "Async functions can only be declared at the top level or inside a block."; public const string BadGetterArity = "Getter must not have any formal parameters"; public const string BadSetterArity = "Setter must have exactly one formal parameter"; public const string BadSetterRestParameter = "Setter function argument must not be a rest parameter"; public const string CannotUseAwaitInClassStaticBlock = "Cannot use await in class static initialization block"; public const string CannotUseImportMetaOutsideAModule = "Cannot use 'import.meta' outside a module"; public const string CannotUseImportWithNew = "Cannot use new with import"; public const string ConstructorIsAccessor = "Class constructor may not be an accessor"; public const string ConstructorIsAsync = "Class constructor may not be an async method"; public const string ConstructorIsField = "Classes may not have a field named 'constructor'"; public const string ConstructorIsGenerator = "Class constructor may not be a generator"; public const string DeclarationMissingInitializer = "Missing initializer in {0} declaration"; public const string DefaultRestParameter = "Unexpected token ="; public const string DefaultRestProperty = "Unexpected token ="; public const string DuplicateBinding = "Duplicate binding {0}"; public const string DuplicateConstructor = "A class may only have one constructor"; public const string DuplicateParameter = "Duplicate parameter name not allowed in this context"; public const string DuplicateProtoProperty = "Duplicate __proto__ fields are not allowed in object literals"; public const string DuplicateKeyInImportAttributes = "Import attributes has duplicate key '{0}'"; public const string ForInOfLoopInitializer = "'{0} loop variable declaration may not have an initializer"; public const string GeneratorInLegacyContext = "Generator declarations are not allowed in legacy contexts"; public const string IllegalBreak = "Illegal break statement"; public const string IllegalContinue = "Illegal continue statement"; public const string IllegalExportDeclaration = "Unexpected token"; public const string IllegalImportDeclaration = "Unexpected token"; public const string IllegalLanguageModeDirective = "Illegal 'use strict' directive in function with non-simple parameter list"; public const string IllegalReturn = "Illegal return statement"; public const string InvalidDecoratorMemberExpression = "Invalid decorator member expression"; public const string InvalidEscapedReservedWord = "Keyword must not contain escaped characters"; public const string InvalidHexEscapeSequence = "Invalid hexadecimal escape sequence"; public const string InvalidLHSInAssignment = "Invalid left-hand side in assignment"; public const string InvalidLHSInForIn = "Invalid left-hand side in for-in"; public const string InvalidLHSInForLoop = "Invalid left-hand side in for-loop"; public const string InvalidModuleSpecifier = "Unexpected token"; public const string InvalidOptionalChainFromNewExpression = "Invalid optional chain from new expression"; public const string InvalidRegExpFlags = "Invalid regular expression flags"; public const string InvalidTaggedTemplateOnOptionalChain = "Invalid tagged template on optional chain"; public const string InvalidUnicodeEscapeSequence = "Invalid Unicode escape sequence"; public const string LetInLexicalBinding = "let is disallowed as a lexically bound name"; public const string MissingFromClause = "Unexpected token"; public const string MultipleDefaultsInSwitch = "More than one default clause in switch statement"; public const string NewlineAfterThrow = "Illegal newline after throw"; public const string NewTargetNotAllowedHere = "new.target expression is not allowed here"; public const string NoAsAfterImportNamespace = "Unexpected token"; public const string NoCatchOrFinally = "Missing catch or finally after try"; public const string NoSemicolonAfterDecorator = "Decorators must not be followed by a semicolon."; public const string NumericSeparatorAfterLeadingZero = "Numeric separator can not be used after leading 0"; public const string NumericSeparatorNotAllowedHere = "Numeric separator is not allowed here"; public const string NumericSeparatorOneUnderscore = "Numeric separator must be exactly one underscore"; public const string ParameterAfterRestParameter = "Rest parameter must be last formal parameter"; public const string PrivateFieldNoDelete = "Private fields can not be deleted"; public const string PrivateFieldOutsideClass = "Private field '{0}' must be declared in an enclosing class"; public const string PropertyAfterRestProperty = "Unexpected token"; public const string Redeclaration = "{0} \"{1}\" has already been declared"; public const string RegExpDuplicateCaptureGroupName = "Invalid regular expression: /{0}/{1}: Duplicate capture group name"; public const string RegExpIncompleteQuantifier = "Invalid regular expression: /{0}/{1}: Incomplete quantifier"; public const string RegExpInvalidCaptureGroupName = "Invalid regular expression: /{0}/{1}: Invalid capture group name"; public const string RegExpInvalidEscape = "Invalid regular expression: /{0}/{1}: Invalid escape"; public const string RegExpInvalidDecimalEscape = "Invalid regular expression: /{0}/{1}: Invalid decimal escape"; public const string RegExpInvalidCharacterClass = "Invalid regular expression: /{0}/{1}: Invalid character class"; public const string RegExpInvalidClassEscape = "Invalid regular expression: /{0}/{1}: Invalid class escape"; public const string RegExpInvalidGroup = "Invalid regular expression: /{0}/{1}: Invalid group"; public const string RegExpInvalidPropertyName = "Invalid regular expression: /{0}/{1}: Invalid property name"; public const string RegExpInvalidPropertyNameInCharacterClass = "Invalid regular expression: /{0}/{1}: Invalid property name in character class"; public const string RegExpInvalidNamedCaptureReferenced = "Invalid regular expression: /{0}/{1}: Invalid named capture referenced"; public const string RegExpInvalidNamedReference = "Invalid regular expression: /{0}/{1}: Invalid named reference"; public const string RegExpInvalidQuantifier = "Invalid regular expression: /{0}/{1}: Invalid quantifier"; public const string RegExpInvalidUnicodeEscape = "Invalid regular expression: /{0}/{1}: Invalid Unicode escape"; public const string RegExpLoneQuantifierBrackets = "Invalid regular expression: /{0}/{1}: Lone quantifier brackets"; public const string RegExpNothingToRepeat = "Invalid regular expression: /{0}/{1}: Nothing to repeat"; public const string RegExpNumbersOutOfOrderInQuantifier = "Invalid regular expression: /{0}/{1}: numbers out of order in {{}} quantifier"; public const string RegExpRangeOutOfOrderInCharacterClass = "Invalid regular expression: /{0}/{1}: Range out of order in character class"; public const string RegExpUnmatchedOpenParen = "Invalid regular expression: /{0}/{1}: Unmatched ')'"; public const string RegExpUnterminatedCharacterClass = "Invalid regular expression: /{0}/{1}: Unterminated character class"; public const string RegExpUnterminatedGroup = "Invalid regular expression: /{0}/{1}: Unterminated group"; public const string StaticPrototype = "Classes may not have static property named prototype"; public const string StrictCatchVariable = "Catch variable may not be eval or arguments in strict mode"; public const string StrictDecimalWithLeadingZero = "Decimals with leading zeros are not allowed in strict mode."; public const string StrictDelete = "Delete of an unqualified identifier in strict mode."; public const string StrictEscape89 = "\\8 and \\9 are not allowed in strict mode."; public const string StrictFunction = "In strict mode code, functions can only be declared at top level or inside a block"; public const string StrictFunctionName = "Function name may not be eval or arguments in strict mode"; public const string StrictLHSAssignment = "Assignment to eval or arguments is not allowed in strict mode"; public const string StrictLHSPostfix = "Postfix increment/decrement may not have eval or arguments operand in strict mode"; public const string StrictLHSPrefix = "Prefix increment/decrement may not have eval or arguments operand in strict mode"; public const string StrictModeWith = "Strict mode code may not include a with statement"; public const string StrictOctalEscape = "Octal escape sequences are not allowed in strict mode."; public const string StrictOctalLiteral = "Octal literals are not allowed in strict mode."; public const string StrictParamName = "Parameter name eval or arguments is not allowed in strict mode"; public const string StrictReservedWord = "Use of future reserved word in strict mode"; public const string StrictVarName = "Variable name may not be eval or arguments in strict mode"; public const string TemplateEscape89 = "\\8 and \\9 are not allowed in template strings."; public const string TemplateOctalLiteral = "Octal literals are not allowed in template strings."; public const string UndefinedUnicodeCodePoint = "Undefined Unicode code-point"; public const string UnexpectedEOS = "Unexpected end of input"; public const string UnexpectedIdentifier = "Unexpected identifier"; public const string UnexpectedNumber = "Unexpected number"; public const string UnexpectedPrivateField = "Unexpected private field"; public const string UnexpectedReserved = "Unexpected reserved word"; public const string UnexpectedString = "Unexpected string"; public const string UnexpectedSuper = "'super' keyword unexpected here"; public const string UnexpectedTemplate = "Unexpected quasi {0}"; public const string UnexpectedToken = "Unexpected token {0}"; public const string UnexpectedTokenIllegal = "Unexpected token ILLEGAL"; public const string UnknownLabel = "Undefined label \"{0}\""; public const string UnterminatedRegExp = "Invalid regular expression: missing /"; public const string InvalidUnicodeKeyword = "The `{0}` contextual keyword must not contain Unicode escape sequences."; } public sealed class ParseError { public string Description { get; } public string? Source { get; } public bool IsIndexDefined => Index >= 0; public int Index { get; } public bool IsPositionDefined => Position.Line > 0; public Position Position { get; } public int LineNumber => Position.Line; public int Column => Position.Column + 1; public ParseError(string description, string? source = null, int index = -1, Position position = default(Position)) { Description = description ?? throw new ArgumentNullException("description"); Source = source; Index = index; Position = position; } public override string ToString() { if (LineNumber <= 0) { return Description; } return $"Line {LineNumber}: {Description}"; } public ParserException ToException() { return new ParserException(this); } } public sealed class ParserException : Exception { public ParseError? Error { get; } public string? Description => Error?.Description; public string? SourceLocation => Error?.Source; public int Index => Error?.Index ?? (-1); public int LineNumber => Error?.LineNumber ?? 0; public int Column => Error?.Column ?? 1; public ParserException() : this(null, null, null) { } public ParserException(ParseError error) : this(null, null, error) { } public ParserException(string? message, Exception? innerException = null, ParseError? error = null) : base(message ?? error?.ToString(), innerException) { Error = error; } } internal static class ParserExtensions { private const int MethodImplOptionsAggressiveOptimization = 512; internal static readonly object s_boxedTrue; internal static readonly object s_boxedFalse; private static readonly string[] s_charToString; public static object AsCachedObject(this bool value) { if (!value) { return s_boxedFalse; } return s_boxedTrue; } static ParserExtensions() { s_boxedTrue = true; s_boxedFalse = false; s_charToString = new string[256]; for (int i = 0; i < s_charToString.Length; i++) { s_charToString[i] = ((char)i).ToString(); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static ReadOnlySpan Between(this string s, int start, int end) { return s.AsSpan(start, end - start); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ref readonly T Last(this ReadOnlySpan span) { return ref span[span.Length - 1]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ref T Last(this Span span) { return ref span[span.Length - 1]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static ReadOnlySpan ToParsable(this ReadOnlySpan s) { return s; } internal static int FindIndex(this ReadOnlySpan s, Predicate match, int startIndex = 0) { while (startIndex < s.Length) { if (match(s[startIndex])) { return startIndex; } startIndex++; } return -1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static int FindIndex(this string s, Predicate match, int startIndex = 0) { return s.AsSpan().FindIndex(match, startIndex); } internal static string Replace(this string s, Predicate match, char c) { int num = s.FindIndex(match); if (num < 0) { return s; } return string.Create(s.Length, (s, num, match, c), delegate(Span chars, (string s, int i, Predicate match, char c) state) { var (text, i, predicate, c2) = state; text.AsSpan().CopyTo(chars); chars[i++] = c2; for (; i < chars.Length; i++) { if (predicate(chars[i])) { chars[i] = c2; } } }); } [MethodImpl(MethodImplOptions.AggressiveOptimization)] [StringMatcher(new string[] { "if", "in", "do", "var", "for", "new", "try", "let", "this", "else", "case", "void", "with", "enum", "while", "break", "catch", "throw", "const", "yield", "class", "super", "return", "typeof", "delete", "switch", "export", "import", "default", "finally", "extends", "function", "continue", "debugger", "instanceof", "as", "of", "get", "set", "false", "from", "null", "true", "async", "await", "static", "constructor", "undefined", "length", "object", "Object", "obj", "Array", "Math", "data", "done", "args", "arguments", "Symbol", "prototype", "options", "value", "name", "self", "key", "\"use strict\"", "use strict" })] internal static string? TryGetInternedString(ReadOnlySpan source) { switch (source.Length) { case 2: return source[0] switch { 'a' => (source[1] == 's') ? "as" : null, 'd' => (source[1] == 'o') ? "do" : null, 'i' => source[1] switch { 'f' => "if", 'n' => "in", _ => null, }, 'o' => (source[1] == 'f') ? "of" : null, _ => null, }; case 3: return source[0] switch { 'f' => (source[1] == 'o' && source[2] == 'r') ? "for" : null, 'g' => (source[1] == 'e' && source[2] == 't') ? "get" : null, 'k' => (source[1] == 'e' && source[2] == 'y') ? "key" : null, 'l' => (source[1] == 'e' && source[2] == 't') ? "let" : null, 'n' => (source[1] == 'e' && source[2] == 'w') ? "new" : null, 'o' => (source[1] == 'b' && source[2] == 'j') ? "obj" : null, 's' => (source[1] == 'e' && source[2] == 't') ? "set" : null, 't' => (source[1] == 'r' && source[2] == 'y') ? "try" : null, 'v' => (source[1] == 'a' && source[2] == 'r') ? "var" : null, _ => null, }; case 4: return source[0] switch { 'M' => (source[1] == 'a' && source[2] == 't' && source[3] == 'h') ? "Math" : null, 'a' => (source[1] == 'r' && source[2] == 'g' && source[3] == 's') ? "args" : null, 'c' => (source[1] == 'a' && source[2] == 's' && source[3] == 'e') ? "case" : null, 'd' => source[1] switch { 'a' => (source[2] == 't' && source[3] == 'a') ? "data" : null, 'o' => (source[2] == 'n' && source[3] == 'e') ? "done" : null, _ => null, }, 'e' => source[1] switch { 'l' => (source[2] == 's' && source[3] == 'e') ? "else" : null, 'n' => (source[2] == 'u' && source[3] == 'm') ? "enum" : null, _ => null, }, 'f' => (source[1] == 'r' && source[2] == 'o' && source[3] == 'm') ? "from" : null, 'n' => source[1] switch { 'a' => (source[2] == 'm' && source[3] == 'e') ? "name" : null, 'u' => (source[2] == 'l' && source[3] == 'l') ? "null" : null, _ => null, }, 's' => (source[1] == 'e' && source[2] == 'l' && source[3] == 'f') ? "self" : null, 't' => source[1] switch { 'h' => (source[2] == 'i' && source[3] == 's') ? "this" : null, 'r' => (source[2] == 'u' && source[3] == 'e') ? "true" : null, _ => null, }, 'v' => (source[1] == 'o' && source[2] == 'i' && source[3] == 'd') ? "void" : null, 'w' => (source[1] == 'i' && source[2] == 't' && source[3] == 'h') ? "with" : null, _ => null, }; case 5: return source[0] switch { 'A' => (source[1] == 'r' && source[2] == 'r' && source[3] == 'a' && source[4] == 'y') ? "Array" : null, 'a' => source[1] switch { 's' => (source[2] == 'y' && source[3] == 'n' && source[4] == 'c') ? "async" : null, 'w' => (source[2] == 'a' && source[3] == 'i' && source[4] == 't') ? "await" : null, _ => null, }, 'b' => (source[1] == 'r' && source[2] == 'e' && source[3] == 'a' && source[4] == 'k') ? "break" : null, 'c' => source[1] switch { 'a' => (source[2] == 't' && source[3] == 'c' && source[4] == 'h') ? "catch" : null, 'l' => (source[2] == 'a' && source[3] == 's' && source[4] == 's') ? "class" : null, 'o' => (source[2] == 'n' && source[3] == 's' && source[4] == 't') ? "const" : null, _ => null, }, 'f' => (source[1] == 'a' && source[2] == 'l' && source[3] == 's' && source[4] == 'e') ? "false" : null, 's' => (source[1] == 'u' && source[2] == 'p' && source[3] == 'e' && source[4] == 'r') ? "super" : null, 't' => (source[1] == 'h' && source[2] == 'r' && source[3] == 'o' && source[4] == 'w') ? "throw" : null, 'v' => (source[1] == 'a' && source[2] == 'l' && source[3] == 'u' && source[4] == 'e') ? "value" : null, 'w' => (source[1] == 'h' && source[2] == 'i' && source[3] == 'l' && source[4] == 'e') ? "while" : null, 'y' => (source[1] == 'i' && source[2] == 'e' && source[3] == 'l' && source[4] == 'd') ? "yield" : null, _ => null, }; case 6: return source[0] switch { 'O' => (source[1] == 'b' && source[2] == 'j' && source[3] == 'e' && source[4] == 'c' && source[5] == 't') ? "Object" : null, 'S' => (source[1] == 'y' && source[2] == 'm' && source[3] == 'b' && source[4] == 'o' && source[5] == 'l') ? "Symbol" : null, 'd' => (source[1] == 'e' && source[2] == 'l' && source[3] == 'e' && source[4] == 't' && source[5] == 'e') ? "delete" : null, 'e' => (source[1] == 'x' && source[2] == 'p' && source[3] == 'o' && source[4] == 'r' && source[5] == 't') ? "export" : null, 'i' => (source[1] == 'm' && source[2] == 'p' && source[3] == 'o' && source[4] == 'r' && source[5] == 't') ? "import" : null, 'l' => (source[1] == 'e' && source[2] == 'n' && source[3] == 'g' && source[4] == 't' && source[5] == 'h') ? "length" : null, 'o' => (source[1] == 'b' && source[2] == 'j' && source[3] == 'e' && source[4] == 'c' && source[5] == 't') ? "object" : null, 'r' => (source[1] == 'e' && source[2] == 't' && source[3] == 'u' && source[4] == 'r' && source[5] == 'n') ? "return" : null, 's' => source[1] switch { 't' => (source[2] == 'a' && source[3] == 't' && source[4] == 'i' && source[5] == 'c') ? "static" : null, 'w' => (source[2] == 'i' && source[3] == 't' && source[4] == 'c' && source[5] == 'h') ? "switch" : null, _ => null, }, 't' => (source[1] == 'y' && source[2] == 'p' && source[3] == 'e' && source[4] == 'o' && source[5] == 'f') ? "typeof" : null, _ => null, }; case 7: return source[0] switch { 'd' => (source[1] == 'e' && source[2] == 'f' && source[3] == 'a' && source[4] == 'u' && source[5] == 'l' && source[6] == 't') ? "default" : null, 'e' => (source[1] == 'x' && source[2] == 't' && source[3] == 'e' && source[4] == 'n' && source[5] == 'd' && source[6] == 's') ? "extends" : null, 'f' => (source[1] == 'i' && source[2] == 'n' && source[3] == 'a' && source[4] == 'l' && source[5] == 'l' && source[6] == 'y') ? "finally" : null, 'o' => (source[1] == 'p' && source[2] == 't' && source[3] == 'i' && source[4] == 'o' && source[5] == 'n' && source[6] == 's') ? "options" : null, _ => null, }; case 8: return source[0] switch { 'c' => (source[1] == 'o' && source[2] == 'n' && source[3] == 't' && source[4] == 'i' && source[5] == 'n' && source[6] == 'u' && source[7] == 'e') ? "continue" : null, 'd' => (source[1] == 'e' && source[2] == 'b' && source[3] == 'u' && source[4] == 'g' && source[5] == 'g' && source[6] == 'e' && source[7] == 'r') ? "debugger" : null, 'f' => (source[1] == 'u' && source[2] == 'n' && source[3] == 'c' && source[4] == 't' && source[5] == 'i' && source[6] == 'o' && source[7] == 'n') ? "function" : null, _ => null, }; case 9: return source[0] switch { 'a' => (source[1] == 'r' && source[2] == 'g' && source[3] == 'u' && source[4] == 'm' && source[5] == 'e' && source[6] == 'n' && source[7] == 't' && source[8] == 's') ? "arguments" : null, 'p' => (source[1] == 'r' && source[2] == 'o' && source[3] == 't' && source[4] == 'o' && source[5] == 't' && source[6] == 'y' && source[7] == 'p' && source[8] == 'e') ? "prototype" : null, 'u' => (source[1] == 'n' && source[2] == 'd' && source[3] == 'e' && source[4] == 'f' && source[5] == 'i' && source[6] == 'n' && source[7] == 'e' && source[8] == 'd') ? "undefined" : null, _ => null, }; case 10: return source[0] switch { 'i' => source.SequenceEqual("instanceof".AsSpan()) ? "instanceof" : null, 'u' => source.SequenceEqual("use strict".AsSpan()) ? "use strict" : null, _ => null, }; case 11: if (!source.SequenceEqual("constructor".AsSpan())) { return null; } return "constructor"; case 12: if (!source.SequenceEqual("\"use strict\"".AsSpan())) { return null; } return "\"use strict\""; default: return null; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static string ToInternedString(this ReadOnlySpan source, ref StringPool stringPool) { if (source.Length == 1) { return CharToString(source[0]); } return TryGetInternedString(source) ?? stringPool.GetOrCreate(source); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static string ToInternedString(this ReadOnlySpan source, ref StringPool stringPool, int interningThreshold) { if (source.Length > interningThreshold) { return source.ToString(); } return source.ToInternedString(ref stringPool); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static string CharToString(char c) { int num = c; string[] array = s_charToString; if ((uint)num < array.Length) { return array[num]; } return c.ToString(); } internal static StringBuilder AppendCodePoint(this StringBuilder sb, int cp) { if (cp > 65535) { Character.GetSurrogatePair((uint)cp, out var highSurrogate, out var lowSurrogate); return sb.Append(highSurrogate).Append(lowSurrogate); } return sb.Append((char)cp); } public static int CodePointAt(this string text, int i) { char c = text.CharCodeAt(i); if (c >= '\ud800' && c <= '\udbff') { char c2 = text.CharCodeAt(i + 1); if (c2 >= '\udc00' && c2 <= '\udfff') { return (int)Character.GetCodePoint(c, c2); } } return c; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static char CharCodeAt(this string source, int index) { if ((uint)index < source.Length) { return source[index]; } return '\0'; } internal static bool TryConsumeInt(this ref ReadOnlySpan s, out int result) { result = 0; int i; for (i = 0; i < s.Length; i++) { char c2; char c = (c2 = s[i]); if (c < '0' || c > '9') { break; } result = checked(result * 10 + c2 - 48); } if (i == 0) { result = 0; return false; } s = s.Slice(i); return true; } } public record ParserOptions { public bool Tokens { get; init; } public bool Comments { get { return _scannerOptions._comments; } init { _scannerOptions._comments = value; } } public bool Tolerant { get { return _scannerOptions._tolerant; } init { _scannerOptions._tolerant = value; } } public bool AllowReturnOutsideFunction { get; set; } public ErrorHandler ErrorHandler { get { return _scannerOptions._errorHandler; } init { _scannerOptions._errorHandler = value; } } public RegExpParseMode RegExpParseMode { get { return _scannerOptions._regExpParseMode; } init { _scannerOptions._regExpParseMode = value; } } public TimeSpan RegexTimeout { get { return _scannerOptions._regexTimeout; } init { _scannerOptions._regexTimeout = value; } } public int MaxAssignmentDepth { get; init; } = 200; public Action? OnNodeCreated { get; init; } public static readonly ParserOptions Default = new ParserOptions(); private readonly ScannerOptions _scannerOptions = new ScannerOptions(); public ScannerOptions GetScannerOptions() { return _scannerOptions; } protected ParserOptions(ParserOptions original) { _scannerOptions = original._scannerOptions.$(); Tokens = original.Tokens; AllowReturnOutsideFunction = original.AllowReturnOutsideFunction; MaxAssignmentDepth = original.MaxAssignmentDepth; OnNodeCreated = original.OnNodeCreated; } [CompilerGenerated] protected virtual bool PrintMembers(StringBuilder builder) { RuntimeHelpers.EnsureSufficientExecutionStack(); builder.Append("Tokens = "); builder.Append(Tokens.ToString()); builder.Append(", Comments = "); builder.Append(Comments.ToString()); builder.Append(", Tolerant = "); builder.Append(Tolerant.ToString()); builder.Append(", AllowReturnOutsideFunction = "); builder.Append(AllowReturnOutsideFunction.ToString()); builder.Append(", ErrorHandler = "); builder.Append(ErrorHandler); builder.Append(", RegExpParseMode = "); builder.Append(RegExpParseMode.ToString()); builder.Append(", RegexTimeout = "); builder.Append(RegexTimeout.ToString()); builder.Append(", MaxAssignmentDepth = "); builder.Append(MaxAssignmentDepth.ToString()); builder.Append(", OnNodeCreated = "); builder.Append(OnNodeCreated); return true; } [CompilerGenerated] public override int GetHashCode() { return ((((EqualityComparer.Default.GetHashCode(EqualityContract) * -1521134295 + EqualityComparer.Default.GetHashCode(_scannerOptions)) * -1521134295 + EqualityComparer.Default.GetHashCode(Tokens)) * -1521134295 + EqualityComparer.Default.GetHashCode(AllowReturnOutsideFunction)) * -1521134295 + EqualityComparer.Default.GetHashCode(MaxAssignmentDepth)) * -1521134295 + EqualityComparer>.Default.GetHashCode(OnNodeCreated); } [CompilerGenerated] public virtual bool Equals(ParserOptions? other) { if ((object)this != other) { if ((object)other != null && EqualityContract == other.EqualityContract && EqualityComparer.Default.Equals(_scannerOptions, other._scannerOptions) && EqualityComparer.Default.Equals(Tokens, other.Tokens) && EqualityComparer.Default.Equals(AllowReturnOutsideFunction, other.AllowReturnOutsideFunction) && EqualityComparer.Default.Equals(MaxAssignmentDepth, other.MaxAssignmentDepth)) { return EqualityComparer>.Default.Equals(OnNodeCreated, other.OnNodeCreated); } return false; } return true; } public ParserOptions() { } } public readonly struct Position : IEquatable, IComparable { public readonly int Line; public readonly int Column; private static bool Validate(int line, int column, bool throwOnError) { if (line < 0 || (line == 0 && column != 0)) { if (throwOnError) { throw new ArgumentOutOfRangeException("line", line, null); } return false; } if (column < 0) { if (throwOnError) { throw new ArgumentOutOfRangeException("column", column, null); } return false; } return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Position From(int line, int column) { Validate(line, column, throwOnError: true); return new Position(line, column); } internal Position(int line, int column) { Line = line; Column = column; } public override bool Equals(object obj) { if (obj is Position other) { return Equals(other); } return false; } public bool Equals(Position other) { if (Line == other.Line) { return Column == other.Column; } return false; } public int CompareTo(Position other) { if (Line >= other.Line) { if (Line <= other.Line) { if (Column >= other.Column) { return (Column > other.Column) ? 1 : 0; } return -1; } return 1; } return -1; } public static bool operator ==(Position left, Position right) { return left.Equals(right); } public static bool operator !=(Position left, Position right) { return !left.Equals(right); } public static bool operator <(Position left, Position right) { return left.CompareTo(right) < 0; } public static bool operator <=(Position left, Position right) { return left.CompareTo(right) <= 0; } public static bool operator >(Position left, Position right) { return left.CompareTo(right) > 0; } public static bool operator >=(Position left, Position right) { return left.CompareTo(right) >= 0; } public override int GetHashCode() { return (Line * 397) ^ Column; } public override string ToString() { return Line.ToString(CultureInfo.InvariantCulture) + "," + Column.ToString(CultureInfo.InvariantCulture); } private static bool TryParseCore(ReadOnlySpan s, bool throwIfInvalid, out Position result) { if (s.Length >= 3 && s.TryConsumeInt(out var result2) && s.Length >= 2 && s[0] == ',') { s = s.Slice(1); if (s.TryConsumeInt(out var result3) && s.Length <= 0 && Validate(result2, result3, throwIfInvalid)) { result = new Position(result2, result3); return true; } } result = default(Position); return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryParse(ReadOnlySpan s, out Position result) { return TryParseCore(s, throwIfInvalid: false, out result); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryParse(string s, out Position result) { return TryParse(s.AsSpan(), out result); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Position Parse(ReadOnlySpan s) { if (!TryParseCore(s, throwIfInvalid: true, out var result)) { return EsprimaExceptionHelper.ThrowFormatException("Input string was not in a correct format."); } return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Position Parse(string s) { return Parse(s.AsSpan()); } [EditorBrowsable(EditorBrowsableState.Never)] public void Deconstruct(out int line, out int column) { line = Line; column = Column; } } public readonly struct Range : IEquatable { public readonly int Start; public readonly int End; public int Length { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return End - Start; } } private static bool Validate(int start, int end, bool throwOnError) { if (start < 0) { if (throwOnError) { throw new ArgumentOutOfRangeException("start", start, null); } return false; } if (end < start) { if (throwOnError) { throw new ArgumentOutOfRangeException("end", end, null); } return false; } return true; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Range From(int start, int end) { Validate(start, end, throwOnError: true); return new Range(start, end); } internal Range(int start, int end) { Start = start; End = end; } public bool Equals(Range other) { if (Start == other.Start) { return End == other.End; } return false; } public override bool Equals(object obj) { if (obj is Range other) { return Equals(other); } return false; } public static bool operator ==(Range left, Range right) { return left.Equals(right); } public static bool operator !=(Range left, Range right) { return !left.Equals(right); } public override int GetHashCode() { return (Start * 397) ^ End; } public override string ToString() { if (Start == End) { return string.Format(CultureInfo.InvariantCulture, "[{0})", Start); } return string.Format(CultureInfo.InvariantCulture, "[{0}..{1})", Start, End); } private static bool TryParseCore(ReadOnlySpan s, bool throwIfInvalid, out Range result) { int result2; int result3; if (s.Length >= 3 && s[0] == '[' && s[s.Length - 1] == ')') { s = s.Slice(1, s.Length - 2); if (s.TryConsumeInt(out result2)) { if (s.Length == 0) { result3 = result2; goto IL_00a3; } if (s.Length >= 3 && s[0] == '.' && s[1] == '.') { s = s.Slice(2); if (s.TryConsumeInt(out result3) && s.Length <= 0) { goto IL_00a3; } } } } goto IL_00bc; IL_00a3: if (Validate(result2, result3, throwIfInvalid)) { result = From(result2, result3); return true; } goto IL_00bc; IL_00bc: result = default(Range); return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryParse(ReadOnlySpan s, out Range result) { return TryParseCore(s, throwIfInvalid: false, out result); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryParse(string s, out Range result) { return TryParse(s.AsSpan(), out result); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Range Parse(ReadOnlySpan s) { if (!TryParseCore(s, throwIfInvalid: true, out var result)) { return EsprimaExceptionHelper.ThrowFormatException("Input string was not in a correct format."); } return result; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Range Parse(string s) { return Parse(s.AsSpan()); } [EditorBrowsable(EditorBrowsableState.Never)] public void Deconstruct(out int start, out int end) { start = Start; end = End; } public System.Range ToSystemRange() { return Start..End; } } internal readonly struct ScannerState { public readonly int Index; public readonly int LineNumber; public readonly int LineStart; public readonly ArrayList CurlyStack; public ScannerState(int index, int lineNumber, int lineStart, ArrayList curlyStack) { Index = index; LineNumber = lineNumber; LineStart = lineStart; CurlyStack = curlyStack; } } internal readonly record struct LexOptions(bool Strict, bool AllowIdentifierEscape) { public LexOptions(bool Strict, bool AllowIdentifierEscape) { this.Strict = Strict; this.AllowIdentifierEscape = AllowIdentifierEscape; } public LexOptions(JavaScriptParser.Context context) : this(context.Strict, context.AllowIdentifierEscape) { } } public sealed class Scanner { private enum JavaScriptNumberStyle { Binary, Hex, Octal, Integer } [Flags] internal enum RegExpFlags { None = 0, Global = 1, Multiline = 2, IgnoreCase = 4, Unicode = 8, Sticky = 0x10, DotAll = 0x20, Indices = 0x40, UnicodeSets = 0x80 } internal struct RegExpParser { private ref struct ParsePatternContext { public int Index; public readonly StringBuilder? StringBuilder; public readonly Action? AppendChar; public readonly Action? AppendCharSafe; public readonly ReadOnlySpan CapturingGroups; public readonly Dictionary? CapturingGroupNames; public int CapturingGroupCounter; public ArrayList GroupStack; public int SetStartIndex; public int SetRangeStart; public string? FollowingQuantifierError; public ArrayList UnicodeSet; public bool WithinSet { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return SetStartIndex >= 0; } } public ParsePatternContext(StringBuilder? sb, ReadOnlySpan capturingGroups, Dictionary? capturingGroupNames) { Index = 0; AppendChar = null; AppendCharSafe = null; CapturingGroupCounter = 0; GroupStack = default(ArrayList); SetStartIndex = 0; SetRangeStart = 0; FollowingQuantifierError = null; UnicodeSet = default(ArrayList); StringBuilder = sb; if (sb != null) { AppendChar = s_appendChar; AppendCharSafe = s_appendCharSafe; } CapturingGroups = capturingGroups; CapturingGroupNames = capturingGroupNames; } } private interface IMode { void ProcessChar(ref ParsePatternContext context, char ch, Action? appender, ref RegExpParser parser); void ProcessSetSpecialChar(ref ParsePatternContext context, char ch); void ProcessSetChar(ref ParsePatternContext context, char ch, Action? appender, ref RegExpParser parser, int startIndex); bool RewriteSet(ref ParsePatternContext context, ref RegExpParser parser); void RewriteDot(ref ParsePatternContext context, bool dotAll); bool AllowsQuantifierAfterGroup(RegExpGroupType groupType); void HandleInvalidRangeQuantifier(ref ParsePatternContext context, ref RegExpParser parser, int startIndex); bool AdjustEscapeSequence(ref ParsePatternContext context, ref RegExpParser parser, out ParseError? conversionError); } private sealed class LegacyMode : IMode { public static readonly LegacyMode Instance = new LegacyMode(); private LegacyMode() { } public void ProcessChar(ref ParsePatternContext context, char ch, Action? appender, ref RegExpParser parser) { ref readonly StringBuilder stringBuilder = ref context.StringBuilder; appender?.Invoke(stringBuilder, ch); } public void ProcessSetSpecialChar(ref ParsePatternContext context, char ch) { context.StringBuilder?.Append(ch); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ProcessSetChar(ref ParsePatternContext context, char ch, Action? appender, ref RegExpParser parser, int startIndex) { ProcessSetChar(ref context, ch, ch, appender, ref parser, startIndex); } private static void ProcessSetChar(ref ParsePatternContext context, char ch, int charCode, Action? appender, ref RegExpParser parser, int startIndex) { ref readonly StringBuilder stringBuilder = ref context.StringBuilder; if (context.SetRangeStart >= 0) { appender?.Invoke(stringBuilder, ch); context.SetRangeStart = charCode; return; } context.SetRangeStart = ~context.SetRangeStart; if (context.SetRangeStart > charCode) { if (context.SetRangeStart <= 1114111) { parser.ReportSyntaxError(startIndex, "Invalid regular expression: /{0}/{1}: Range out of order in character class"); } else if (stringBuilder != null) { stringBuilder.Remove(stringBuilder.Length - 1, 1); AppendCharSafe(stringBuilder, '-'); } } appender?.Invoke(stringBuilder, ch); context.SetRangeStart = int.MaxValue; } public bool RewriteSet(ref ParsePatternContext context, ref RegExpParser parser) { ref readonly StringBuilder stringBuilder = ref context.StringBuilder; if (stringBuilder != null) { ref readonly string pattern = ref parser._pattern; ref int index = ref context.Index; if (context.SetStartIndex == index - 1) { stringBuilder.Remove(stringBuilder.Length - 1, 1).Append("[^\\s\\S]"); return true; } if (context.SetStartIndex == index - 2 && pattern[index - 1] == '^') { stringBuilder.Remove(stringBuilder.Length - 2, 2).Append("[\\s\\S]"); return true; } return false; } return true; } public void RewriteDot(ref ParsePatternContext context, bool dotAll) { ref readonly StringBuilder stringBuilder = ref context.StringBuilder; if (stringBuilder != null) { if (!dotAll) { stringBuilder.Append("[^\n\r\u2028\u2029]"); } else { stringBuilder.Append("[\\s\\S]"); } } } private static void ParseOctalEscape(string pattern, ref int i, out ushort charCode) { charCode = 0; int num = Math.Min(i + 3, pattern.Length); char c; do { ushort num2 = (ushort)((charCode << 3) + (pattern[i] - 48)); if (num2 > 255) { break; } charCode = num2; if (++i >= num) { break; } c = pattern[i]; } while (c >= '0' && c <= '7'); i--; } public bool AllowsQuantifierAfterGroup(RegExpGroupType groupType) { bool flag = (uint)(groupType - 12) <= 1u; return !flag; } public void HandleInvalidRangeQuantifier(ref ParsePatternContext context, ref RegExpParser parser, int startIndex) { ref readonly StringBuilder? stringBuilder = ref context.StringBuilder; ref readonly string pattern = ref parser._pattern; stringBuilder?.Append(pattern[startIndex]); context.FollowingQuantifierError = null; } public bool AdjustEscapeSequence(ref ParsePatternContext context, ref RegExpParser parser, out ParseError? conversionError) { ref readonly StringBuilder stringBuilder = ref context.StringBuilder; ref readonly string pattern = ref parser._pattern; ref int index = ref context.Index; int num = index++; char c = pattern[index]; ushort charCode; switch (c) { case 'u': case 'x': if (TryParseHexEscape(pattern, ref index, out charCode)) { if (!context.WithinSet) { context.AppendCharSafe?.Invoke(stringBuilder, (char)charCode); context.FollowingQuantifierError = null; } else { ProcessSetChar(ref context, (char)charCode, context.AppendCharSafe, ref parser, num); } } else if (!context.WithinSet) { stringBuilder?.Append(c); context.FollowingQuantifierError = null; } else { ProcessSetChar(ref context, c, context.AppendChar, ref parser, num); } break; case 'c': if (index + 1 < pattern.Length) { bool flag; switch (charCode = pattern[index + 1]) { case 65: case 66: case 67: case 68: case 69: case 70: case 71: case 72: case 73: case 74: case 75: case 76: case 77: case 78: case 79: case 80: case 81: case 82: case 83: case 84: case 85: case 86: case 87: case 88: case 89: case 90: case 97: case 98: case 99: case 100: case 101: case 102: case 103: case 104: case 105: case 106: case 107: case 108: case 109: case 110: case 111: case 112: case 113: case 114: case 115: case 116: case 117: case 118: case 119: case 120: case 121: case 122: flag = true; break; default: flag = false; break; } if (flag) { charCode &= 0x1F; if (!context.WithinSet) { context.AppendCharSafe?.Invoke(stringBuilder, (char)charCode); context.FollowingQuantifierError = null; } else { ProcessSetChar(ref context, (char)charCode, context.AppendCharSafe, ref parser, num); } index++; break; } if (context.WithinSet) { switch (charCode = pattern[index + 1]) { case 48: case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: case 95: flag = true; break; default: flag = false; break; } if (flag) { charCode &= 0x1F; ProcessSetChar(ref context, (char)charCode, context.AppendCharSafe, ref parser, num); index++; break; } } } if (!context.WithinSet) { stringBuilder?.Append('\\').Append('\\').Append(c); context.FollowingQuantifierError = null; } else { stringBuilder?.Append('\\'); ProcessSetChar(ref context, '\\', context.AppendChar, ref parser, num); ProcessSetChar(ref context, c, context.AppendChar, ref parser, num); } break; case '0': ParseOctalEscape(pattern, ref index, out charCode); if (!context.WithinSet) { context.AppendCharSafe?.Invoke(stringBuilder, (char)charCode); context.FollowingQuantifierError = null; } else { ProcessSetChar(ref context, (char)charCode, context.AppendCharSafe, ref parser, num); } break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (!context.WithinSet && parser.TryAdjustBackreference(ref context, num, out conversionError)) { if (conversionError != null) { return false; } context.FollowingQuantifierError = null; break; } if (!Character.IsOctalDigit(c)) { if (!context.WithinSet) { context.AppendCharSafe?.Invoke(stringBuilder, c); context.FollowingQuantifierError = null; } else { ProcessSetChar(ref context, c, context.AppendCharSafe, ref parser, num); } break; } goto case '0'; case 'k': if (context.CapturingGroupNames == null) { stringBuilder?.Append(c); context.FollowingQuantifierError = null; } else if (!context.WithinSet) { parser.AdjustNamedBackreference(ref context, num, out conversionError); if (conversionError != null) { return false; } context.FollowingQuantifierError = null; } else { parser.ReportSyntaxError(num, "Invalid regular expression: /{0}/{1}: Invalid escape"); } break; case 'D': case 'S': case 'W': case 'd': case 's': case 'w': if (!context.WithinSet) { if (stringBuilder != null) { switch (c) { case 's': stringBuilder.Append('[').Append('\\').Append(c) .Append("\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff") .Append(']'); break; case 'S': stringBuilder.Append('[').Append("\0-\b\u000e-\u001f\\x21-\u009f¡-ᙿᚁ-\u1fff\u200b-‧\u202a-\u202e‰-⁞\u2060-\u2fff、-\ufefe\uff00-\uffff").Append(']'); break; default: stringBuilder.Append(pattern, num, 2); break; } } context.FollowingQuantifierError = null; break; } if (stringBuilder != null) { if (context.SetRangeStart < 0) { stringBuilder.Remove(stringBuilder.Length - 1, 1); AppendCharSafe(stringBuilder, '-'); } switch (c) { case 's': stringBuilder.Append('\\').Append(c).Append("\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff"); break; case 'S': stringBuilder.Append("\0-\b\u000e-\u001f\\x21-\u009f¡-ᙿᚁ-\u1fff\u200b-‧\u202a-\u202e‰-⁞\u2060-\u2fff、-\ufefe\uff00-\uffff"); break; default: stringBuilder.Append(pattern, num, 2); break; } } context.SetRangeStart = ((context.SetRangeStart >= 0) ? 2147483646 : int.MaxValue); break; case 'P': case 'a': case 'e': case 'p': if (!context.WithinSet) { stringBuilder?.Append(c); context.FollowingQuantifierError = null; } else { ProcessSetChar(ref context, c, context.AppendChar, ref parser, num); } break; default: if (!context.WithinSet) { bool flag; switch (c) { case '<': case 'A': case 'G': case 'Z': case 'z': flag = true; break; default: flag = false; break; } if (flag) { stringBuilder?.Append(c); context.FollowingQuantifierError = null; } else { stringBuilder?.Append(pattern, num, 2); flag = ((c == 'B' || c == 'b') ? true : false); context.FollowingQuantifierError = (flag ? "Invalid regular expression: /{0}/{1}: Nothing to repeat" : null); } } else if (c != '-') { if (!TryGetSimpleEscapeCharCode(c, context.WithinSet, out charCode)) { charCode = c; } stringBuilder?.Append('\\'); ProcessSetChar(ref context, c, charCode, context.AppendChar, ref parser, num); } else { ProcessSetChar(ref context, c, context.AppendCharSafe, ref parser, num); } break; } conversionError = null; return true; } } private sealed class UnicodeMode : IMode { public static readonly UnicodeMode Instance = new UnicodeMode(); private UnicodeMode() { } public void ProcessChar(ref ParsePatternContext context, char ch, Action? appender, ref RegExpParser parser) { ref readonly StringBuilder stringBuilder = ref context.StringBuilder; ref readonly string pattern = ref parser._pattern; ref int index = ref context.Index; if (!char.IsSurrogate(ch)) { appender?.Invoke(stringBuilder, ch); } else if (char.IsHighSurrogate(ch) && char.IsLowSurrogate(pattern.CharCodeAt(index + 1))) { stringBuilder?.Append("(?:").Append(ch).Append(pattern[index + 1]) .Append(')'); index++; } else if (stringBuilder != null) { AppendLoneSurrogate(stringBuilder, ch); } } private static void AppendCodePointSafe(StringBuilder sb, int cp) { if (cp > 65535) { sb.Append("(?:").AppendCodePoint(cp).Append(')'); } else { AppendUnicodeCharSafe(sb, (char)cp); } } private static void AppendUnicodeCharSafe(StringBuilder sb, char ch) { if (!char.IsSurrogate(ch)) { AppendCharSafe(sb, ch); } else { AppendLoneSurrogate(sb, ch); } } private static void AppendLoneSurrogate(StringBuilder sb, char ch) { if (sb != null) { sb.Append("(?:"); if (!char.IsHighSurrogate(ch)) { sb.Append("(?? appender, ref RegExpParser parser, int startIndex) { ref readonly string pattern = ref parser._pattern; ref int index = ref context.Index; if (char.IsHighSurrogate(ch) && char.IsLowSurrogate(pattern.CharCodeAt(index + 1))) { AddSetCodePoint(ref context, char.ConvertToUtf32(ch, pattern[index + 1]), ref parser, startIndex); index++; } else { AddSetCodePoint(ref context, ch, ref parser, startIndex); } } private static void AddSetCodePoint(ref ParsePatternContext context, int cp, ref RegExpParser parser, int startIndex) { StringBuilder stringBuilder = context.StringBuilder; if (context.SetRangeStart >= 0) { if (stringBuilder != null) { context.UnicodeSet.Add(new CodePointRange(cp)); } context.SetRangeStart = cp; return; } context.SetRangeStart = ~context.SetRangeStart; if (context.SetRangeStart > cp) { parser.ReportSyntaxError(startIndex, (context.SetRangeStart <= 1114111) ? "Invalid regular expression: /{0}/{1}: Range out of order in character class" : "Invalid regular expression: /{0}/{1}: Invalid character class"); } if (stringBuilder != null) { context.UnicodeSet.AsSpan().Last() = new CodePointRange(context.SetRangeStart, cp); } context.SetRangeStart = int.MaxValue; } public bool RewriteSet(ref ParsePatternContext context, ref RegExpParser parser) { ref readonly StringBuilder stringBuilder = ref context.StringBuilder; ref readonly string pattern = ref parser._pattern; if (stringBuilder != null) { if (context.SetRangeStart < 0) { context.UnicodeSet.Add(new CodePointRange(45)); } CodePointRange.NormalizeRanges(ref context.UnicodeSet); AppendSet(stringBuilder, context.UnicodeSet.AsReadOnlySpan(), pattern.CharCodeAt(context.SetStartIndex + 1) == '^'); context.UnicodeSet = default(ArrayList); } return true; } private static void AppendSet(StringBuilder sb, ReadOnlySpan normalizedSet, bool isInverted) { bool? flag = ((normalizedSet.Length == 0) ? new bool?(isInverted) : ((normalizedSet.Length == 1 && normalizedSet[0].Start == 0 && normalizedSet[0].End == 1114111) ? new bool?(!isInverted) : ((bool?)null))); if (flag.HasValue) { if (flag != true) { sb.Append("[^\\s\\S]"); } else { sb.Append("(?:").Append("[\ud800-\udbff][\udc00-\udfff]").Append('|') .Append("[\ud800-\udbff](?![\udc00-\udfff])|(? 65535) { break; } if (reference.End > 65535) { i++; break; } } ArrayList arrayList; Span span; if (i != 0) { arrayList = new ArrayList(new CodePointRange[i]); span = arrayList.AsSpan(); normalizedSet.Slice(0, span.Length).CopyTo(span); ref CodePointRange reference2 = ref span.Last(); if (reference2.End > 65535) { reference2 = new CodePointRange(reference2.Start, 65535); i--; } } else { arrayList = default(ArrayList); } ArrayList arrayList2; if (i != normalizedSet.Length) { arrayList2 = new ArrayList(new CodePointRange[normalizedSet.Length - i]); span = arrayList2.AsSpan(); normalizedSet.Slice(i, span.Length).CopyTo(span); ref CodePointRange reference3 = ref span[0]; if (reference3.Start <= 65535) { reference3 = new CodePointRange(65536, reference3.End); } } else { arrayList2 = default(ArrayList); } if (isInverted) { arrayList2 = CodePointRange.InvertRanges(arrayList2.AsReadOnlySpan(), 65536); } ArrayList arrayList3 = default(ArrayList); ArrayList arrayList4 = default(ArrayList); for (i = 0; i < arrayList.Count; i++) { CodePointRange item = arrayList[i]; if (item.End < 55296) { continue; } if (item.Start > 57343) { break; } if (item.End > 57343) { if (item.Start < 55296) { arrayList[i] = new CodePointRange(item.Start, 55295); arrayList.Insert(++i, new CodePointRange(57344, item.End)); item = new CodePointRange(55296, 57343); } else { arrayList[i] = new CodePointRange(57344, item.End); item = new CodePointRange(item.Start, 57343); } } else if (item.Start < 55296) { arrayList[i] = new CodePointRange(item.Start, 55295); item = new CodePointRange(55296, item.End); } else { arrayList.RemoveAt(i--); } if (item.End >= 56320 && item.Start < 56320) { arrayList3.Add(new CodePointRange(item.Start, 56319)); arrayList4.Add(new CodePointRange(56320, item.End)); } else if (item.Start < 56320) { arrayList3.Add(item); } else { arrayList4.Add(item); } } if (isInverted) { arrayList.Add(new CodePointRange(55296, 57343)); arrayList3 = CodePointRange.InvertRanges(arrayList3.AsReadOnlySpan(), 55296, 56319); arrayList4 = CodePointRange.InvertRanges(arrayList4.AsReadOnlySpan(), 56320, 57343); } sb.Append("(?:"); string value = null; if (arrayList2.Count > 0) { span = arrayList2.AsSpan(); Span span2 = stackalloc char[2]; Span span3 = stackalloc char[2]; for (i = 0; i < span.Length; i++) { sb.Append(value); value = "|"; ref CodePointRange reference4 = ref span[i]; if (reference4.Start == reference4.End) { sb.AppendCodePoint(reference4.Start); continue; } Character.GetSurrogatePair((uint)reference4.Start, out span2[0], out span2[1]); Character.GetSurrogatePair((uint)reference4.End, out span3[0], out span3[1]); if (span2[0] == span3[0]) { sb.Append(span2[0]); AppendAstralRange(sb, new CodePointRange(span2[1], span3[1])); continue; } int num = ((span2[1] > '\udc00') ? 1 : 0); int num2 = ((span3[1] < '\udfff') ? 1 : 0); string value2 = null; if (num != 0) { sb.Append(span2[0]); AppendAstralRange(sb, new CodePointRange(span2[1], 57343)); value2 = "|"; } if (span3[0] - span2[0] >= num + num2) { sb.Append(value2); AppendAstralRange(sb, new CodePointRange(span2[0] + num, span3[0] - num2)); AppendAstralRange(sb, new CodePointRange(56320, 57343)); value2 = "|"; } if (num2 != 0) { sb.Append(value2); sb.Append(span3[0]); AppendAstralRange(sb, new CodePointRange(56320, span3[1])); } } } if (arrayList3.Count > 0) { sb.Append(value); value = "|"; sb.Append('['); span = arrayList3.AsSpan(); for (i = 0; i < span.Length; i++) { AppendBmpRange(sb, span[i], s_appendChar); } sb.Append(']').Append("(?![\udc00-\udfff])"); } if (arrayList4.Count > 0) { sb.Append(value); value = "|"; sb.Append("(? 0) { sb.Append(value); sb.Append('['); if (isInverted) { sb.Append('^'); } span = arrayList.AsSpan(); for (i = 0; i < span.Length; i++) { AppendBmpRange(sb, span[i], s_appendCharSafe); } sb.Append(']'); } sb.Append(')'); [MethodImpl(MethodImplOptions.AggressiveInlining)] static void AppendAstralRange(StringBuilder sb2, CodePointRange range) { AppendRange(sb2, range, s_appendChar, delegate(StringBuilder stringBuilder) { stringBuilder.Append('['); }, delegate(StringBuilder stringBuilder) { stringBuilder.Append(']'); }); } [MethodImpl(MethodImplOptions.AggressiveInlining)] static void AppendBmpRange(StringBuilder sb2, CodePointRange range, Action appender) { AppendRange(sb2, range, appender, delegate { }, delegate { }); } static void AppendRange(StringBuilder stringBuilder, CodePointRange range, Action appender, Action onRangeStart, Action onRangeEnd) { if (range.Start == range.End) { appender(stringBuilder, (char)range.Start); } else { onRangeStart(stringBuilder); appender(stringBuilder, (char)range.Start); if (range.End > range.Start + 1) { stringBuilder.Append('-'); } appender(stringBuilder, (char)range.End); onRangeEnd(stringBuilder); } } } private static void AddStandardCharClass(ref ArrayList set, char ch) { ReadOnlySpan items = ch switch { 'd' => stackalloc CodePointRange[1] { new CodePointRange(48, 57) }, 'D' => stackalloc CodePointRange[2] { new CodePointRange(0, 47), new CodePointRange(58, 1114111) }, 's' => stackalloc CodePointRange[10] { new CodePointRange(9, 13), new CodePointRange(32), new CodePointRange(160), new CodePointRange(5760), new CodePointRange(8192, 8202), new CodePointRange(8232, 8233), new CodePointRange(8239), new CodePointRange(8287), new CodePointRange(12288), new CodePointRange(65279) }, 'S' => stackalloc CodePointRange[11] { new CodePointRange(0, 8), new CodePointRange(14, 31), new CodePointRange(33, 159), new CodePointRange(161, 5759), new CodePointRange(5761, 8191), new CodePointRange(8203, 8231), new CodePointRange(8234, 8238), new CodePointRange(8240, 8286), new CodePointRange(8288, 12287), new CodePointRange(12289, 65278), new CodePointRange(65280, 1114111) }, 'w' => stackalloc CodePointRange[4] { new CodePointRange(48, 57), new CodePointRange(65, 90), new CodePointRange(95), new CodePointRange(97, 122) }, 'W' => stackalloc CodePointRange[5] { new CodePointRange(0, 47), new CodePointRange(58, 64), new CodePointRange(91, 94), new CodePointRange(96), new CodePointRange(123, 1114111) }, _ => throw new ArgumentOutOfRangeException("ch", ch, null), }; set.AddRange(items); } private static bool TryTranslateUnicodePropertyToRanges(ReadOnlySpan expression, CodePointRange.Cache cache, [MaybeNullWhen(false)] out CodePointRange[] ranges) { int num = expression.IndexOf('='); if (num >= 0) { ReadOnlySpan span = expression.Slice(0, num); if (!MemoryExtensions.Equals(span, "gc".AsSpan(), StringComparison.Ordinal) && !MemoryExtensions.Equals(span, "General_Category".AsSpan(), StringComparison.Ordinal)) { ranges = null; return false; } expression = expression.Slice(num + 1); } ranges = GetUnicodeCategoryRanges(expression, cache); return ranges != null; } private static CodePointRange[]? GetUnicodeCategoryRanges(ReadOnlySpan name, CodePointRange.Cache cache) { switch (name) { case "L": case "Letter": return cache.GetGeneralCategory(CodePointRange.Cache.LetterCategory); case "LC": case "Cased_Letter": return cache.GetGeneralCategory(CodePointRange.Cache.CasedLetterCategory); case "Lu": case "Uppercase_Letter": return cache.GetGeneralCategory(UnicodeCategory.UppercaseLetter); case "Ll": case "Lowercase_Letter": return cache.GetGeneralCategory(UnicodeCategory.LowercaseLetter); case "Lt": case "Titlecase_Letter": return cache.GetGeneralCategory(UnicodeCategory.TitlecaseLetter); case "Lm": case "Modifier_Letter": return cache.GetGeneralCategory(UnicodeCategory.ModifierLetter); case "Lo": case "Other_Letter": return cache.GetGeneralCategory(UnicodeCategory.OtherLetter); case "M": case "Combining_Mark": case "Mark": return cache.GetGeneralCategory(CodePointRange.Cache.MarkCategory); case "Mn": case "Nonspacing_Mark": return cache.GetGeneralCategory(UnicodeCategory.NonSpacingMark); case "Mc": case "Spacing_Mark": return cache.GetGeneralCategory(UnicodeCategory.SpacingCombiningMark); case "Me": case "Enclosing_Mark": return cache.GetGeneralCategory(UnicodeCategory.EnclosingMark); case "N": case "Number": return cache.GetGeneralCategory(CodePointRange.Cache.NumberCategory); case "Nd": case "Decimal_Number": case "digit": return cache.GetGeneralCategory(UnicodeCategory.DecimalDigitNumber); case "Nl": case "Letter_Number": return cache.GetGeneralCategory(UnicodeCategory.LetterNumber); case "No": case "Other_Number": return cache.GetGeneralCategory(UnicodeCategory.OtherNumber); case "P": case "punct": case "Punctuation": return cache.GetGeneralCategory(CodePointRange.Cache.PunctuationCategory); case "Pc": case "Connector_Punctuation": return cache.GetGeneralCategory(UnicodeCategory.ConnectorPunctuation); case "Pd": case "Dash_Punctuation": return cache.GetGeneralCategory(UnicodeCategory.DashPunctuation); case "Ps": case "Open_Punctuation": return cache.GetGeneralCategory(UnicodeCategory.OpenPunctuation); case "Pe": case "Close_Punctuation": return cache.GetGeneralCategory(UnicodeCategory.ClosePunctuation); case "Pi": case "Initial_Punctuation": return cache.GetGeneralCategory(UnicodeCategory.InitialQuotePunctuation); case "Pf": case "Final_Punctuation": return cache.GetGeneralCategory(UnicodeCategory.FinalQuotePunctuation); case "Po": case "Other_Punctuation": return cache.GetGeneralCategory(UnicodeCategory.OtherPunctuation); case "S": case "Symbol": return cache.GetGeneralCategory(CodePointRange.Cache.SymbolCategory); case "Sm": case "Math_Symbol": return cache.GetGeneralCategory(UnicodeCategory.MathSymbol); case "Sc": case "Currency_Symbol": return cache.GetGeneralCategory(UnicodeCategory.CurrencySymbol); case "Sk": case "Modifier_Symbol": return cache.GetGeneralCategory(UnicodeCategory.ModifierSymbol); case "So": case "Other_Symbol": return cache.GetGeneralCategory(UnicodeCategory.OtherSymbol); case "Z": case "Separator": return cache.GetGeneralCategory(CodePointRange.Cache.SeparatorCategory); case "Zs": case "Space_Separator": return cache.GetGeneralCategory(UnicodeCategory.SpaceSeparator); case "Zl": case "Line_Separator": return cache.GetGeneralCategory(UnicodeCategory.LineSeparator); case "Zp": case "Paragraph_Separator": return cache.GetGeneralCategory(UnicodeCategory.ParagraphSeparator); case "C": case "Other": return cache.GetGeneralCategory(CodePointRange.Cache.OtherCategory); case "Cc": case "cntrl": case "Control": return cache.GetGeneralCategory(UnicodeCategory.Control); case "Format": case "Cf": return cache.GetGeneralCategory(UnicodeCategory.Format); case "Cs": case "Surrogate": return cache.GetGeneralCategory(UnicodeCategory.Surrogate); case "Co": case "Private_Use": return cache.GetGeneralCategory(UnicodeCategory.PrivateUse); case "Cn": case "Unassigned": return cache.GetGeneralCategory(UnicodeCategory.OtherNotAssigned); default: return null; } } public void RewriteDot(ref ParsePatternContext context, bool dotAll) { ref readonly StringBuilder stringBuilder = ref context.StringBuilder; if (stringBuilder != null) { stringBuilder.Append("(?:").Append("[\ud800-\udbff][\udc00-\udfff]").Append('|') .Append("[\ud800-\udbff](?![\udc00-\udfff])|(? expression = pattern.AsSpan(index + 2, i - (index + 2)); int cp; bool flag = !int.TryParse(expression.ToParsable(), NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out cp); if (!flag) { bool flag2 = ((cp < 0 || cp > 1114111) ? true : false); flag = flag2; } if (flag) { parser.ReportSyntaxError(num, "Invalid regular expression: /{0}/{1}: Invalid Unicode escape"); } if (!context.WithinSet) { if (stringBuilder != null) { AppendCodePointSafe(stringBuilder, cp); } context.FollowingQuantifierError = null; } else { AddSetCodePoint(ref context, cp, ref parser, num); } index = i; break; } goto case 'x'; case 'x': if (TryParseHexEscape(pattern, ref index, out charCode)) { if (c == 'u' && char.IsHighSurrogate((char)charCode) && index + 2 < pattern.Length && pattern[index + 1] == '\\' && pattern[index + 2] == 'u') { int i = index + 2; if (TryParseHexEscape(pattern, ref i, out var charCode2) && char.IsLowSurrogate((char)charCode2)) { int cp = char.ConvertToUtf32((char)charCode, (char)charCode2); if (!context.WithinSet) { if (stringBuilder != null) { AppendCodePointSafe(stringBuilder, cp); } context.FollowingQuantifierError = null; } else { AddSetCodePoint(ref context, cp, ref parser, num); } index = i; break; } } if (!context.WithinSet) { if (stringBuilder != null) { AppendUnicodeCharSafe(stringBuilder, (char)charCode); } context.FollowingQuantifierError = null; } else { AddSetCodePoint(ref context, charCode, ref parser, num); } } else { parser.ReportSyntaxError(num, (c == 'u') ? "Invalid regular expression: /{0}/{1}: Invalid Unicode escape" : "Invalid regular expression: /{0}/{1}: Invalid escape"); } break; case 'c': if (index + 1 < pattern.Length) { bool flag; switch (pattern[index + 1]) { case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': flag = true; break; default: flag = false; break; } if (flag) { charCode = (ushort)(char.ToUpperInvariant(pattern[++index]) - 64); if (!context.WithinSet) { context.AppendCharSafe?.Invoke(stringBuilder, (char)charCode); context.FollowingQuantifierError = null; } else { AddSetCodePoint(ref context, charCode, ref parser, num); } break; } } parser.ReportSyntaxError(num, "Invalid regular expression: /{0}/{1}: Invalid Unicode escape"); break; case '0': if (!Character.IsDecimalDigit(pattern.CharCodeAt(index + 1))) { if (!context.WithinSet) { context.AppendCharSafe?.Invoke(stringBuilder, '\0'); context.FollowingQuantifierError = null; } else { AddSetCodePoint(ref context, 0, ref parser, num); } } else { parser.ReportSyntaxError(num, (!context.WithinSet) ? "Invalid regular expression: /{0}/{1}: Invalid decimal escape" : "Invalid regular expression: /{0}/{1}: Invalid class escape"); } break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (!context.WithinSet && parser.TryAdjustBackreference(ref context, num, out conversionError)) { if (conversionError != null) { return false; } context.FollowingQuantifierError = null; } else { parser.ReportSyntaxError(num, (!context.WithinSet || c >= '8') ? "Invalid regular expression: /{0}/{1}: Invalid escape" : "Invalid regular expression: /{0}/{1}: Invalid class escape"); } break; case 'k': if (!context.WithinSet) { parser.AdjustNamedBackreference(ref context, num, out conversionError); if (conversionError != null) { return false; } context.FollowingQuantifierError = null; } else { parser.ReportSyntaxError(num, "Invalid regular expression: /{0}/{1}: Invalid escape"); } break; case 'D': case 'S': case 'W': case 'd': case 's': case 'w': if (!context.WithinSet) { if (stringBuilder != null) { if ((c == 'D' || c == 'S' || c == 'W') ? true : false) { StringBuilder stringBuilder2 = stringBuilder.Append("(?:").Append("[\ud800-\udbff][\udc00-\udfff]").Append('|') .Append("[\ud800-\udbff](?![\udc00-\udfff])|(? "\0-\\x2F\\x3A-\ud7ff\ue000-\uffff", 'S' => "\0-\b\u000e-\u001f\\x21-\u009f¡-ᙿᚁ-\u1fff\u200b-‧\u202a-\u202e‰-⁞\u2060-\u2fff、-\ud7ff\ue000-\ufefe\uff00-\uffff", _ => "\0-\\x2F\\x3A-\\x40\\x5B-\\x5E\\x60\\x7B-\ud7ff\ue000-\uffff", }).Append(']').Append(')'); } else if (c != 's') { stringBuilder.Append(pattern, num, 2); } else { stringBuilder.Append('[').Append('\\').Append(c) .Append("\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff") .Append(']'); } } context.FollowingQuantifierError = null; } else { if (context.SetRangeStart < 0) { parser.ReportSyntaxError(num, "Invalid regular expression: /{0}/{1}: Invalid character class"); } if (stringBuilder != null) { AddStandardCharClass(ref context.UnicodeSet, c); } context.SetRangeStart = 2147483646; } break; case 'P': case 'p': if (pattern.CharCodeAt(index + 1) == '{') { int i = pattern.IndexOf('}', index + 2); ReadOnlySpan expression; if (i < 0 || (expression = pattern.AsSpan(index + 2, i - (index + 2))).IsWhiteSpace()) { parser.ReportSyntaxError(num, (!context.WithinSet) ? "Invalid regular expression: /{0}/{1}: Invalid property name" : "Invalid regular expression: /{0}/{1}: Invalid property name in character class"); expression = default(ReadOnlySpan); } ReadOnlySpan readOnlySpan; if (stringBuilder != null) { if (!TryTranslateUnicodePropertyToRanges(expression, parser.GetCodePointRangeCache(), out CodePointRange[] ranges)) { conversionError = parser.ReportConversionFailure(num, "Inconvertible Unicode property escape"); return false; } readOnlySpan = ((c == 'P') ? CodePointRange.InvertRanges(ranges).AsReadOnlySpan() : ((ReadOnlySpan)ranges)); } else { readOnlySpan = default(ReadOnlySpan); } if (!context.WithinSet) { if (stringBuilder != null) { AppendSet(stringBuilder, readOnlySpan, isInverted: false); } context.FollowingQuantifierError = null; } else { if (context.SetRangeStart < 0) { parser.ReportSyntaxError(num, "Invalid regular expression: /{0}/{1}: Invalid character class"); } if (stringBuilder != null) { context.UnicodeSet.AddRange(readOnlySpan); } context.SetRangeStart = 2147483646; } index = i; } else { parser.ReportSyntaxError(num, (!context.WithinSet) ? "Invalid regular expression: /{0}/{1}: Invalid property name" : "Invalid regular expression: /{0}/{1}: Invalid property name in character class"); } break; default: if (!TryGetSimpleEscapeCharCode(c, context.WithinSet, out charCode)) { parser.ReportSyntaxError(num, "Invalid regular expression: /{0}/{1}: Invalid escape"); } if (!context.WithinSet) { stringBuilder?.Append(pattern, num, 2); bool flag = ((c == 'B' || c == 'b') ? true : false); context.FollowingQuantifierError = (flag ? "Invalid regular expression: /{0}/{1}: Nothing to repeat" : null); } else { AddSetCodePoint(ref context, charCode, ref parser, num); } break; } conversionError = null; return true; } } private const string MatchAnyRegex = "[\\s\\S]"; private const string MatchNoneRegex = "[^\\s\\S]"; private const string MatchNewLineRegex = "[\n\r\u2028\u2029]"; private const string MatchAnyButNewLineRegex = "[^\n\r\u2028\u2029]"; private const string AdditionalWhiteSpacePattern = "\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff"; private const int SetRangeNotStarted = int.MaxValue; private const int SetRangeStartedWithCharClass = 2147483646; private readonly string _pattern; private readonly int _patternStartIndex; private readonly RegExpFlags _flags; private readonly string _flagsOriginal; private readonly Scanner _scanner; private StringBuilder? _tempStringBuilder; private static readonly Action s_appendChar = delegate(StringBuilder sb, char ch) { sb.Append(ch); }; private static readonly Action s_appendCharSafe = AppendCharSafe; private const string MatchSurrogatePairRegex = "[\ud800-\udbff][\udc00-\udfff]"; private const string MatchLoneSurrogateRegex = "[\ud800-\udbff](?![\udc00-\udfff])|(? RegExpFlags.Global, 'i' => RegExpFlags.IgnoreCase, 'm' => RegExpFlags.Multiline, 'u' => RegExpFlags.Unicode, 'y' => RegExpFlags.Sticky, 's' => RegExpFlags.DotAll, 'd' => RegExpFlags.Indices, 'v' => RegExpFlags.UnicodeSets, _ => RegExpFlags.None, }; if (regExpFlags2 == RegExpFlags.None || (regExpFlags & regExpFlags2) != RegExpFlags.None) { scanner._index = startIndex; scanner.ThrowUnexpectedToken("Invalid regular expression flags"); } regExpFlags |= regExpFlags2; } if ((regExpFlags & RegExpFlags.Unicode) != RegExpFlags.None && (regExpFlags & RegExpFlags.UnicodeSets) != RegExpFlags.None) { scanner._index = startIndex; scanner.ThrowUnexpectedToken("Invalid regular expression flags"); } return regExpFlags; } private static RegexOptions FlagsToOptions(RegExpFlags flags, bool compiled) { RegexOptions regexOptions = RegexOptions.ECMAScript | RegexOptions.CultureInvariant; if (compiled) { regexOptions |= RegexOptions.Compiled; } if ((flags & RegExpFlags.IgnoreCase) != RegExpFlags.None) { regexOptions |= RegexOptions.IgnoreCase; } return regexOptions; } public RegExpParser(string pattern, int patternStartIndex, string flags, int flagsStartIndex, Scanner scanner) { _tempStringBuilder = null; _pattern = pattern; _patternStartIndex = patternStartIndex; _flags = ParseFlags(flags, flagsStartIndex, scanner); _flagsOriginal = flags; _scanner = scanner; } public RegExpParser(string pattern, string flags, ScannerOptions scannerOptions) : this(pattern, 0, flags, 0, new Scanner(flags, scannerOptions)) { _scanner.Reset(pattern, null); } private Scanner MoveScannerTo(int index, out int originalIndex) { originalIndex = _scanner._index; _scanner._index = _patternStartIndex + index; return _scanner; } private Scanner MoveScannerTo(int index) { int originalIndex; return MoveScannerTo(index, out originalIndex); } private ParseError ReportConversionFailure(int index, string reason) { int originalIndex; ParseError result = MoveScannerTo(index, out originalIndex).TolerateUnexpectedToken("Cannot convert regular expression to an equivalent " + typeof(Regex).ToString() + ": /" + _pattern + "/" + _flagsOriginal + ": " + reason); _scanner._index = originalIndex; return result; } [DoesNotReturn] private void ReportSyntaxError(int index, string message) { MoveScannerTo(index).ThrowUnexpectedToken(string.Format(CultureInfo.InvariantCulture, message, _pattern, _flagsOriginal)); } public RegExpParseResult Parse() { ParseError conversionError; if ((_flags & RegExpFlags.UnicodeSets) != RegExpFlags.None) { if (_scanner._regExpParseMode != RegExpParseMode.Validate) { conversionError = ReportConversionFailure(0, "Unicode sets mode (flag v) is not supported currently"); return new RegExpParseResult(conversionError); } MoveScannerTo(0).ThrowUnexpectedToken("Unicode sets mode (flag v) is not supported currently"); } ArrayList capturingGroups; string text = ParseCore(out capturingGroups, out conversionError); if (text == null) { return new RegExpParseResult(conversionError); } capturingGroups.TrimExcess(); RegexOptions options = FlagsToOptions(_flags, _scanner._regExpParseMode == RegExpParseMode.AdaptToCompiled); TimeSpan regexTimeout = _scanner._regexTimeout; try { return new RegExpParseResult(new Regex(text, options, regexTimeout), capturingGroups); } catch { conversionError = ReportConversionFailure(0, "Failed to adapt regular expression"); return new RegExpParseResult(conversionError); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal string? ParseCore(out ArrayList capturingGroups, out ParseError? conversionError) { CheckBracesBalance(out capturingGroups, out Dictionary capturingGroupNames); if ((_flags & RegExpFlags.Unicode) == 0) { return ParsePattern(LegacyMode.Instance, ref capturingGroups, capturingGroupNames, out conversionError); } return ParsePattern(UnicodeMode.Instance, ref capturingGroups, capturingGroupNames, out conversionError); } private void CheckBracesBalance(out ArrayList capturingGroups, out Dictionary? capturingGroupNames) { capturingGroups = default(ArrayList); capturingGroupNames = null; bool flag = (_flags & RegExpFlags.Unicode) != 0; int num = 0; bool flag2 = false; bool flag3 = false; for (int i = 0; i < _pattern.Length; i++) { switch (_pattern[i]) { case '\\': i++; break; case '(': if (flag3) { break; } num++; switch (DetermineGroupType(i)) { case RegExpGroupType.Capturing: capturingGroups.Add(new RegExpCapturingGroup(i, null)); break; case RegExpGroupType.NamedCapturing: { int num2 = i++; string text = ParseNormalizedCapturingGroupName(ref i); if (text != null) { (capturingGroupNames ?? (capturingGroupNames = new Dictionary())).TryAdd(text, null); capturingGroups.Add(new RegExpCapturingGroup(i, text)); } else { ReportSyntaxError(num2 + 3, "Invalid regular expression: /{0}/{1}: Invalid capture group name"); } break; } case RegExpGroupType.Unknown: ReportSyntaxError(i, "Invalid regular expression: /{0}/{1}: Invalid group"); break; } break; case ')': if (!flag3) { if (num == 0) { ReportSyntaxError(i, "Invalid regular expression: /{0}/{1}: Unmatched ')'"); } num--; } break; case '{': if (!flag3) { if (!flag2) { flag2 = true; } else if (flag) { ReportSyntaxError(i, "Invalid regular expression: /{0}/{1}: Incomplete quantifier"); } } break; case '}': if (!flag3) { if (flag2) { flag2 = false; } else if (flag) { ReportSyntaxError(i, "Invalid regular expression: /{0}/{1}: Lone quantifier brackets"); } } break; case '[': if (!flag3) { flag3 = true; } break; case ']': if (flag3) { flag3 = false; } else if (flag) { ReportSyntaxError(i, "Invalid regular expression: /{0}/{1}: Lone quantifier brackets"); } break; } } if (num > 0) { ReportSyntaxError(_pattern.Length, "Invalid regular expression: /{0}/{1}: Unterminated group"); } if (flag3) { ReportSyntaxError(_pattern.Length, "Invalid regular expression: /{0}/{1}: Unterminated character class"); } if (flag && flag2) { ReportSyntaxError(_pattern.Length, "Invalid regular expression: /{0}/{1}: Lone quantifier brackets"); } } private string? ParsePattern(TMode mode, ref ArrayList capturingGroups, Dictionary? capturingGroupNames, out ParseError? conversionError) where TMode : IMode { StringBuilder stringBuilder; if (_scanner._regExpParseMode != RegExpParseMode.Validate) { stringBuilder = _scanner.GetStringBuilder(); if (stringBuilder.Capacity < _pattern.Length) { stringBuilder.Capacity = _pattern.Length; } } else { stringBuilder = null; } ParsePatternContext parsePatternContext = new ParsePatternContext(stringBuilder, capturingGroups.AsReadOnlySpan(), capturingGroupNames); parsePatternContext.CapturingGroupCounter = 0; parsePatternContext.GroupStack = ((capturingGroupNames != null) ? new ArrayList(new RegExpGroup[1] { new RegExpGroup(RegExpGroupType.Unknown, null) }) : default(ArrayList)); parsePatternContext.SetStartIndex = -1; parsePatternContext.FollowingQuantifierError = "Invalid regular expression: /{0}/{1}: Nothing to repeat"; ParsePatternContext context = parsePatternContext; ref int index = ref context.Index; for (index = 0; index < _pattern.Length; index++) { char c = _pattern[index]; switch (c) { case '[': if (!context.WithinSet) { context.SetStartIndex = index; context.SetRangeStart = int.MaxValue; mode.ProcessSetSpecialChar(ref context, c); if ((c = _pattern.CharCodeAt(index + 1)) == '^') { mode.ProcessSetSpecialChar(ref context, c); index++; } continue; } break; case '-': if (context.WithinSet) { if (context.SetRangeStart >= 0 && context.SetRangeStart != int.MaxValue) { context.SetRangeStart = ~context.SetRangeStart; mode.ProcessSetSpecialChar(ref context, c); continue; } char ch = c; Action? appendCharSafe = context.AppendCharSafe; int startIndex2 = index; mode.ProcessSetChar(ref context, ch, appendCharSafe, ref this, startIndex2); continue; } break; case ']': if (context.WithinSet) { if (!mode.RewriteSet(ref context, ref this)) { mode.ProcessSetSpecialChar(ref context, c); } context.SetStartIndex = -1; context.FollowingQuantifierError = null; continue; } break; case '(': { if (context.WithinSet) { break; } RegExpGroupAlternate regExpGroupAlternate = ((capturingGroupNames != null) ? context.GroupStack.AsReadOnlySpan().Last().LastAlternate : null); RegExpGroupType regExpGroupType = DetermineGroupType(index); switch (regExpGroupType) { case RegExpGroupType.Capturing: context.CapturingGroupCounter++; break; case RegExpGroupType.NamedCapturing: { string name = capturingGroups[context.CapturingGroupCounter++].Name; if (!regExpGroupAlternate.TryAddGroupName(name)) { ReportSyntaxError(index + 3, "Invalid regular expression: /{0}/{1}: Duplicate capture group name"); } if (stringBuilder != null) { name = AdjustCapturingGroupName(name, capturingGroupNames); if (name == null) { conversionError = ReportConversionFailure(index + 3, "Cannot map group name '" + name + "' to a unique group name in the adapted regex."); return null; } stringBuilder.Append('(').Append(_pattern, index, 3).Append(name); } index = _pattern.IndexOf('>', index + 3); stringBuilder?.Append(_pattern[index]); context.GroupStack.Push(new RegExpGroup(regExpGroupType, regExpGroupAlternate)); context.FollowingQuantifierError = "Invalid regular expression: /{0}/{1}: Nothing to repeat"; continue; } } stringBuilder?.Append(_pattern, index, 1 + ((int)regExpGroupType >> 2)); index += (int)regExpGroupType >> 2; context.GroupStack.Push((regExpGroupAlternate != null) ? new RegExpGroup(regExpGroupType, regExpGroupAlternate) : new RegExpGroup(regExpGroupType)); context.FollowingQuantifierError = "Invalid regular expression: /{0}/{1}: Nothing to repeat"; continue; } case '|': if (!context.WithinSet) { stringBuilder?.Append(c); if (capturingGroupNames != null) { context.GroupStack.AsSpan().Last().AddAlternate(); } context.FollowingQuantifierError = "Invalid regular expression: /{0}/{1}: Nothing to repeat"; continue; } break; case ')': { if (context.WithinSet) { break; } if (capturingGroupNames != null) { context.GroupStack.AsSpan().Last().HoistGroupNamesToParent(); } RegExpGroupType regExpGroupType = context.GroupStack.Pop().Type; if (stringBuilder != null) { stringBuilder.Append(c); if (regExpGroupType == RegExpGroupType.NamedCapturing) { stringBuilder.Append(')'); } } context.FollowingQuantifierError = (mode.AllowsQuantifierAfterGroup(regExpGroupType) ? null : "Invalid regular expression: /{0}/{1}: Invalid quantifier"); continue; } case '^': if (context.WithinSet) { break; } if (stringBuilder != null) { if ((_flags & RegExpFlags.Multiline) == 0) { stringBuilder.Append(c); } else { stringBuilder.Append("(?<=").Append("[\n\r\u2028\u2029]").Append('|') .Append(c) .Append(')'); } } context.FollowingQuantifierError = "Invalid regular expression: /{0}/{1}: Nothing to repeat"; continue; case '$': if (context.WithinSet) { break; } if (stringBuilder != null) { if ((_flags & RegExpFlags.Multiline) == 0) { stringBuilder.Append(c); } else { stringBuilder.Append("(?=").Append("[\n\r\u2028\u2029]").Append('|') .Append(c) .Append(')'); } } context.FollowingQuantifierError = "Invalid regular expression: /{0}/{1}: Nothing to repeat"; continue; case '.': if (!context.WithinSet) { bool dotAll = (_flags & RegExpFlags.DotAll) != 0; mode.RewriteDot(ref context, dotAll); context.FollowingQuantifierError = null; continue; } break; case '*': case '+': case '?': if (!context.WithinSet) { if (context.FollowingQuantifierError != null) { ReportSyntaxError(index, context.FollowingQuantifierError); } stringBuilder?.Append(c); if ((c = _pattern.CharCodeAt(index + 1)) == '?') { stringBuilder?.Append(c); index++; } context.FollowingQuantifierError = "Invalid regular expression: /{0}/{1}: Nothing to repeat"; continue; } break; case '{': if (context.WithinSet) { break; } if (!TryAdjustRangeQuantifier(ref context, out conversionError)) { int startIndex = index; mode.HandleInvalidRangeQuantifier(ref context, ref this, startIndex); continue; } if (conversionError != null) { return null; } if ((c = _pattern.CharCodeAt(index + 1)) == '?') { stringBuilder?.Append(c); index++; } context.FollowingQuantifierError = "Invalid regular expression: /{0}/{1}: Nothing to repeat"; continue; case '\\': if (mode.AdjustEscapeSequence(ref context, ref this, out conversionError)) { continue; } return null; } if (!context.WithinSet) { char ch2 = c; Action? appendChar = context.AppendChar; mode.ProcessChar(ref context, ch2, appendChar, ref this); context.FollowingQuantifierError = null; } else { mode.ProcessSetChar(ref context, c, (c != '[' || context.SetRangeStart >= 0) ? context.AppendChar : context.AppendCharSafe, ref this, index); } } conversionError = null; return stringBuilder?.ToString(); } private static void AppendCharSafe(StringBuilder sb, char ch) { ushort num = ch; if (num < 32 || num >= 127) { sb.Append(ch); } else { sb.Append('\\').Append('x').Append(((byte)ch).ToString("X2", CultureInfo.InvariantCulture)); } } private static bool TryParseHexEscape(string pattern, ref int i, out ushort charCode) { int num = ((pattern[i] == 'u') ? 4 : 2); if (i + num < pattern.Length && ushort.TryParse(pattern.AsSpan(i + 1, num).ToParsable(), NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out charCode)) { i += num; return true; } charCode = 0; return false; } private static bool TryGetSimpleEscapeCharCode(char ch, bool withinSet, out ushort charCode) { switch (ch) { case 'b': charCode = (ushort)(withinSet ? 8 : ushort.MaxValue); return true; case 'B': charCode = ushort.MaxValue; return !withinSet; case 'f': charCode = 12; return true; case 'n': charCode = 10; return true; case 't': charCode = 9; return true; case 'r': charCode = 13; return true; case 'v': charCode = 11; return true; case '$': case '(': case ')': case '*': case '+': case '.': case '/': case '?': case '[': case '\\': case ']': case '^': case '{': case '|': case '}': charCode = ch; return true; case '-': charCode = ch; return withinSet; default: charCode = 0; return false; } } private bool TryAdjustRangeQuantifier(ref ParsePatternContext context, out ParseError? conversionError) { conversionError = null; ref readonly StringBuilder stringBuilder = ref context.StringBuilder; ref int index = ref context.Index; int num = _pattern.IndexOf('}', index + 1); if (num < 0 || num == index + 1) { return false; } int num2 = _pattern.IndexOf(',', index + 1, num - (index + 1)); if (num2 < 0) { num2 = num; } ReadOnlySpan s = _pattern.AsSpan(index + 1, num2 - (index + 1)); if (!int.TryParse(s.ToParsable(), NumberStyles.None, CultureInfo.InvariantCulture, out var result)) { if (s.Length == 0 || s.FindIndex((char ch) => !Character.IsDecimalDigit(ch)) >= 0) { return false; } result = -1; } int result2; if (num2 == num) { result2 = result; } else if (num2 == num - 1) { result2 = int.MaxValue; } else { s = _pattern.AsSpan(num2 + 1, num - (num2 + 1)); if (!int.TryParse(s.ToParsable(), NumberStyles.None, CultureInfo.InvariantCulture, out result2)) { if (s.FindIndex((char ch) => !Character.IsDecimalDigit(ch)) >= 0) { result2 = 0; return false; } result2 = -1; } } if (result >= 0 && result2 >= 0) { if (result > result2) { ReportSyntaxError(index, "Invalid regular expression: /{0}/{1}: numbers out of order in {{}} quantifier"); } if (context.FollowingQuantifierError != null) { ReportSyntaxError(index, context.FollowingQuantifierError); } stringBuilder?.Append(_pattern, index, num + 1 - index); } else if (stringBuilder != null) { conversionError = ReportConversionFailure(index, "Inconvertible {} quantifier"); return true; } index = num; return true; } private RegExpGroupType DetermineGroupType(int i) { if (++i >= _pattern.Length || _pattern[i] != '?') { return RegExpGroupType.Capturing; } if (++i >= _pattern.Length) { return RegExpGroupType.Unknown; } return _pattern[i] switch { ':' => RegExpGroupType.NonCapturing, '=' => RegExpGroupType.LookaheadAssertion, '!' => RegExpGroupType.NegativeLookaheadAssertion, '<' => ((++i < _pattern.Length) ? _pattern[i] : '\0') switch { '=' => RegExpGroupType.LookbehindAssertion, '!' => RegExpGroupType.NegativeLookbehindAssertion, _ => RegExpGroupType.NamedCapturing, }, _ => RegExpGroupType.Unknown, }; } private string? ParseNormalizedCapturingGroupName(ref int i) { if (_pattern.CharCodeAt(i + 1) == '<') { int num = _pattern.IndexOf('>', i + 2); if (num < 0 || num == i + 2 || !Character.IsIdentifierStart(_pattern[i + 2])) { return null; } MoveScannerTo(i + 2, out var originalIndex); int length = _scanner._length; StringBuilder sb = _scanner._sb; _scanner._length = _patternStartIndex + num; _scanner._sb = _tempStringBuilder?.Clear() ?? (_tempStringBuilder = new StringBuilder()); if (_tempStringBuilder.Capacity < _scanner._length - _scanner._index) { _tempStringBuilder.Capacity = _scanner._length - _scanner._index; } string result; try { ushort num2 = _scanner._source[_scanner._index]; if (num2 >= 55296) { if (num2 <= 57343) { goto IL_0132; } } else if (num2 == 92) { goto IL_0132; } bool flag = false; goto IL_013a; IL_013a: result = (flag ? _scanner.GetComplexIdentifier(allowEscapedSurrogates: true) : _scanner.GetIdentifier(allowEscapedSurrogates: true)); if (_scanner.Eof()) { i = num; } else { result = null; } goto end_IL_00fb; IL_0132: flag = true; goto IL_013a; end_IL_00fb:; } catch (ParserException) { result = null; } _scanner._index = originalIndex; _scanner._length = length; _scanner._sb = sb; return result; } return null; } private static string? AdjustCapturingGroupName(string groupName, Dictionary capturingGroupNames) { string text = capturingGroupNames[groupName]; if (text != null) { return text; } if (groupName.FindIndex((char ch) => !IsWordChar(ch)) < 0) { capturingGroupNames[groupName] = groupName; return groupName; } text = EncodeGroupName(groupName); if (!capturingGroupNames.ContainsKey(text)) { capturingGroupNames[groupName] = text; return text; } return null; static ReadOnlySpan AsciiLookup() { return new byte[16] { 0, 0, 0, 0, 0, 0, 255, 3, 254, 255, 255, 135, 254, 255, 255, 7 }; } static bool IsWordChar(char ch) { ReadOnlySpan readOnlySpan = AsciiLookup(); int num = (int)ch >> 3; if ((uint)num < readOnlySpan.Length) { return (readOnlySpan[num] & (1 << (ch & 7))) != 0; } UnicodeCategory unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(ch); if ((uint)unicodeCategory <= 5u || unicodeCategory == UnicodeCategory.DecimalDigitNumber || unicodeCategory == UnicodeCategory.ConnectorPunctuation) { return true; } if (ch != '\u200d') { return ch == '\u200c'; } return true; } } internal static string EncodeGroupName(string groupName) { return "__utf8_" + BitConverter.ToString(Encoding.UTF8.GetBytes(groupName)).Replace("-", ""); } private bool TryAdjustBackreference(ref ParsePatternContext context, int startIndex, out ParseError? conversionError) { conversionError = null; ref readonly StringBuilder stringBuilder = ref context.StringBuilder; ref int index = ref context.Index; int num = _pattern.FindIndex((char ch) => !Character.IsDecimalDigit(ch), index + 1); if (num < 0) { num = _pattern.Length; } int num2 = int.Parse(_pattern.AsSpan(index, num - index).ToParsable(), NumberStyles.None, CultureInfo.InvariantCulture); if (num2 > context.CapturingGroups.Length) { return false; } if (startIndex > context.CapturingGroups[num2 - 1].StartIndex) { stringBuilder?.Append(_pattern, startIndex, num - startIndex); } else if (stringBuilder != null) { conversionError = ReportConversionFailure(startIndex, "Inconvertible forward reference"); return true; } index = num - 1; return true; } private void AdjustNamedBackreference(ref ParsePatternContext context, int startIndex, out ParseError? conversionError) { conversionError = null; ref readonly StringBuilder stringBuilder = ref context.StringBuilder; ref int index = ref context.Index; string text = ParseNormalizedCapturingGroupName(ref index); if (text != null) { Unsafe.SkipInit(out string value); if (context.CapturingGroupNames?.TryGetValue(text, out value) ?? false) { if (stringBuilder != null) { if (IsDefinedCapturingGroupName(text, startIndex, context.CapturingGroups)) { stringBuilder.Append(_pattern, startIndex, 3).Append(value).Append(_pattern[index]); } else { conversionError = ReportConversionFailure(startIndex, "Inconvertible named forward reference"); } } } else { ReportSyntaxError(startIndex, "Invalid regular expression: /{0}/{1}: Invalid named capture referenced"); } } else if (_pattern.CharCodeAt(index + 1) == '<') { ReportSyntaxError(startIndex + 3, "Invalid regular expression: /{0}/{1}: Invalid capture group name"); } else { ReportSyntaxError(startIndex + 2, "Invalid regular expression: /{0}/{1}: Invalid named reference"); } } private static bool IsDefinedCapturingGroupName(string value, int startIndex, ReadOnlySpan capturingGroups) { for (int i = 0; i < capturingGroups.Length; i++) { RegExpCapturingGroup regExpCapturingGroup = capturingGroups[i]; if (regExpCapturingGroup.StartIndex < startIndex && regExpCapturingGroup.Name == value) { return true; } } return false; } private CodePointRange.Cache GetCodePointRangeCache() { Scanner scanner = _scanner; return scanner._codePointRangeCache ?? (scanner._codePointRangeCache = new CodePointRange.Cache()); } } private enum RegExpGroupType { Unknown = 0, Capturing = 1, NamedCapturing = 8, NonCapturing = 9, LookaheadAssertion = 10, NegativeLookaheadAssertion = 11, LookbehindAssertion = 12, NegativeLookbehindAssertion = 13 } private struct RegExpGroup { private AdditionalDataSlot _alternates; public RegExpGroupType Type { get; } public int AlternateCount { get; private set; } public RegExpGroupAlternate? FirstAlternate => (RegExpGroupAlternate)_alternates.PrimaryData; public RegExpGroupAlternate? LastAlternate => GetAlternate(AlternateCount - 1); public RegExpGroup(RegExpGroupType type) { _alternates = default(AdditionalDataSlot); AlternateCount = 0; Type = type; } public RegExpGroup(RegExpGroupType type, RegExpGroupAlternate? parent) : this(type) { _alternates.PrimaryData = new RegExpGroupAlternate(parent); AlternateCount = 1; } public RegExpGroupAlternate? GetAlternate(int index) { return (RegExpGroupAlternate)_alternates[index]; } public void AddAlternate() { _alternates[AlternateCount++] = new RegExpGroupAlternate(FirstAlternate.Parent); } public void HoistGroupNamesToParent() { RegExpGroupAlternate parent = FirstAlternate.Parent; for (int i = 0; i < AlternateCount; i++) { GetAlternate(i).HoistGroupNamesTo(parent); } } } private sealed class RegExpGroupAlternate { private ArrayList _groupNames; public readonly RegExpGroupAlternate? Parent; public RegExpGroupAlternate(RegExpGroupAlternate? parent) { Parent = parent; } public bool IsDefinedGroupName(string value) { return _groupNames.AsReadOnlySpan().BinarySearch(value) >= 0; } public bool TryAddGroupName(string value) { int num = _groupNames.AsReadOnlySpan().BinarySearch(value); bool flag = num >= 0; RegExpGroupAlternate regExpGroupAlternate = this; while (true) { if (flag) { return false; } if ((regExpGroupAlternate = regExpGroupAlternate.Parent) == null) { break; } flag = regExpGroupAlternate.IsDefinedGroupName(value); } _groupNames.Insert(~num, value); return true; } public void HoistGroupNamesTo(RegExpGroupAlternate other) { if (_groupNames.Count <= 0) { return; } if (other._groupNames.Count == 0) { other._groupNames = _groupNames; } else { foreach (string groupName in _groupNames) { int num = other._groupNames.AsReadOnlySpan().BinarySearch(groupName); if (num < 0) { other._groupNames.Insert(~num, groupName); } } } _groupNames = default(ArrayList); } } internal readonly record struct RegExpCapturingGroup(int StartIndex, string? Name); internal const int NonIdentifierInterningThreshold = 20; private readonly ErrorHandler _errorHandler; private readonly bool _tolerant; private readonly bool _trackComment; private readonly RegExpParseMode _regExpParseMode; private readonly TimeSpan _regexTimeout; private int _length; internal string _source; internal string? _sourceLocation; internal int _index; internal int _lineNumber; internal int _lineStart; internal bool _isModule; private ArrayList _curlyStack; private StringBuilder _sb = new StringBuilder(); internal StringPool _stringPool; internal CodePointRange.Cache? _codePointRangeCache; public string Code { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _source; } } public int Index { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _index; } } public int LineNumber { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _lineNumber; } } public int LineStart { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _lineStart; } } private static int OctalValue(char ch) { return ch - 48; } internal Scanner(ScannerOptions options) { if (options == null) { throw new ArgumentNullException("options"); } _regExpParseMode = options.RegExpParseMode; _regexTimeout = options.RegexTimeout; _errorHandler = options.ErrorHandler; _tolerant = options.Tolerant; _trackComment = options.Comments; _source = string.Empty; } public Scanner(string code) : this(code, ScannerOptions.Default) { } public Scanner(string code, ScannerOptions options) : this(code, null, options) { } public Scanner(string code, string? source) : this(code, source, ScannerOptions.Default) { } public Scanner(string code, string? source, ScannerOptions options) : this(options) { Reset(code, source); } public void Reset() { Reset(0, (_length > 0) ? 1 : 0, 0); } public void Reset(int startIndex, int lineNumber, int lineStartIndex) { if (_length > 0) { if (0 > startIndex || startIndex >= _length) { throw new ArgumentOutOfRangeException("startIndex"); } _index = startIndex; if (lineNumber <= 0) { throw new ArgumentOutOfRangeException("lineNumber"); } _lineNumber = lineNumber; if (0 > lineStartIndex || lineStartIndex > _index) { throw new ArgumentOutOfRangeException("lineStartIndex"); } _lineStart = lineStartIndex; } else { if (startIndex != 0) { throw new ArgumentOutOfRangeException("startIndex"); } _index = startIndex; if (lineNumber != 0) { throw new ArgumentOutOfRangeException("lineNumber"); } _lineNumber = lineNumber; if (lineStartIndex != 0) { throw new ArgumentOutOfRangeException("lineStartIndex"); } _lineStart = lineStartIndex; } _curlyStack.Clear(); _sb.Clear(); _errorHandler.Reset(); } internal void Reset(string code, string? source) { Reset(code, source, 0, (code.Length > 0) ? 1 : 0, 0); } internal void Reset(string code, string? source, int startIndex, int lineNumber, int lineStartIndex) { _source = code ?? throw new ArgumentNullException("code"); _length = code.Length; _sourceLocation = source; Reset(startIndex, lineNumber, lineStartIndex); _stringPool = default(StringPool); _codePointRangeCache = null; _isModule = false; } internal void ReleaseLargeBuffers() { _curlyStack.Clear(); if (_curlyStack.Capacity > 16) { _curlyStack.Capacity = 16; } _sb.Clear(); if (_sb.Capacity > 1024) { _sb.Capacity = 1024; } _stringPool = default(StringPool); _codePointRangeCache = null; } internal ScannerState SaveState() { return new ScannerState(_index, _lineNumber, _lineStart, new ArrayList(_curlyStack.ToArray())); } internal void RestoreState(in ScannerState state) { _index = state.Index; _lineNumber = state.LineNumber; _lineStart = state.LineStart; _curlyStack = state.CurlyStack; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal bool Eof() { return _index >= _length; } [DoesNotReturn] private void ThrowUnexpectedToken(string message = "Unexpected token ILLEGAL") { throw _errorHandler.CreateError(_sourceLocation, _index, _lineNumber, _index - _lineStart, message).ToException(); } [DoesNotReturn] private T ThrowUnexpectedToken(string message = "Unexpected token ILLEGAL") { throw _errorHandler.CreateError(_sourceLocation, _index, _lineNumber, _index - _lineStart, message).ToException(); } private ParseError TolerateUnexpectedToken(string message = "Unexpected token ILLEGAL") { return _errorHandler.TolerateError(_sourceLocation, _index, _lineNumber, _index - _lineStart, message, _tolerant); } private StringBuilder GetStringBuilder() { _sb.Clear(); return _sb; } [StringMatcher(new string[] { "enum", "export", "import", "super" })] public static bool IsFutureReservedWord(string id) { return id.Length switch { 4 => id == "enum", 5 => id == "super", 6 => id[0] switch { 'e' => id == "export", 'i' => id == "import", _ => false, }, _ => false, }; } [StringMatcher(new string[] { "implements", "interface", "package", "private", "protected", "public", "static", "yield", "let" })] public static bool IsStrictModeReservedWord(string id) { return id.Length switch { 3 => id == "let", 5 => id == "yield", 6 => id[0] switch { 'p' => id == "public", 's' => id == "static", _ => false, }, 7 => id[1] switch { 'a' => id == "package", 'r' => id == "private", _ => false, }, 9 => id[0] switch { 'i' => id == "interface", 'p' => id == "protected", _ => false, }, 10 => id == "implements", _ => false, }; } public static bool IsRestrictedWord(string id) { if (id == "eval" || id == "arguments") { return true; } return false; } [StringMatcher(new string[] { "&&", "||", "==", "!=", "+=", "-=", "*=", "/=", "++", "--", "<<", ">>", "&=", "|=", "^=", "%=", "<=", ">=", "=>", "**" })] private static string? TryGetInternedTwoCharacterPunctuator(ReadOnlySpan id) { return id[0] switch { '!' => (id[1] == '=') ? "!=" : null, '%' => (id[1] == '=') ? "%=" : null, '&' => id[1] switch { '&' => "&&", '=' => "&=", _ => null, }, '*' => id[1] switch { '*' => "**", '=' => "*=", _ => null, }, '+' => id[1] switch { '+' => "++", '=' => "+=", _ => null, }, '-' => id[1] switch { '-' => "--", '=' => "-=", _ => null, }, '/' => (id[1] == '=') ? "/=" : null, '<' => id[1] switch { '<' => "<<", '=' => "<=", _ => null, }, '=' => id[1] switch { '=' => "==", '>' => "=>", _ => null, }, '>' => id[1] switch { '=' => ">=", '>' => ">>", _ => null, }, '^' => (id[1] == '=') ? "^=" : null, '|' => id[1] switch { '=' => "|=", '|' => "||", _ => null, }, _ => null, }; } [StringMatcher(new string[] { "===", "!==", ">>>", "<<=", ">>=", "**=", "&&=", "||=" })] private static string? TryGetInternedThreeCharacterPunctuator(ReadOnlySpan id) { return id[0] switch { '!' => (id[1] == '=' && id[2] == '=') ? "!==" : null, '&' => (id[1] == '&' && id[2] == '=') ? "&&=" : null, '*' => (id[1] == '*' && id[2] == '=') ? "**=" : null, '<' => (id[1] == '<' && id[2] == '=') ? "<<=" : null, '=' => (id[1] == '=' && id[2] == '=') ? "===" : null, '>' => (id[1] != '>') ? null : (id[2] switch { '=' => ">>=", '>' => ">>>", _ => null, }), '|' => (id[1] == '|' && id[2] == '=') ? "||=" : null, _ => null, }; } [StringMatcher(new string[] { "if", "in", "do", "var", "for", "new", "try", "let", "this", "else", "case", "void", "with", "enum", "while", "break", "catch", "throw", "const", "yield", "class", "super", "return", "typeof", "delete", "switch", "export", "import", "default", "finally", "extends", "function", "continue", "debugger", "instanceof" })] public static bool IsKeyword(string id) { return id.Length switch { 2 => id[1] switch { 'o' => id == "do", 'f' => id == "if", 'n' => id == "in", _ => false, }, 3 => id[0] switch { 'f' => id == "for", 'l' => id == "let", 'n' => id == "new", 't' => id == "try", 'v' => id == "var", _ => false, }, 4 => id[1] switch { 'a' => id == "case", 'l' => id == "else", 'n' => id == "enum", 'h' => id == "this", 'o' => id == "void", 'i' => id == "with", _ => false, }, 5 => id[4] switch { 'k' => id == "break", 'h' => id == "catch", 's' => id == "class", 't' => id == "const", 'r' => id == "super", 'w' => id == "throw", 'e' => id == "while", 'd' => id == "yield", _ => false, }, 6 => id[0] switch { 'd' => id == "delete", 'e' => id == "export", 'i' => id == "import", 'r' => id == "return", 's' => id == "switch", 't' => id == "typeof", _ => false, }, 7 => id[0] switch { 'd' => id == "default", 'e' => id == "extends", 'f' => id == "finally", _ => false, }, 8 => id[0] switch { 'c' => id == "continue", 'd' => id == "debugger", 'f' => id == "function", _ => false, }, 10 => id == "instanceof", _ => false, }; } private ArrayList SkipSingleLineComment(int offset) { ArrayList result = default(ArrayList); int num = 0; Position startPosition = default(Position); if (_trackComment) { num = _index - offset; startPosition = new Position(_lineNumber, _index - _lineStart - offset); } while (!Eof()) { char c = _source[_index]; _index++; if (Character.IsLineTerminator(c)) { if (_trackComment) { Position endPosition = new Position(_lineNumber, _index - _lineStart - 1); Range slice = new Range(num + offset, _index - 1); Comment item = new Comment(CommentType.Line, slice, num, _index - 1, startPosition, endPosition); result.Add(item); } if (c == '\r' && _source.CharCodeAt(_index) == '\n') { _index++; } _lineNumber++; _lineStart = _index; return result; } } if (_trackComment) { Position endPosition = new Position(_lineNumber, _index - _lineStart); Range slice = new Range(num + offset, _index); Comment item2 = new Comment(CommentType.Line, slice, num, _index, startPosition, endPosition); result.Add(item2); } return result; } private ArrayList SkipMultiLineComment() { ArrayList result = default(ArrayList); int num = 0; Position startPosition = default(Position); if (_trackComment) { num = _index - 2; startPosition = new Position(_lineNumber, _index - _lineStart - 2); } while (!Eof()) { char c = _source[_index]; if (Character.IsLineTerminator(c)) { if (c == '\r' && _source.CharCodeAt(_index + 1) == '\n') { _index++; } _lineNumber++; _index++; _lineStart = _index; } else if (c == '*') { if (_source.CharCodeAt(_index + 1) == '/') { _index += 2; if (_trackComment) { Position endPosition = new Position(_lineNumber, _index - _lineStart); Range slice = new Range(num + 2, _index - 2); Comment item = new Comment(CommentType.Block, slice, num, _index, startPosition, endPosition); result.Add(item); } return result; } _index++; } else { _index++; } } if (_trackComment) { Position endPosition = new Position(_lineNumber, _index - _lineStart); Range slice = new Range(num + 2, _index); Comment item2 = new Comment(CommentType.Block, slice, num, _index, startPosition, endPosition); result.Add(item2); } TolerateUnexpectedToken(); return result; } internal ArrayList ScanCommentsInternal() { ArrayList result = default(ArrayList); bool flag = _index == 0; while (!Eof()) { char c = _source[_index]; if (Character.IsWhiteSpace(c)) { _index++; continue; } if (Character.IsLineTerminator(c)) { _index++; if (c == '\r' && _source.CharCodeAt(_index) == '\n') { _index++; } _lineNumber++; _lineStart = _index; flag = true; continue; } if (c == '/') { switch (_source.CharCodeAt(_index + 1)) { case '/': { _index += 2; ArrayList arrayList2 = SkipSingleLineComment(2); if (_trackComment) { result.AddRange(arrayList2.AsReadOnlySpan()); } flag = true; continue; } case '*': { _index += 2; ArrayList arrayList = SkipMultiLineComment(); if (_trackComment) { result.AddRange(arrayList.AsReadOnlySpan()); } continue; } } break; } if (flag && c == '-') { if (_source.CharCodeAt(_index + 1) != '-' || _source.CharCodeAt(_index + 2) != '>') { break; } _index += 3; ArrayList arrayList3 = SkipSingleLineComment(3); if (_trackComment) { result.AddRange(arrayList3.AsReadOnlySpan()); } continue; } if (c == '<') { if (_source.CharCodeAt(_index + 1) != '!' || _source.CharCodeAt(_index + 2) != '-' || _source.CharCodeAt(_index + 3) != '-') { break; } if (_isModule) { ThrowUnexpectedToken(); } _index += 4; ArrayList arrayList4 = SkipSingleLineComment(4); if (_trackComment) { result.AddRange(arrayList4.AsReadOnlySpan()); } continue; } if (_index != 0 || c != '#') { break; } if (_source.CharCodeAt(_index + 1) != '!') { ThrowUnexpectedToken(); } _index += 2; while (!Eof()) { c = _source.CharCodeAt(_index); if (c == '/' && _source.CharCodeAt(_index + 1) == '*') { ThrowUnexpectedToken(); } _index++; if (Character.IsLineTerminator(c)) { break; } } } return result; } public ReadOnlySpan ScanComments() { ArrayList arrayList = ScanCommentsInternal(); arrayList.TrimExcess(); return arrayList.AsReadOnlySpan(); } private bool ScanHexEscape(char prefix, out char result) { int num = ((prefix == 'u') ? 4 : 2); int num2 = 0; for (int i = 0; i < num; i++) { if (!Eof()) { char c = _source[_index]; if (Character.IsHexDigit(c)) { num2 = num2 * 16 + System.HexConverter.FromChar(c); _index++; continue; } result = '\0'; return false; } result = '\0'; return false; } result = (char)num2; return true; } private bool TryScanUnicodeCodePointEscape(out int code) { char c = _source.CharCodeAt(_index); code = 0; if (c == '}') { return false; } while (!Eof()) { c = _source[_index++]; if (!Character.IsHexDigit(c)) { break; } code = code * 16 + System.HexConverter.FromChar(c); if (code > 1114111) { return false; } } if (c != '}') { return false; } return true; } private int ScanUnicodeCodePointEscape() { if (!TryScanUnicodeCodePointEscape(out var code)) { ThrowUnexpectedToken((code > 1114111) ? "Undefined Unicode code-point" : "Invalid Unicode escape sequence"); } return code; } private string GetIdentifier(bool allowEscapedSurrogates = false) { int num = _index++; while (!Eof()) { char c = _source[_index]; ushort num2 = c; if (num2 >= 55296) { if (num2 <= 57343) { goto IL_003f; } } else if (num2 == 92) { goto IL_003f; } bool flag = false; goto IL_0047; IL_0047: if (flag) { _index = num; return GetComplexIdentifier(allowEscapedSurrogates); } if (!Character.IsIdentifierPart(c)) { break; } _index++; continue; IL_003f: flag = true; goto IL_0047; } return _source.Between(num, _index).ToInternedString(ref _stringPool); } private string GetComplexIdentifier(bool allowEscapedSurrogates = false) { StringBuilder stringBuilder = GetStringBuilder(); int num = _source.CodePointAt(_index); int cp; if (num != 92) { if (num <= 65535) { if (char.IsSurrogate((char)num)) { ThrowUnexpectedToken(); } stringBuilder.Append((char)num); } else { if (!Character.IsIdentifierStartAstral(num)) { ThrowUnexpectedToken(); } stringBuilder.AppendCodePoint(num); _index++; } _index++; } else { _index++; if (_source.CharCodeAt(_index) != 'u') { ThrowUnexpectedToken(); } _index++; if (_source.CharCodeAt(_index) == '{') { _index++; if (!TryScanUnicodeCodePointEscape(out cp)) { ThrowUnexpectedToken((cp > 1114111) ? "Undefined Unicode code-point" : "Invalid Unicode escape sequence"); } } else { if (!ScanHexEscape('u', out var result) || result == '\\') { ThrowUnexpectedToken(); } if (!char.IsSurrogate(result)) { if (!Character.IsIdentifierStart(result)) { ThrowUnexpectedToken(); } stringBuilder.Append(result); goto IL_037e; } if (!allowEscapedSurrogates || !char.IsHighSurrogate(result) || !TryGetEscapedSurrogate(result, out cp)) { ThrowUnexpectedToken(); cp = 0; } } if (cp > 65535) { if (!Character.IsIdentifierStartAstral(cp)) { ThrowUnexpectedToken(); } stringBuilder.AppendCodePoint(cp); } else { if (char.IsSurrogate((char)cp) || !Character.IsIdentifierStart((char)cp)) { ThrowUnexpectedToken(); } stringBuilder.Append((char)cp); } } goto IL_037e; IL_037e: while (!Eof()) { num = _source.CodePointAt(_index); if (num != 92) { if (num <= 65535) { if (!Character.IsIdentifierPart((char)num)) { break; } if (char.IsSurrogate((char)num)) { ThrowUnexpectedToken(); } stringBuilder.Append((char)num); } else { if (!Character.IsIdentifierPartAstral(num)) { break; } stringBuilder.AppendCodePoint(num); _index++; } _index++; continue; } _index++; if (_source.CharCodeAt(_index) != 'u') { ThrowUnexpectedToken(); } _index++; if (_source.CharCodeAt(_index) == '{') { _index++; if (!TryScanUnicodeCodePointEscape(out cp)) { ThrowUnexpectedToken((cp > 1114111) ? "Undefined Unicode code-point" : "Invalid Unicode escape sequence"); } } else { if (!ScanHexEscape('u', out var result2) || result2 == '\\') { ThrowUnexpectedToken(); } if (!char.IsSurrogate(result2)) { if (!Character.IsIdentifierPart(result2)) { ThrowUnexpectedToken(); } stringBuilder.Append(result2); continue; } if (!allowEscapedSurrogates || !char.IsHighSurrogate(result2) || !TryGetEscapedSurrogate(result2, out cp)) { ThrowUnexpectedToken(); cp = 0; } } if (cp > 65535) { if (!Character.IsIdentifierPartAstral(cp)) { ThrowUnexpectedToken(); } stringBuilder.AppendCodePoint(cp); } else { if (char.IsSurrogate((char)cp) || !Character.IsIdentifierPart((char)cp)) { ThrowUnexpectedToken(); } stringBuilder.Append((char)cp); } } return stringBuilder.ToString().AsSpan().ToInternedString(ref _stringPool); } private bool TryGetEscapedSurrogate(char highSurrogate, out int cp) { if (_index + 1 < _source.Length && _source[_index] == '\\' && _source[_index + 1] == 'u') { _index += 2; if (ScanHexEscape('u', out var result) && char.IsLowSurrogate(result)) { cp = char.ConvertToUtf32(highSurrogate, result); return true; } } cp = 0; return false; } private int OctalToDecimal(char ch, out int length) { int num = OctalValue(ch); length = 1; if (!Eof() && Character.IsOctalDigit(_source[_index])) { num = num * 8 + OctalValue(_source[_index++]); length++; if (ch >= '0' && ch <= '3' && !Eof() && Character.IsOctalDigit(_source[_index])) { num = num * 8 + OctalValue(_source[_index++]); length++; } } return num; } private Token ScanIdentifier(bool allowEscapes) { int index = _index; ushort num = _source[_index]; if (num >= 55296) { if (num <= 57343) { goto IL_0030; } } else if (num == 92) { goto IL_0030; } bool flag = false; goto IL_0038; IL_0038: string text = (flag ? GetComplexIdentifier() : GetIdentifier()); TokenType tokenType = ((text.Length == 1) ? TokenType.Identifier : (IsKeyword(text) ? TokenType.Keyword : ("null".Equals(text, StringComparison.Ordinal) ? TokenType.NullLiteral : (("true".Equals(text, StringComparison.Ordinal) || "false".Equals(text, StringComparison.Ordinal)) ? TokenType.BooleanLiteral : TokenType.Identifier)))); if (tokenType != TokenType.Identifier && index + text.Length != _index) { int index2 = _index; _index = index; if (!allowEscapes) { TolerateUnexpectedToken("Keyword must not contain escaped characters"); } _index = index2; } return Token.Create(tokenType, text, index, _index, _lineNumber, _lineStart); IL_0030: flag = true; goto IL_0038; } private Token ScanPunctuator() { int index = _index; char c = _source[_index]; string str = ParserExtensions.CharToString(c); switch (c) { case '(': _index++; break; case '{': _curlyStack.Add("{"); _index++; break; case '.': _index++; if (_source.Length >= _index + 2 && _source[_index] == '.' && _source[_index + 1] == '.') { _index += 2; str = "..."; } break; case '}': _index++; if (_curlyStack.Count > 0) { _curlyStack.RemoveAt(_curlyStack.Count - 1); } break; case '?': _index++; if (_source.CharCodeAt(_index) == '?') { _index++; if (_source.CharCodeAt(_index) == '=') { _index++; str = "??="; } else { str = "??"; } } if (_source.CharCodeAt(_index) == '.' && !char.IsDigit(_source.CharCodeAt(_index + 1))) { _index++; str = "?."; } break; case '#': _index++; if (_source.CharCodeAt(_index) == '!') { _index++; str = "#!"; } break; case ')': case ',': case ':': case ';': case '@': case '[': case ']': case '~': _index++; break; default: if (_index + 4 <= _source.Length && _source.AsSpan(_index, 4).SequenceEqual(">>>=".AsSpan())) { _index += 4; str = ">>>="; break; } if (_index + 3 <= _source.Length && (str = TryGetInternedThreeCharacterPunctuator(_source.AsSpan(_index, 3))) != null) { _index += 3; break; } if (_index + 2 <= _source.Length && (str = TryGetInternedTwoCharacterPunctuator(_source.AsSpan(_index, 2))) != null) { _index += 2; break; } str = ParserExtensions.CharToString(c); if ("<>=!+-*%&|^/".Contains(c)) { _index++; } break; } if (_index == index) { ThrowUnexpectedToken(); } return Token.CreatePunctuator(str, index, _index, _lineNumber, _lineStart); } private Token ScanHexLiteral(int start) { ReadOnlySpan readOnlySpan = ScanLiteralPart(Character.IsHexDigitFunc, allowNumericSeparator: true); if (readOnlySpan.Length == 0) { ThrowUnexpectedToken(); } char c = _source.CharCodeAt(_index); if (Character.IsIdentifierStart(c)) { if (c == 'n') { _index++; return ScanBigIntLiteral(start, readOnlySpan, JavaScriptNumberStyle.Hex); } ThrowUnexpectedToken(); } double value = ((readOnlySpan.Length > 16) ? ParseIntAsDouble(readOnlySpan, 16) : ((double)ulong.Parse(readOnlySpan.ToParsable(), NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture))); return Token.CreateNumericLiteral(value, octal: false, start, _index, _lineNumber, _lineStart); } private static double ParseIntAsDouble(ReadOnlySpan number, byte fromBase) { double num = 0.0; double num2 = 1.0; int num3 = number.Length; while (num3 > 0) { char c = number[--num3]; ushort num4; if (c >= 'a') { num4 = (ushort)(c - 87); } else if (c >= 'A') { num4 = (ushort)(c - 55); } else { if (c < '0' || c > '9') { break; } num4 = (ushort)(c - 48); } num += num2 * (double)(int)num4; num2 *= (double)(int)fromBase; } return num; } private Token ScanBigIntLiteral(int start, ReadOnlySpan number, JavaScriptNumberStyle style) { BigInteger value = 0; if ((style == JavaScriptNumberStyle.Binary || style == JavaScriptNumberStyle.Octal) ? true : false) { int num = ((style == JavaScriptNumberStyle.Binary) ? 1 : 3); ReadOnlySpan readOnlySpan = number; for (int i = 0; i < readOnlySpan.Length; i++) { char c = readOnlySpan[i]; value <<= num; value += (BigInteger)(c - 48); } } else { NumberStyles style2; if (style == JavaScriptNumberStyle.Hex) { char c2 = number[0]; if (c2 > '7' && Character.IsHexDigit(c2)) { number = ("0" + number).AsSpan(); } style2 = NumberStyles.AllowHexSpecifier; } else { style2 = NumberStyles.None; } value = BigInteger.Parse(number.ToParsable(), style2, CultureInfo.InvariantCulture); } return Token.CreateBigIntLiteral(value, start, _index, _lineNumber, _lineStart); } private Token ScanBinaryLiteral(int start) { ReadOnlySpan number = ScanLiteralPart((char c2) => (c2 == '0' || c2 == '1') ? true : false, allowNumericSeparator: true); if (number.Length == 0) { ThrowUnexpectedToken(); } if (!Eof()) { char c = _source[_index]; if (c == 'n') { _index++; return ScanBigIntLiteral(start, number, JavaScriptNumberStyle.Binary); } if (Character.IsIdentifierStart(c) || Character.IsDecimalDigit(c)) { ThrowUnexpectedToken(); } } double value = ((number.Length > 64) ? ParseIntAsDouble(number, 2) : ((double)Convert.ToUInt64(number.ToString(), 2))); return Token.CreateNumericLiteral(value, octal: false, start, _index, _lineNumber, _lineStart); } private Token ScanOctalLiteral(char prefix, int start, bool isLegacyOctalDigital = false) { StringBuilder stringBuilder = GetStringBuilder(); bool flag = false; if (Character.IsOctalDigit(prefix)) { flag = true; stringBuilder.Append('0').Append(_source[_index++]); } else { _index++; } stringBuilder.Append(ScanLiteralPart(Character.IsOctalDigitFunc, !isLegacyOctalDigital)); string text = stringBuilder.ToString(); if (!flag && text.Length == 0) { ThrowUnexpectedToken(); } char c = _source.CharCodeAt(_index); if (c == 'n') { if (isLegacyOctalDigital) { ThrowUnexpectedToken(); } _index++; return ScanBigIntLiteral(start, text.AsSpan(), JavaScriptNumberStyle.Octal); } if (Character.IsIdentifierStart(c) || Character.IsDecimalDigit(c)) { ThrowUnexpectedToken(); } double value = ((text.Length > 21) ? ParseIntAsDouble(text.AsSpan(), 8) : ((double)Convert.ToUInt64(text.ToString(), 8))); return Token.CreateNumericLiteral(value, flag, start, _index, _lineNumber, _lineStart); } private bool IsImplicitOctalLiteral() { for (int i = _index + 1; i < _length; i++) { char c = _source[i]; if (c == '8' || c == '9') { return false; } if (!Character.IsOctalDigit(c)) { return true; } } return true; } private ReadOnlySpan ScanLiteralPart(Func check, bool allowNumericSeparator) { int index = _index; char c = _source.CharCodeAt(_index); if (c == '_') { ThrowUnexpectedToken("Numeric separator is not allowed here"); } bool flag = false; while (check(c) || c == '_') { if (c == '_') { if (!allowNumericSeparator) { ThrowUnexpectedToken(); } flag = true; } _index++; char c2 = _source.CharCodeAt(_index); if (c == '_') { if (c2 == '_') { ThrowUnexpectedToken("Numeric separator must be exactly one underscore"); } if (c2 == 'n') { ThrowUnexpectedToken("Numeric separator is not allowed here"); } } if (Eof()) { break; } c = c2; } if (_source[_index - 1] == '_') { ThrowUnexpectedToken("Numeric separator is not allowed here"); } ReadOnlySpan result = _source.AsSpan(index, _index - index); if (!flag) { return result; } return result.ToString().Replace("_", "").AsSpan(); } private Token ScanNumericLiteral(bool strict) { StringBuilder stringBuilder = GetStringBuilder(); int index = _index; char c = _source[index]; bool flag = false; if (c != '.') { char num = _source[_index++]; c = _source.CharCodeAt(_index); if (num == '0') { if ((c == 'X' || c == 'x') ? true : false) { _index++; return ScanHexLiteral(index); } if ((c == 'B' || c == 'b') ? true : false) { _index++; return ScanBinaryLiteral(index); } if ((c == 'O' || c == 'o') ? true : false) { return ScanOctalLiteral(c, index); } if (c == '_') { TolerateUnexpectedToken("Numeric separator can not be used after leading 0"); } flag = char.IsNumber(c); if (flag && strict) { ThrowUnexpectedToken("Decimals with leading zeros are not allowed in strict mode."); } if (c > '\0' && Character.IsOctalDigit(c) && IsImplicitOctalLiteral()) { return ScanOctalLiteral(c, index, isLegacyOctalDigital: true); } } _index--; stringBuilder.Append(ScanLiteralPart(Character.IsDecimalDigitFunc, !flag)); c = _source.CharCodeAt(_index); } if (c == '.') { stringBuilder.Append(_source[_index++]); stringBuilder.Append(ScanLiteralPart(Character.IsDecimalDigitFunc, !flag)); c = _source.CharCodeAt(_index); } string text; switch (c) { case 'E': case 'e': stringBuilder.Append(_source[_index++]); c = _source.CharCodeAt(_index); if (c == '+' || c == '-') { stringBuilder.Append(_source[_index++]); } if (Character.IsDecimalDigit(_source.CharCodeAt(_index))) { stringBuilder.Append(ScanLiteralPart(Character.IsDecimalDigitFunc, allowNumericSeparator: true)); } else { ThrowUnexpectedToken(); } break; case 'n': text = stringBuilder.ToString(); if (flag || text.Contains('.')) { ThrowUnexpectedToken(); } _index++; return ScanBigIntLiteral(index, text.AsSpan(), JavaScriptNumberStyle.Integer); } if (Character.IsIdentifierStart(_source.CharCodeAt(_index))) { ThrowUnexpectedToken(); } text = stringBuilder.ToString(); double value; double result2; if (long.TryParse(text, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent, CultureInfo.InvariantCulture, out var result)) { value = result; } else if (double.TryParse(text, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent, CultureInfo.InvariantCulture, out result2)) { value = result2; } else { result2 = (text.TrimStart().StartsWith('-') ? double.NegativeInfinity : double.PositiveInfinity); value = result2; } return Token.CreateNumericLiteral(value, octal: false, index, _index, _lineNumber, _lineStart); } private Token ScanStringLiteral(bool strict) { int index = _index; int lineNumber = _lineNumber; int lineStart = _lineStart; char c = _source[index]; _index++; LegacyOctalKind octalKind = LegacyOctalKind.None; StringBuilder stringBuilder = GetStringBuilder(); while (!Eof()) { char c2 = _source[_index]; _index++; if (c2 == c) { c = '\0'; break; } if (c2 == '\\') { if (_index >= _source.Length) { break; } c2 = _source[_index]; _index++; if (!Character.IsLineTerminator(c2)) { switch (c2) { case 'u': { if (_source.CharCodeAt(_index) == '{') { _index++; stringBuilder.AppendCodePoint(ScanUnicodeCodePointEscape()); continue; } if (!ScanHexEscape(c2, out var result2)) { ThrowUnexpectedToken(); } stringBuilder.Append(result2); continue; } case 'x': { if (!ScanHexEscape(c2, out var result)) { ThrowUnexpectedToken("Invalid hexadecimal escape sequence"); } stringBuilder.Append(result); continue; } case 'n': stringBuilder.Append('\n'); continue; case 'r': stringBuilder.Append('\r'); continue; case 't': stringBuilder.Append('\t'); continue; case 'b': stringBuilder.Append('\b'); continue; case 'f': stringBuilder.Append('\f'); continue; case 'v': stringBuilder.Append('\v'); continue; case '8': case '9': stringBuilder.Append(c2); octalKind = LegacyOctalKind.Escaped8or9; if (strict) { TolerateUnexpectedToken("\\8 and \\9 are not allowed in strict mode."); } continue; } if (Character.IsOctalDigit(c2)) { int length; int num = OctalToDecimal(c2, out length); bool flag = num != 0 || length > 1; if (!flag) { char c3 = _source.CharCodeAt(_index); bool flag2 = ((c3 == '8' || c3 == '9') ? true : false); flag = flag2; } if (flag) { octalKind = LegacyOctalKind.Octal; if (strict) { TolerateUnexpectedToken("Octal literals are not allowed in strict mode."); } } stringBuilder.Append((char)num); } else { stringBuilder.Append(c2); } } else { _lineNumber++; if (c2 == '\r' && _source.CharCodeAt(_index) == '\n') { _index++; } _lineStart = _index; } } else if (Character.IsLineTerminator(c2)) { if ((c2 != '\u2028' && c2 != '\u2029') || 1 == 0) { break; } _lineNumber++; _lineStart = _index; stringBuilder.Append(c2); } else { stringBuilder.Append(c2); } } if (c != 0) { _index = index; _lineNumber = lineNumber; _lineStart = lineStart; ThrowUnexpectedToken(); } return Token.CreateStringLiteral(stringBuilder.ToString(), octalKind, index, _index, _lineNumber, _lineStart); } private Token ScanTemplate() { StringBuilder stringBuilder = GetStringBuilder(); bool flag = false; int index = _index; bool flag2 = _source[index] == '`'; bool tail = false; char c = '\0'; int num = 2; bool flag3 = false; _index++; while (!Eof()) { char c2 = _source[_index++]; switch (c2) { case '`': num = 1; tail = true; flag = true; break; case '$': if (_source.CharCodeAt(_index) == '{') { _curlyStack.Add("${"); _index++; flag = true; break; } stringBuilder.Append(c2); continue; default: if (c != 0) { continue; } if (c2 == '\\') { if (_index >= _source.Length) { break; } c2 = _source[_index++]; if (!Character.IsLineTerminator(c2)) { switch (c2) { case 'n': stringBuilder.Append('\n'); break; case 'r': stringBuilder.Append('\r'); break; case 't': stringBuilder.Append('\t'); break; case 'u': { char result; if (_source.CharCodeAt(_index) == '{') { _index++; if (!TryScanUnicodeCodePointEscape(out var code)) { c = ((code > 1114111) ? 'v' : 'u'); } else { stringBuilder.AppendCodePoint(code); } } else if (!ScanHexEscape(c2, out result)) { c = 'u'; } else { stringBuilder.Append(result); } break; } case 'x': { if (!ScanHexEscape(c2, out var result2)) { c = 'x'; } else { stringBuilder.Append(result2); } break; } case 'b': stringBuilder.Append('\b'); break; case 'f': stringBuilder.Append('\f'); break; case 'v': stringBuilder.Append('\v'); break; case '0': if (Character.IsDecimalDigit(_source.CharCodeAt(_index))) { c = '0'; } else { stringBuilder.Append('\0'); } break; default: if (Character.IsDecimalDigit(c2)) { c = c2; } else { stringBuilder.Append(c2); } break; } continue; } _lineNumber++; if (c2 == '\r') { flag3 = true; if (_source.CharCodeAt(_index) == '\n') { _index++; } } _lineStart = _index; continue; } if (Character.IsLineTerminator(c2)) { _lineNumber++; if (c2 == '\r') { flag3 = true; if (_source.CharCodeAt(_index) == '\n') { _index++; } c2 = '\n'; } _lineStart = _index; stringBuilder.Append(c2); } else { stringBuilder.Append(c2); } continue; } break; } if (!flag) { ThrowUnexpectedToken(); } if (!flag2) { _curlyStack.RemoveAt(_curlyStack.Count - 1); } string cooked = ((c == '\0') ? stringBuilder.ToString() : null); int num2 = index + 1; int num3 = _index - num; ReadOnlySpan source = _source.AsSpan(num2, num3 - num2); if (flag3) { stringBuilder.Clear(); if (stringBuilder.Capacity < source.Length) { stringBuilder.Capacity = source.Length; } for (int i = 0; i < source.Length; i++) { char c2 = source[i]; if (c2 == '\r') { if (i + 1 < source.Length && source[i + 1] == '\n') { i++; } c2 = '\n'; } stringBuilder.Append(c2); } source = stringBuilder.ToString().AsSpan(); } return Token.CreateTemplate(cooked, source.ToInternedString(ref _stringPool, 20), flag2, tail, c, index, _index, _lineNumber, _lineStart); } public static bool ValidateRegExp(string pattern, string flags, out ParseError? error) { if (pattern == null) { throw new ArgumentNullException("pattern"); } if (flags == null) { throw new ArgumentNullException("flags"); } ScannerOptions scannerOptions = new ScannerOptions { RegExpParseMode = RegExpParseMode.Validate, Tolerant = false }; try { new RegExpParser(pattern, flags, scannerOptions).Parse(); } catch (ParserException ex) { error = ex.Error; return false; } error = null; return true; } public static RegExpParseResult AdaptRegExp(string pattern, string flags, bool compiled = false, TimeSpan? matchTimeout = null, bool throwIfNotAdaptable = false) { if (pattern == null) { throw new ArgumentNullException("pattern"); } if (flags == null) { throw new ArgumentNullException("flags"); } ScannerOptions scannerOptions = ScannerOptions.Default; TimeSpan valueOrDefault = matchTimeout.GetValueOrDefault(); if (!matchTimeout.HasValue) { valueOrDefault = scannerOptions.RegexTimeout; matchTimeout = valueOrDefault; } RegExpParseMode regExpParseMode = ((!compiled) ? RegExpParseMode.AdaptToInterpreted : RegExpParseMode.AdaptToCompiled); bool flag = !throwIfNotAdaptable; ScannerOptions scannerOptions2 = ((regExpParseMode == scannerOptions.RegExpParseMode && matchTimeout.Value == scannerOptions.RegexTimeout && flag == scannerOptions.Tolerant) ? ScannerOptions.Default : new ScannerOptions { RegExpParseMode = regExpParseMode, RegexTimeout = matchTimeout.Value, Tolerant = flag }); return new RegExpParser(pattern, flags, scannerOptions2).Parse(); } private string ScanRegExpBody() { StringBuilder stringBuilder = GetStringBuilder(); stringBuilder.Append(_source[_index++]); bool flag = false; bool flag2 = false; while (!Eof()) { char c = _source[_index++]; stringBuilder.Append(c); if (c == '\\') { if (_index >= _source.Length) { break; } c = _source[_index++]; if (Character.IsLineTerminator(c)) { ThrowUnexpectedToken("Invalid regular expression: missing /"); } stringBuilder.Append(c); continue; } if (Character.IsLineTerminator(c)) { ThrowUnexpectedToken("Invalid regular expression: missing /"); continue; } if (flag) { if (c == ']') { flag = false; } continue; } switch (c) { case '/': break; case '[': flag = true; continue; default: continue; } flag2 = true; break; } if (!flag2) { ThrowUnexpectedToken("Invalid regular expression: missing /"); } return stringBuilder.ToString(1, stringBuilder.Length - 2); } private string ScanRegExpFlags() { string text = ""; while (!Eof()) { char c = _source[_index]; if (!Character.IsIdentifierStart(c)) { break; } _index++; if (c == '\\' && !Eof()) { c = _source[_index]; if (c == 'u') { _index++; int index = _index; if (ScanHexEscape('u', out c)) { text += c; } else { _index = index; text += "u"; } TolerateUnexpectedToken(); } else { TolerateUnexpectedToken(); } } else { text += c; } } return text; } internal Token ScanRegExp() { int index = _index; string pattern = ScanRegExpBody(); int index2 = _index; string flags = ScanRegExpFlags(); return Token.CreateRegExpLiteral((_regExpParseMode != RegExpParseMode.Skip) ? new RegExpParser(pattern, index + 1, flags, index2, this).Parse() : default(RegExpParseResult), new RegexValue(pattern, flags), index, _index, _lineNumber, _lineStart); } public Token Lex() { return Lex(default(LexOptions)); } internal Token Lex(in LexOptions options) { if (Eof()) { ReleaseLargeBuffers(); return Token.CreateEof(_index, _lineNumber, _lineStart); } char c = _source[_index]; if (Character.IsIdentifierStart(c)) { return ScanIdentifier(options.AllowIdentifierEscape); } switch (c) { case '(': case ')': case ';': return ScanPunctuator(); case '"': case '\'': return ScanStringLiteral(options.Strict); case '.': if (Character.IsDecimalDigit(_source.CharCodeAt(_index + 1))) { return ScanNumericLiteral(options.Strict); } return ScanPunctuator(); default: if (Character.IsDecimalDigit(c)) { return ScanNumericLiteral(options.Strict); } if (c == '`' || (c == '}' && _curlyStack.Count > 0 && _curlyStack[_curlyStack.Count - 1] == "${")) { return ScanTemplate(); } return ScanPunctuator(); } } internal Marker GetMarker() { return new Marker(_index, _lineNumber, _index - _lineStart); } } public readonly struct RegExpParseResult { private readonly object? _regexOrConversionError; private readonly ArrayList _capturingGroups; public bool Success { get { object regexOrConversionError = _regexOrConversionError; bool flag = ((regexOrConversionError == null || regexOrConversionError is ParseError) ? true : false); return !flag; } } public ParseError? ConversionError => _regexOrConversionError as ParseError; public Regex? Regex => _regexOrConversionError as Regex; public int ActualRegexGroupCount => _capturingGroups.Count + 1; internal RegExpParseResult(Regex regex, ArrayList capturingGroups) { _regexOrConversionError = regex; _capturingGroups = capturingGroups; } internal RegExpParseResult(ParseError? conversionError) { _capturingGroups = default(ArrayList); _regexOrConversionError = ((object)conversionError) ?? ((object)"Success"); } public string? GetRegexGroupName(int number) { if ((uint)(--number) >= (uint)_capturingGroups.Count) { return null; } return _capturingGroups[number].Name; } } public enum RegExpParseMode { Skip, Validate, AdaptToInterpreted, AdaptToCompiled } public record ScannerOptions { public bool Comments { get { return _comments; } init { _comments = value; } } public bool Tolerant { get { return _tolerant; } init { _tolerant = value; } } public ErrorHandler ErrorHandler { get { return _errorHandler; } init { _errorHandler = value; } } public RegExpParseMode RegExpParseMode { get { return _regExpParseMode; } init { _regExpParseMode = value; } } public TimeSpan RegexTimeout { get { return _regexTimeout; } init { _regexTimeout = value; } } public static readonly ScannerOptions Default = new ScannerOptions(); internal bool _comments; internal bool _tolerant = true; internal ErrorHandler _errorHandler = Esprima.ErrorHandler.Default; internal RegExpParseMode _regExpParseMode = RegExpParseMode.AdaptToInterpreted; internal TimeSpan _regexTimeout = TimeSpan.FromSeconds(10.0); [CompilerGenerated] protected virtual bool PrintMembers(StringBuilder builder) { RuntimeHelpers.EnsureSufficientExecutionStack(); builder.Append("Comments = "); builder.Append(Comments.ToString()); builder.Append(", Tolerant = "); builder.Append(Tolerant.ToString()); builder.Append(", ErrorHandler = "); builder.Append(ErrorHandler); builder.Append(", RegExpParseMode = "); builder.Append(RegExpParseMode.ToString()); builder.Append(", RegexTimeout = "); builder.Append(RegexTimeout.ToString()); return true; } [CompilerGenerated] protected ScannerOptions(ScannerOptions original) { _comments = original._comments; _tolerant = original._tolerant; _errorHandler = original._errorHandler; _regExpParseMode = original._regExpParseMode; _regexTimeout = original._regexTimeout; } public ScannerOptions() { } } internal static class Shims { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static UnicodeCategory GetUnicodeCategory(int codePoint) { return CharUnicodeInfo.GetUnicodeCategory(codePoint); } } internal struct StringPool { private struct Entry { public int HashCode; public int Next; public string Value; } private const int MinAllocatedCount = 4; private int[]? _buckets; private Entry[]? _entries; private int _count; public int Count { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _count; } } private int Initialize(int capacity) { int[] buckets = new int[capacity]; Entry[] entries = new Entry[capacity]; _buckets = buckets; _entries = entries; return capacity; } private void Resize(int newSize) { Entry[] array = new Entry[newSize]; int count = _count; Array.Copy(_entries, array, count); _buckets = new int[newSize]; for (int i = 0; i < count; i++) { ref Entry reference = ref array[i]; if (reference.Next >= -1) { ref int bucketRef = ref GetBucketRef(reference.HashCode); reference.Next = bucketRef - 1; bucketRef = i + 1; } } _entries = array; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private ref int GetBucketRef(int hashCode) { int[] buckets = _buckets; return ref buckets[(uint)hashCode % (uint)buckets.Length]; } public string GetOrCreate(ReadOnlySpan value) { if (_buckets == null) { Initialize(4); } Entry[] entries = _entries; uint num = 0u; int hashCode = GetHashCode(value); ref int bucketRef = ref GetBucketRef(hashCode); int num2 = bucketRef - 1; while (num2 >= 0) { ref Entry reference = ref entries[num2]; if (reference.HashCode == hashCode && reference.Value.AsSpan().SequenceEqual(value)) { return reference.Value; } num2 = reference.Next; num++; if (num > (uint)entries.Length) { throw new InvalidOperationException("A concurrent update was performed on this object and corrupted its state."); } } int count = _count; int num3; checked { if (count == entries.Length) { Resize(_count + unchecked(_count / 2)); bucketRef = ref GetBucketRef(hashCode); } num3 = count; } _count = count + 1; entries = _entries; ref Entry reference2 = ref entries[num3]; reference2.HashCode = hashCode; reference2.Next = bucketRef - 1; reference2.Value = value.ToString(); bucketRef = num3 + 1; return reference2.Value; } private static int GetHashCode(ReadOnlySpan span) { int num = 5381; while (span.Length >= 8) { num = ((num << 5) + num) ^ span[0].GetHashCode(); num = ((num << 5) + num) ^ span[1].GetHashCode(); num = ((num << 5) + num) ^ span[2].GetHashCode(); num = ((num << 5) + num) ^ span[3].GetHashCode(); num = ((num << 5) + num) ^ span[4].GetHashCode(); num = ((num << 5) + num) ^ span[5].GetHashCode(); num = ((num << 5) + num) ^ span[6].GetHashCode(); num = ((num << 5) + num) ^ span[7].GetHashCode(); span = span.Slice(8); } if (span.Length >= 4) { num = ((num << 5) + num) ^ span[0].GetHashCode(); num = ((num << 5) + num) ^ span[1].GetHashCode(); num = ((num << 5) + num) ^ span[2].GetHashCode(); num = ((num << 5) + num) ^ span[3].GetHashCode(); span = span.Slice(4); } if (span.Length > 0) { num = ((num << 5) + num) ^ span[0].GetHashCode(); if (span.Length > 1) { num = ((num << 5) + num) ^ span[1].GetHashCode(); if (span.Length > 2) { num = ((num << 5) + num) ^ span[2].GetHashCode(); } } } return num; } } public enum TokenType : byte { Unknown = 0, BooleanLiteral = 1, EOF = 2, Identifier = 3, Keyword = 4, NullLiteral = 5, NumericLiteral = 6, Punctuator = 7, StringLiteral = 8, RegularExpression = 9, Template = 10, BigIntLiteral = 11, Extension = byte.MaxValue } internal enum LegacyOctalKind : byte { None, Octal, Escaped8or9 } [StructLayout(LayoutKind.Auto)] public readonly record struct Token { internal abstract record ValueHolder(object? Value); private sealed record RegexHolder(RegExpParseResult ParseResult, RegexValue RegexValue) : ValueHolder(ParseResult.Regex); private sealed record TemplateHolder : ValueHolder { public string RawTemplate { get; init; } public char NotEscapeSequenceHead { get; init; } public bool Head { get; init; } public bool Tail { get; init; } public TemplateHolder(object? Value, string RawTemplate, char NotEscapeSequenceHead, bool Head, bool Tail) { this.RawTemplate = RawTemplate; this.NotEscapeSequenceHead = NotEscapeSequenceHead; this.Head = Head; this.Tail = Tail; base..ctor(Value); } [CompilerGenerated] public void Deconstruct(out object? Value, out string RawTemplate, out char NotEscapeSequenceHead, out bool Head, out bool Tail) { Value = base.Value; RawTemplate = this.RawTemplate; NotEscapeSequenceHead = this.NotEscapeSequenceHead; Head = this.Head; Tail = this.Tail; } } public bool Octal => OctalKind == LegacyOctalKind.Octal; public object? Value { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { TokenType type = Type; if ((type - 9 <= TokenType.BooleanLiteral || type == TokenType.Extension) ? true : false) { return GetValueFromHolder(in this); } return _value; [MethodImpl(MethodImplOptions.NoInlining)] static object? GetValueFromHolder(in Token token) { return ((ValueHolder)token._value).Value; } } } internal char NotEscapeSequenceHead { get { if (Type != TokenType.Template) { return '\0'; } return ((TemplateHolder)_value).NotEscapeSequenceHead; } } public bool Head { get { if (Type == TokenType.Template) { return ((TemplateHolder)_value).Head; } return false; } } public bool Tail { get { if (Type == TokenType.Template) { return ((TemplateHolder)_value).Tail; } return false; } } public string? RawTemplate { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { if (Type != TokenType.Template) { return null; } return ((TemplateHolder)_value).RawTemplate; } } public RegExpParseResult RegExpParseResult { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { if (Type != TokenType.RegularExpression) { return default(RegExpParseResult); } return ((RegexHolder)_value).ParseResult; } } public RegexValue? RegexValue { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { if (Type != TokenType.RegularExpression) { return null; } return ((RegexHolder)_value).RegexValue; } } internal readonly object? _value; public readonly TokenType Type; internal readonly LegacyOctalKind OctalKind; public readonly int Start; public readonly int End; public readonly int LineNumber; public readonly int LineStart; internal Token(TokenType type, object? value, int start, int end, int lineNumber, int lineStart, LegacyOctalKind octalKind = LegacyOctalKind.None) { Type = type; _value = value; OctalKind = octalKind; Start = start; End = end; LineNumber = lineNumber; LineStart = lineStart; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static Token Create(TokenType type, object? value, int start, int end, int lineNumber, int lineStart) { return new Token(type, value, start, end, lineNumber, lineStart); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static Token CreateStringLiteral(string str, LegacyOctalKind octalKind, int start, int end, int lineNumber, int lineStart) { return new Token(TokenType.StringLiteral, str, start, end, lineNumber, lineStart, octalKind); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static Token CreateRegExpLiteral(RegExpParseResult parseResult, RegexValue regexValue, int start, int end, int lineNumber, int lineStart) { return new Token(TokenType.RegularExpression, new RegexHolder(parseResult, regexValue), start, end, lineNumber, lineStart); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static Token CreateNumericLiteral(double value, bool octal, int start, int end, int lineNumber, int lineStart) { return new Token(TokenType.NumericLiteral, value, start, end, lineNumber, lineStart, octal ? LegacyOctalKind.Octal : LegacyOctalKind.None); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static Token CreateBigIntLiteral(BigInteger value, int start, int end, int lineNumber, int lineStart) { return new Token(TokenType.BigIntLiteral, value, start, end, lineNumber, lineStart); } internal static Token CreateEof(int index, int lineNumber, int lineStart) { return new Token(TokenType.EOF, null, index, index, lineNumber, lineStart); } internal static Token CreatePunctuator(string str, int start, int end, int lineNumber, int lineStart) { return new Token(TokenType.Punctuator, str, start, end, lineNumber, lineStart); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static Token CreateTemplate(string? cooked, string rawTemplate, bool head, bool tail, char notEscapeSequenceHead, int start, int end, int lineNumber, int lineStart) { TemplateHolder value = new TemplateHolder(cooked, rawTemplate, notEscapeSequenceHead, head, tail); return new Token(TokenType.Template, value, start, end, lineNumber, lineStart); } internal Token ChangeType(TokenType newType) { return new Token(newType, _value, Start, End, LineNumber, LineStart, OctalKind); } internal bool IsEscaped(string value) { return value.Length != End - Start; } [CompilerGenerated] private bool PrintMembers(StringBuilder builder) { builder.Append("Type = "); builder.Append(Type.ToString()); builder.Append(", Octal = "); builder.Append(Octal.ToString()); builder.Append(", Start = "); builder.Append(Start.ToString()); builder.Append(", End = "); builder.Append(End.ToString()); builder.Append(", LineNumber = "); builder.Append(LineNumber.ToString()); builder.Append(", LineStart = "); builder.Append(LineStart.ToString()); builder.Append(", Value = "); builder.Append(Value); builder.Append(", Head = "); builder.Append(Head.ToString()); builder.Append(", Tail = "); builder.Append(Tail.ToString()); builder.Append(", RawTemplate = "); builder.Append((object?)RawTemplate); builder.Append(", RegExpParseResult = "); builder.Append(RegExpParseResult.ToString()); builder.Append(", RegexValue = "); builder.Append(RegexValue); return true; } } [AttributeUsage(AttributeTargets.Method)] internal class StringMatcherAttribute : Attribute { public string[] Targets { get; } public StringMatcherAttribute(params string[] targets) { Targets = targets; } } } namespace Esprima.Utils { internal struct AdditionalDataHolder { public object? Data; } internal struct AdditionalDataSlot { private object? _data; public object? PrimaryData { get { return GetPrimaryDataRef(ref this); } set { GetPrimaryDataRef(ref this) = value; } } public object? this[int index] { get { if (index == 0) { return GetPrimaryDataRef(ref this); } if (!(_data is AdditionalDataHolder[] array) || (uint)index >= (uint)array.Length) { return null; } return array[index].Data; } set { if (index == 0) { GetPrimaryDataRef(ref this) = value; return; } AdditionalDataHolder[] array = _data as AdditionalDataHolder[]; if (array != null) { if ((uint)index >= (uint)array.Length) { if (value == null) { return; } Array.Resize(ref array, index + 1); _data = array; } } else { if (value == null) { return; } array = new AdditionalDataHolder[index + 1]; array[0].Data = _data; _data = array; } array[index].Data = value; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ref object? GetPrimaryDataRef(ref AdditionalDataSlot slot) { if (slot._data is AdditionalDataHolder[] array) { return ref array[0].Data; } return ref slot._data; } } [AutoGeneratedAstVisitor] public class AstRewriter : AstVisitor { public virtual T VisitAndConvert(T node, bool allowNull = false, [CallerMemberName] string? callerName = null) where T : Node? { if (node == null) { if (!allowNull) { throw new ArgumentNullException("node"); } return null; } object obj = Visit(node); if (!(obj is T result)) { if (obj == null) { if (allowNull) { return null; } throw MustRewriteToSameNodeNonNullable(typeof(T), callerName); } throw allowNull ? MustRewriteToSameNodeNullable(typeof(T), callerName) : MustRewriteToSameNodeNonNullable(typeof(T), callerName); } return result; static Exception MustRewriteToSameNodeNonNullable(Type nodeType, string? text) { return new InvalidOperationException($"When called from {text}, rewriting a node of type {nodeType} must return a non-null value of the same type. Alternatively, override {text} and change it to not visit children of this type."); } static Exception MustRewriteToSameNodeNullable(Type nodeType, string? text) { return new InvalidOperationException($"When called from {text}, rewriting a node of type {nodeType} must return null or a non-null value of the same type. Alternatively, override {text} and change it to not visit children of this type."); } } public virtual bool VisitAndConvert(in NodeList nodes, out NodeList newNodes, bool allowNullElement = false, [CallerMemberName] string? callerName = null) where T : Node? { List list = null; for (int i = 0; i < nodes.Count; i++) { T val = nodes[i]; T val2 = VisitAndConvert(val, allowNullElement, callerName); if (list != null) { list.Add(val2); } else if (val2 != val) { list = new List(); for (int j = 0; j < i; j++) { list.Add(nodes[j]); } list.Add(val2); } } if (list != null) { newNodes = new NodeList(list); return true; } newNodes = nodes; return false; } protected internal override object? VisitExportSpecifier(ExportSpecifier exportSpecifier) { Expression exported; Expression local; if (exportSpecifier.Exported == exportSpecifier.Local) { exported = (local = VisitAndConvert(exportSpecifier.Local, allowNull: false, "VisitExportSpecifier")); } else { local = VisitAndConvert(exportSpecifier.Local, allowNull: false, "VisitExportSpecifier"); exported = VisitAndConvert(exportSpecifier.Exported, allowNull: false, "VisitExportSpecifier"); } return exportSpecifier.UpdateWith(local, exported); } protected internal override object? VisitImportSpecifier(ImportSpecifier importSpecifier) { Expression imported; Identifier local; if (importSpecifier.Imported == importSpecifier.Local) { imported = (local = VisitAndConvert(importSpecifier.Local, allowNull: false, "VisitImportSpecifier")); } else { imported = VisitAndConvert(importSpecifier.Imported, allowNull: false, "VisitImportSpecifier"); local = VisitAndConvert(importSpecifier.Local, allowNull: false, "VisitImportSpecifier"); } return importSpecifier.UpdateWith(imported, local); } protected internal override object? VisitProperty(Property property) { Node node; Expression key; if (property.Shorthand) { node = VisitAndConvert(property.Value, allowNull: false, "VisitProperty"); key = ((node is AssignmentPattern assignmentPattern) ? assignmentPattern.Left : node).As(); } else { key = VisitAndConvert(property.Key, allowNull: false, "VisitProperty"); node = VisitAndConvert(property.Value, allowNull: false, "VisitProperty"); } return property.UpdateWith(key, node); } protected internal override object? VisitAccessorProperty(AccessorProperty accessorProperty) { VisitAndConvert(in accessorProperty.Decorators, out var newNodes, allowNullElement: false, "VisitAccessorProperty"); Expression key = VisitAndConvert(accessorProperty.Key, allowNull: false, "VisitAccessorProperty"); Expression value = VisitAndConvert(accessorProperty.Value, allowNull: true, "VisitAccessorProperty"); return accessorProperty.UpdateWith(in newNodes, key, value); } protected internal override object? VisitArrayExpression(ArrayExpression arrayExpression) { VisitAndConvert(in arrayExpression.Elements, out var newNodes, allowNullElement: true, "VisitArrayExpression"); return arrayExpression.UpdateWith(in newNodes); } protected internal override object? VisitArrayPattern(ArrayPattern arrayPattern) { VisitAndConvert(in arrayPattern.Elements, out var newNodes, allowNullElement: true, "VisitArrayPattern"); return arrayPattern.UpdateWith(in newNodes); } protected internal override object? VisitArrowFunctionExpression(ArrowFunctionExpression arrowFunctionExpression) { VisitAndConvert(in arrowFunctionExpression.Params, out var newNodes, allowNullElement: false, "VisitArrowFunctionExpression"); StatementListItem body = VisitAndConvert(arrowFunctionExpression.Body, allowNull: false, "VisitArrowFunctionExpression"); return arrowFunctionExpression.UpdateWith(in newNodes, body); } protected internal override object? VisitAssignmentExpression(AssignmentExpression assignmentExpression) { Node left = VisitAndConvert(assignmentExpression.Left, allowNull: false, "VisitAssignmentExpression"); Expression right = VisitAndConvert(assignmentExpression.Right, allowNull: false, "VisitAssignmentExpression"); return assignmentExpression.UpdateWith(left, right); } protected internal override object? VisitAssignmentPattern(AssignmentPattern assignmentPattern) { Node left = VisitAndConvert(assignmentPattern.Left, allowNull: false, "VisitAssignmentPattern"); Expression right = VisitAndConvert(assignmentPattern.Right, allowNull: false, "VisitAssignmentPattern"); return assignmentPattern.UpdateWith(left, right); } protected internal override object? VisitAwaitExpression(AwaitExpression awaitExpression) { Expression argument = VisitAndConvert(awaitExpression.Argument, allowNull: false, "VisitAwaitExpression"); return awaitExpression.UpdateWith(argument); } protected internal override object? VisitBinaryExpression(BinaryExpression binaryExpression) { Expression left = VisitAndConvert(binaryExpression.Left, allowNull: false, "VisitBinaryExpression"); Expression right = VisitAndConvert(binaryExpression.Right, allowNull: false, "VisitBinaryExpression"); return binaryExpression.UpdateWith(left, right); } protected internal override object? VisitBlockStatement(BlockStatement blockStatement) { VisitAndConvert(in blockStatement.Body, out var newNodes, allowNullElement: false, "VisitBlockStatement"); return blockStatement.UpdateWith(in newNodes); } protected internal override object? VisitBreakStatement(BreakStatement breakStatement) { Identifier label = VisitAndConvert(breakStatement.Label, allowNull: true, "VisitBreakStatement"); return breakStatement.UpdateWith(label); } protected internal override object? VisitCallExpression(CallExpression callExpression) { Expression callee = VisitAndConvert(callExpression.Callee, allowNull: false, "VisitCallExpression"); VisitAndConvert(in callExpression.Arguments, out var newNodes, allowNullElement: false, "VisitCallExpression"); return callExpression.UpdateWith(callee, in newNodes); } protected internal override object? VisitCatchClause(CatchClause catchClause) { Node param = VisitAndConvert(catchClause.Param, allowNull: true, "VisitCatchClause"); BlockStatement body = VisitAndConvert(catchClause.Body, allowNull: false, "VisitCatchClause"); return catchClause.UpdateWith(param, body); } protected internal override object? VisitChainExpression(ChainExpression chainExpression) { Expression expression = VisitAndConvert(chainExpression.Expression, allowNull: false, "VisitChainExpression"); return chainExpression.UpdateWith(expression); } protected internal override object? VisitClassBody(ClassBody classBody) { VisitAndConvert(in classBody.Body, out var newNodes, allowNullElement: false, "VisitClassBody"); return classBody.UpdateWith(in newNodes); } protected internal override object? VisitClassDeclaration(ClassDeclaration classDeclaration) { VisitAndConvert(in classDeclaration.Decorators, out var newNodes, allowNullElement: false, "VisitClassDeclaration"); Identifier id = VisitAndConvert(classDeclaration.Id, allowNull: true, "VisitClassDeclaration"); Expression superClass = VisitAndConvert(classDeclaration.SuperClass, allowNull: true, "VisitClassDeclaration"); ClassBody body = VisitAndConvert(classDeclaration.Body, allowNull: false, "VisitClassDeclaration"); return classDeclaration.UpdateWith(in newNodes, id, superClass, body); } protected internal override object? VisitClassExpression(ClassExpression classExpression) { VisitAndConvert(in classExpression.Decorators, out var newNodes, allowNullElement: false, "VisitClassExpression"); Identifier id = VisitAndConvert(classExpression.Id, allowNull: true, "VisitClassExpression"); Expression superClass = VisitAndConvert(classExpression.SuperClass, allowNull: true, "VisitClassExpression"); ClassBody body = VisitAndConvert(classExpression.Body, allowNull: false, "VisitClassExpression"); return classExpression.UpdateWith(in newNodes, id, superClass, body); } protected internal override object? VisitConditionalExpression(ConditionalExpression conditionalExpression) { Expression test = VisitAndConvert(conditionalExpression.Test, allowNull: false, "VisitConditionalExpression"); Expression consequent = VisitAndConvert(conditionalExpression.Consequent, allowNull: false, "VisitConditionalExpression"); Expression alternate = VisitAndConvert(conditionalExpression.Alternate, allowNull: false, "VisitConditionalExpression"); return conditionalExpression.UpdateWith(test, consequent, alternate); } protected internal override object? VisitContinueStatement(ContinueStatement continueStatement) { Identifier label = VisitAndConvert(continueStatement.Label, allowNull: true, "VisitContinueStatement"); return continueStatement.UpdateWith(label); } protected internal override object? VisitDecorator(Decorator decorator) { Expression expression = VisitAndConvert(decorator.Expression, allowNull: false, "VisitDecorator"); return decorator.UpdateWith(expression); } protected internal override object? VisitDoWhileStatement(DoWhileStatement doWhileStatement) { Statement body = VisitAndConvert(doWhileStatement.Body, allowNull: false, "VisitDoWhileStatement"); Expression test = VisitAndConvert(doWhileStatement.Test, allowNull: false, "VisitDoWhileStatement"); return doWhileStatement.UpdateWith(body, test); } protected internal override object? VisitExportAllDeclaration(ExportAllDeclaration exportAllDeclaration) { Expression exported = VisitAndConvert(exportAllDeclaration.Exported, allowNull: true, "VisitExportAllDeclaration"); Literal source = VisitAndConvert(exportAllDeclaration.Source, allowNull: false, "VisitExportAllDeclaration"); VisitAndConvert(in exportAllDeclaration.Attributes, out var newNodes, allowNullElement: false, "VisitExportAllDeclaration"); return exportAllDeclaration.UpdateWith(exported, source, in newNodes); } protected internal override object? VisitExportDefaultDeclaration(ExportDefaultDeclaration exportDefaultDeclaration) { StatementListItem declaration = VisitAndConvert(exportDefaultDeclaration.Declaration, allowNull: false, "VisitExportDefaultDeclaration"); return exportDefaultDeclaration.UpdateWith(declaration); } protected internal override object? VisitExportNamedDeclaration(ExportNamedDeclaration exportNamedDeclaration) { Declaration declaration = VisitAndConvert(exportNamedDeclaration.Declaration, allowNull: true, "VisitExportNamedDeclaration"); VisitAndConvert(in exportNamedDeclaration.Specifiers, out var newNodes, allowNullElement: false, "VisitExportNamedDeclaration"); Literal source = VisitAndConvert(exportNamedDeclaration.Source, allowNull: true, "VisitExportNamedDeclaration"); VisitAndConvert(in exportNamedDeclaration.Attributes, out var newNodes2, allowNullElement: false, "VisitExportNamedDeclaration"); return exportNamedDeclaration.UpdateWith(declaration, in newNodes, source, in newNodes2); } protected internal override object? VisitExpressionStatement(ExpressionStatement expressionStatement) { Expression expression = VisitAndConvert(expressionStatement.Expression, allowNull: false, "VisitExpressionStatement"); return expressionStatement.UpdateWith(expression); } protected internal override object? VisitForInStatement(ForInStatement forInStatement) { Node left = VisitAndConvert(forInStatement.Left, allowNull: false, "VisitForInStatement"); Expression right = VisitAndConvert(forInStatement.Right, allowNull: false, "VisitForInStatement"); Statement body = VisitAndConvert(forInStatement.Body, allowNull: false, "VisitForInStatement"); return forInStatement.UpdateWith(left, right, body); } protected internal override object? VisitForOfStatement(ForOfStatement forOfStatement) { Node left = VisitAndConvert(forOfStatement.Left, allowNull: false, "VisitForOfStatement"); Expression right = VisitAndConvert(forOfStatement.Right, allowNull: false, "VisitForOfStatement"); Statement body = VisitAndConvert(forOfStatement.Body, allowNull: false, "VisitForOfStatement"); return forOfStatement.UpdateWith(left, right, body); } protected internal override object? VisitForStatement(ForStatement forStatement) { StatementListItem init = VisitAndConvert(forStatement.Init, allowNull: true, "VisitForStatement"); Expression test = VisitAndConvert(forStatement.Test, allowNull: true, "VisitForStatement"); Expression update = VisitAndConvert(forStatement.Update, allowNull: true, "VisitForStatement"); Statement body = VisitAndConvert(forStatement.Body, allowNull: false, "VisitForStatement"); return forStatement.UpdateWith(init, test, update, body); } protected internal override object? VisitFunctionDeclaration(FunctionDeclaration functionDeclaration) { Identifier id = VisitAndConvert(functionDeclaration.Id, allowNull: true, "VisitFunctionDeclaration"); VisitAndConvert(in functionDeclaration.Params, out var newNodes, allowNullElement: false, "VisitFunctionDeclaration"); BlockStatement body = VisitAndConvert(functionDeclaration.Body, allowNull: false, "VisitFunctionDeclaration"); return functionDeclaration.UpdateWith(id, in newNodes, body); } protected internal override object? VisitFunctionExpression(FunctionExpression functionExpression) { Identifier id = VisitAndConvert(functionExpression.Id, allowNull: true, "VisitFunctionExpression"); VisitAndConvert(in functionExpression.Params, out var newNodes, allowNullElement: false, "VisitFunctionExpression"); BlockStatement body = VisitAndConvert(functionExpression.Body, allowNull: false, "VisitFunctionExpression"); return functionExpression.UpdateWith(id, in newNodes, body); } protected internal override object? VisitIfStatement(IfStatement ifStatement) { Expression test = VisitAndConvert(ifStatement.Test, allowNull: false, "VisitIfStatement"); Statement consequent = VisitAndConvert(ifStatement.Consequent, allowNull: false, "VisitIfStatement"); Statement alternate = VisitAndConvert(ifStatement.Alternate, allowNull: true, "VisitIfStatement"); return ifStatement.UpdateWith(test, consequent, alternate); } protected internal override object? VisitImportAttribute(ImportAttribute importAttribute) { Expression key = VisitAndConvert(importAttribute.Key, allowNull: false, "VisitImportAttribute"); Literal value = VisitAndConvert(importAttribute.Value, allowNull: false, "VisitImportAttribute"); return importAttribute.UpdateWith(key, value); } protected internal override object? VisitImportDeclaration(ImportDeclaration importDeclaration) { VisitAndConvert(in importDeclaration.Specifiers, out var newNodes, allowNullElement: false, "VisitImportDeclaration"); Literal source = VisitAndConvert(importDeclaration.Source, allowNull: false, "VisitImportDeclaration"); VisitAndConvert(in importDeclaration.Attributes, out var newNodes2, allowNullElement: false, "VisitImportDeclaration"); return importDeclaration.UpdateWith(in newNodes, source, in newNodes2); } protected internal override object? VisitImportDefaultSpecifier(ImportDefaultSpecifier importDefaultSpecifier) { Identifier local = VisitAndConvert(importDefaultSpecifier.Local, allowNull: false, "VisitImportDefaultSpecifier"); return importDefaultSpecifier.UpdateWith(local); } protected internal override object? VisitImportExpression(ImportExpression importExpression) { Expression source = VisitAndConvert(importExpression.Source, allowNull: false, "VisitImportExpression"); Expression options = VisitAndConvert(importExpression.Options, allowNull: true, "VisitImportExpression"); return importExpression.UpdateWith(source, options); } protected internal override object? VisitImportNamespaceSpecifier(ImportNamespaceSpecifier importNamespaceSpecifier) { Identifier local = VisitAndConvert(importNamespaceSpecifier.Local, allowNull: false, "VisitImportNamespaceSpecifier"); return importNamespaceSpecifier.UpdateWith(local); } protected internal override object? VisitLabeledStatement(LabeledStatement labeledStatement) { Identifier label = VisitAndConvert(labeledStatement.Label, allowNull: false, "VisitLabeledStatement"); Statement body = VisitAndConvert(labeledStatement.Body, allowNull: false, "VisitLabeledStatement"); return labeledStatement.UpdateWith(label, body); } protected internal override object? VisitMemberExpression(MemberExpression memberExpression) { Expression expression = VisitAndConvert(memberExpression.Object, allowNull: false, "VisitMemberExpression"); Expression property = VisitAndConvert(memberExpression.Property, allowNull: false, "VisitMemberExpression"); return memberExpression.UpdateWith(expression, property); } protected internal override object? VisitMetaProperty(MetaProperty metaProperty) { Identifier meta = VisitAndConvert(metaProperty.Meta, allowNull: false, "VisitMetaProperty"); Identifier property = VisitAndConvert(metaProperty.Property, allowNull: false, "VisitMetaProperty"); return metaProperty.UpdateWith(meta, property); } protected internal override object? VisitMethodDefinition(MethodDefinition methodDefinition) { VisitAndConvert(in methodDefinition.Decorators, out var newNodes, allowNullElement: false, "VisitMethodDefinition"); Expression key = VisitAndConvert(methodDefinition.Key, allowNull: false, "VisitMethodDefinition"); FunctionExpression value = VisitAndConvert(methodDefinition.Value, allowNull: false, "VisitMethodDefinition"); return methodDefinition.UpdateWith(in newNodes, key, value); } protected internal override object? VisitNewExpression(NewExpression newExpression) { Expression callee = VisitAndConvert(newExpression.Callee, allowNull: false, "VisitNewExpression"); VisitAndConvert(in newExpression.Arguments, out var newNodes, allowNullElement: false, "VisitNewExpression"); return newExpression.UpdateWith(callee, in newNodes); } protected internal override object? VisitObjectExpression(ObjectExpression objectExpression) { VisitAndConvert(in objectExpression.Properties, out var newNodes, allowNullElement: false, "VisitObjectExpression"); return objectExpression.UpdateWith(in newNodes); } protected internal override object? VisitObjectPattern(ObjectPattern objectPattern) { VisitAndConvert(in objectPattern.Properties, out var newNodes, allowNullElement: false, "VisitObjectPattern"); return objectPattern.UpdateWith(in newNodes); } protected internal override object? VisitProgram(Program program) { VisitAndConvert(in program.Body, out var newNodes, allowNullElement: false, "VisitProgram"); return program.UpdateWith(in newNodes); } protected internal override object? VisitPropertyDefinition(PropertyDefinition propertyDefinition) { VisitAndConvert(in propertyDefinition.Decorators, out var newNodes, allowNullElement: false, "VisitPropertyDefinition"); Expression key = VisitAndConvert(propertyDefinition.Key, allowNull: false, "VisitPropertyDefinition"); Expression value = VisitAndConvert(propertyDefinition.Value, allowNull: true, "VisitPropertyDefinition"); return propertyDefinition.UpdateWith(in newNodes, key, value); } protected internal override object? VisitRestElement(RestElement restElement) { Node argument = VisitAndConvert(restElement.Argument, allowNull: false, "VisitRestElement"); return restElement.UpdateWith(argument); } protected internal override object? VisitReturnStatement(ReturnStatement returnStatement) { Expression argument = VisitAndConvert(returnStatement.Argument, allowNull: true, "VisitReturnStatement"); return returnStatement.UpdateWith(argument); } protected internal override object? VisitSequenceExpression(SequenceExpression sequenceExpression) { VisitAndConvert(in sequenceExpression.Expressions, out var newNodes, allowNullElement: false, "VisitSequenceExpression"); return sequenceExpression.UpdateWith(in newNodes); } protected internal override object? VisitSpreadElement(SpreadElement spreadElement) { Expression argument = VisitAndConvert(spreadElement.Argument, allowNull: false, "VisitSpreadElement"); return spreadElement.UpdateWith(argument); } protected internal override object? VisitStaticBlock(StaticBlock staticBlock) { VisitAndConvert(in staticBlock.Body, out var newNodes, allowNullElement: false, "VisitStaticBlock"); return staticBlock.UpdateWith(in newNodes); } protected internal override object? VisitSwitchCase(SwitchCase switchCase) { Expression test = VisitAndConvert(switchCase.Test, allowNull: true, "VisitSwitchCase"); VisitAndConvert(in switchCase.Consequent, out var newNodes, allowNullElement: false, "VisitSwitchCase"); return switchCase.UpdateWith(test, in newNodes); } protected internal override object? VisitSwitchStatement(SwitchStatement switchStatement) { Expression discriminant = VisitAndConvert(switchStatement.Discriminant, allowNull: false, "VisitSwitchStatement"); VisitAndConvert(in switchStatement.Cases, out var newNodes, allowNullElement: false, "VisitSwitchStatement"); return switchStatement.UpdateWith(discriminant, in newNodes); } protected internal override object? VisitTaggedTemplateExpression(TaggedTemplateExpression taggedTemplateExpression) { Expression tag = VisitAndConvert(taggedTemplateExpression.Tag, allowNull: false, "VisitTaggedTemplateExpression"); TemplateLiteral quasi = VisitAndConvert(taggedTemplateExpression.Quasi, allowNull: false, "VisitTaggedTemplateExpression"); return taggedTemplateExpression.UpdateWith(tag, quasi); } protected internal override object? VisitTemplateLiteral(TemplateLiteral templateLiteral) { VisitAndConvert(in templateLiteral.Quasis, out var newNodes, allowNullElement: false, "VisitTemplateLiteral"); VisitAndConvert(in templateLiteral.Expressions, out var newNodes2, allowNullElement: false, "VisitTemplateLiteral"); return templateLiteral.UpdateWith(in newNodes, in newNodes2); } protected internal override object? VisitThrowStatement(ThrowStatement throwStatement) { Expression argument = VisitAndConvert(throwStatement.Argument, allowNull: false, "VisitThrowStatement"); return throwStatement.UpdateWith(argument); } protected internal override object? VisitTryStatement(TryStatement tryStatement) { BlockStatement block = VisitAndConvert(tryStatement.Block, allowNull: false, "VisitTryStatement"); CatchClause handler = VisitAndConvert(tryStatement.Handler, allowNull: true, "VisitTryStatement"); BlockStatement finalizer = VisitAndConvert(tryStatement.Finalizer, allowNull: true, "VisitTryStatement"); return tryStatement.UpdateWith(block, handler, finalizer); } protected internal override object? VisitUnaryExpression(UnaryExpression unaryExpression) { Expression argument = VisitAndConvert(unaryExpression.Argument, allowNull: false, "VisitUnaryExpression"); return unaryExpression.UpdateWith(argument); } protected internal override object? VisitVariableDeclaration(VariableDeclaration variableDeclaration) { VisitAndConvert(in variableDeclaration.Declarations, out var newNodes, allowNullElement: false, "VisitVariableDeclaration"); return variableDeclaration.UpdateWith(in newNodes); } protected internal override object? VisitVariableDeclarator(VariableDeclarator variableDeclarator) { Node id = VisitAndConvert(variableDeclarator.Id, allowNull: false, "VisitVariableDeclarator"); Expression init = VisitAndConvert(variableDeclarator.Init, allowNull: true, "VisitVariableDeclarator"); return variableDeclarator.UpdateWith(id, init); } protected internal override object? VisitWhileStatement(WhileStatement whileStatement) { Expression test = VisitAndConvert(whileStatement.Test, allowNull: false, "VisitWhileStatement"); Statement body = VisitAndConvert(whileStatement.Body, allowNull: false, "VisitWhileStatement"); return whileStatement.UpdateWith(test, body); } protected internal override object? VisitWithStatement(WithStatement withStatement) { Expression expression = VisitAndConvert(withStatement.Object, allowNull: false, "VisitWithStatement"); Statement body = VisitAndConvert(withStatement.Body, allowNull: false, "VisitWithStatement"); return withStatement.UpdateWith(expression, body); } protected internal override object? VisitYieldExpression(YieldExpression yieldExpression) { Expression argument = VisitAndConvert(yieldExpression.Argument, allowNull: true, "VisitYieldExpression"); return yieldExpression.UpdateWith(argument); } } public record AstToJavaScriptOptions { internal bool IgnoreExtensions { get; init; } public static readonly AstToJavaScriptOptions Default = new AstToJavaScriptOptions(); protected internal virtual AstToJavaScriptConverter CreateConverter(JavaScriptTextWriter writer) { return new AstToJavaScriptConverter(writer, this); } [CompilerGenerated] protected virtual bool PrintMembers(StringBuilder builder) { return false; } [CompilerGenerated] protected AstToJavaScriptOptions(AstToJavaScriptOptions original) { IgnoreExtensions = original.IgnoreExtensions; } public AstToJavaScriptOptions() { } } public static class AstToJavaScript { public static string ToJavaScriptString(this Node node) { return node.ToJavaScriptString(JavaScriptTextWriterOptions.Default, AstToJavaScriptOptions.Default); } public static string ToJavaScriptString(this Node node, KnRJavaScriptTextFormatterOptions formattingOptions) { return node.ToJavaScriptString(formattingOptions, AstToJavaScriptOptions.Default); } public static string ToJavaScriptString(this Node node, bool format) { return node.ToJavaScriptString(format ? KnRJavaScriptTextFormatterOptions.Default : JavaScriptTextWriterOptions.Default, AstToJavaScriptOptions.Default); } public static string ToJavaScriptString(this Node node, JavaScriptTextWriterOptions writerOptions, AstToJavaScriptOptions options) { using StringWriter stringWriter = new StringWriter(); node.WriteJavaScript(stringWriter, writerOptions, options); return stringWriter.ToString(); } public static void WriteJavaScript(this Node node, TextWriter writer) { node.WriteJavaScript(writer, JavaScriptTextWriterOptions.Default, AstToJavaScriptOptions.Default); } public static void WriteJavaScript(this Node node, TextWriter writer, KnRJavaScriptTextFormatterOptions formattingOptions) { node.WriteJavaScript(writer, formattingOptions, AstToJavaScriptOptions.Default); } public static void WriteJavaScript(this Node node, TextWriter writer, bool format) { node.WriteJavaScript(writer, format ? KnRJavaScriptTextFormatterOptions.Default : JavaScriptTextWriterOptions.Default, AstToJavaScriptOptions.Default); } public static void WriteJavaScript(this Node node, TextWriter writer, JavaScriptTextWriterOptions writerOptions, AstToJavaScriptOptions options) { if ((object)writerOptions == null) { throw new ArgumentNullException("writerOptions"); } node.WriteJavaScript(writerOptions.CreateWriter(writer), options); } public static void WriteJavaScript(this Node node, JavaScriptTextWriter writer, AstToJavaScriptOptions options) { if ((object)options == null) { throw new ArgumentNullException("options"); } options.CreateConverter(writer).Convert(node); } } public class AstToJavaScriptConverter : AstVisitor { [Flags] protected internal enum BinaryOperationFlags { None = 0, LeftOperandNeedsBrackets = 1, RightOperandNeedsBrackets = 2, BothOperandsNeedBrackets = 3 } [Flags] protected internal enum StatementFlags { None = 0, NeedsSemicolon = 1, MayOmitRightMostSemicolon = 2, IsRightMost = 4, IsStatementBody = 8, NestedVariableDeclaration = 0x10000 } [Flags] protected internal enum ExpressionFlags { None = 0, NeedsBrackets = 1, IsLeftMost = 2, SpaceBeforeBracketsRecommended = 0x4000, SpaceAfterBracketsRecommended = 0x8000, SpaceAroundBracketsRecommended = 0xC000, IsRootExpression = 0x10000, IsMethod = 0x20000, IsInsideExportDefaultExpression = 0x200000, IsInsideDecorator = 0x400000, IsInAmbiguousInOperatorContext = 0x1000000, IsLeftMostInArrowFunctionBody = 0x2000000, IsInsideArrowFunctionBody = 0x4000000, IsLeftMostInNewCallee = 0x8000000, IsInsideNewCallee = 0x10000000, IsLeftMostInLeftHandSideExpression = 0x20000000, IsInsideLeftHandSideExpression = 0x40000000, IsInsideStatementExpression = int.MinValue, IsInPotentiallyAmbiguousContext = -715128832 } private static readonly object s_lastSwitchCaseFlag = new object(); private static readonly object s_forLoopInitDeclarationFlag = new object(); private static readonly object s_bindingPatternAllowsExpressionsFlag = new object(); private readonly bool _ignoreExtensions; private JavaScriptTextWriter.WriteContext _writeContext; private StatementFlags _currentStatementFlags; private ExpressionFlags _currentExpressionFlags; private object? _currentAuxiliaryNodeContext; private protected static readonly Func s_getCombinedStatementFlags = (AstToJavaScriptConverter @this, Statement statement, StatementFlags flags) => @this.PropagateStatementFlags(flags); private protected static readonly Func s_getCombinedRootExpressionFlags = (AstToJavaScriptConverter @this, Expression expression, ExpressionFlags flags) => @this.DisambiguateExpression(expression, flags); private protected static readonly Func s_getCombinedSubExpressionFlags = (AstToJavaScriptConverter @this, Expression expression, ExpressionFlags flags) => @this.DisambiguateExpression(expression, @this.PropagateExpressionFlags(flags)); public JavaScriptTextWriter Writer { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } protected ref JavaScriptTextWriter.WriteContext WriteContext { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _writeContext; } } protected Node? ParentNode { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _writeContext.ParentNode; } } public AstToJavaScriptConverter(JavaScriptTextWriter writer, AstToJavaScriptOptions options) { Writer = writer ?? throw new ArgumentNullException("writer"); if ((object)options == null) { throw new ArgumentNullException("options"); } _ignoreExtensions = options.IgnoreExtensions; } public void Convert(Node node) { _writeContext = default(JavaScriptTextWriter.WriteContext); _currentStatementFlags = StatementFlags.None; _currentExpressionFlags = ExpressionFlags.None; _currentAuxiliaryNodeContext = null; Visit(node ?? throw new ArgumentNullException("node")); Writer.Finish(); } public override object? Visit(Node node) { JavaScriptTextWriter.WriteContext writeContext = _writeContext; _writeContext = new JavaScriptTextWriter.WriteContext(writeContext.Node, node); object? result = base.Visit(node); _writeContext = writeContext; return result; } protected internal override object? VisitAccessorProperty(AccessorProperty accessorProperty) { if (accessorProperty.Decorators.Count > 0) { _writeContext.SetNodeProperty("Decorators", (Node node) => ref node.As().Decorators); VisitAuxiliaryNodeList(in accessorProperty.Decorators, string.Empty); _writeContext.ClearNodeProperty(); } if (accessorProperty.Static) { _writeContext.SetNodeProperty("Static", (Node node) => node.As().Static); Writer.WriteKeyword("static", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); _writeContext.ClearNodeProperty(); } else { Writer.SpaceRecommendedAfterLastToken(); } Writer.WriteKeyword("accessor", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); _writeContext.SetNodeProperty("Key", (Node node) => node.As().Key); VisitPropertyKey(accessorProperty.Key, accessorProperty.Computed, JavaScriptTextWriter.TokenFlags.LeadingSpaceRecommended); if (accessorProperty.Value != null) { _writeContext.ClearNodeProperty(); Writer.WritePunctuator("=", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended | JavaScriptTextWriter.TokenFlags.InBetween, ref _writeContext); _writeContext.SetNodeProperty("Value", (Node node) => node.As().Value); VisitRootExpression(accessorProperty.Value, RootExpressionFlags(ExpressionNeedsBracketsInList(accessorProperty.Value))); } Writer.WritePunctuator(";", JavaScriptTextWriter.TokenFlags.Trailing | JavaScriptTextWriter.TokenFlags.TrailingSpaceRecommended, ref _writeContext); return accessorProperty; } protected internal override object? VisitArrayExpression(ArrayExpression arrayExpression) { _writeContext.SetNodeProperty("Elements", (Node node) => ref node.As().Elements); Writer.StartArray(arrayExpression.Elements.Count, ref _writeContext); Writer.StartExpressionList(arrayExpression.Elements.Count, ref _writeContext); for (int num = 0; num < arrayExpression.Elements.Count; num++) { Expression expression = arrayExpression.Elements[num]; if (expression != null) { VisitExpressionListItem(expression, num, arrayExpression.Elements.Count, (AstToJavaScriptConverter @this, Expression expression2, int _, int _) => s_getCombinedSubExpressionFlags(@this, expression2, SubExpressionFlags(@this.ExpressionNeedsBracketsInList(expression2), isLeftMost: false))); continue; } ExpressionFlags currentExpressionFlags = _currentExpressionFlags; _currentExpressionFlags = PropagateExpressionFlags(SubExpressionFlags(needsBrackets: false, isLeftMost: false)); _writeContext.SetNodePropertyItemIndex(num); Writer.StartExpressionListItem(num, arrayExpression.Elements.Count, (JavaScriptTextWriter.ExpressionFlags)_currentExpressionFlags, ref _writeContext); Writer.EndExpressionListItem(num, arrayExpression.Elements.Count, (JavaScriptTextWriter.ExpressionFlags)_currentExpressionFlags, ref _writeContext); _currentExpressionFlags = currentExpressionFlags; } Writer.EndExpressionList(arrayExpression.Elements.Count, ref _writeContext); Writer.EndArray(arrayExpression.Elements.Count, ref _writeContext); return arrayExpression; } protected internal override object? VisitArrayPattern(ArrayPattern arrayPattern) { _writeContext.SetNodeProperty("Elements", (Node node2) => ref node2.As().Elements); Writer.StartArray(arrayPattern.Elements.Count, ref _writeContext); Writer.StartAuxiliaryNodeList(arrayPattern.Elements.Count, ref _writeContext); for (int num = 0; num < arrayPattern.Elements.Count; num++) { Node node = arrayPattern.Elements[num]; if (node != null) { if (_currentAuxiliaryNodeContext != s_bindingPatternAllowsExpressionsFlag) { VisitAuxiliaryNodeListItem(node, num, arrayPattern.Elements.Count, ",", (AstToJavaScriptConverter , Node? , int , int ) => (object?)null); continue; } if (!(node is Expression expression)) { VisitAuxiliaryNodeListItem(node, num, arrayPattern.Elements.Count, ",", (AstToJavaScriptConverter , Node? , int , int ) => s_bindingPatternAllowsExpressionsFlag); continue; } object currentAuxiliaryNodeContext = _currentAuxiliaryNodeContext; _currentAuxiliaryNodeContext = null; _writeContext.SetNodePropertyItemIndex(num); Writer.StartAuxiliaryNodeListItem(num, arrayPattern.Elements.Count, ",", _currentAuxiliaryNodeContext, ref _writeContext); VisitRootExpression(expression, RootExpressionFlags(ExpressionNeedsBracketsInList(expression))); Writer.EndAuxiliaryNodeListItem(num, arrayPattern.Elements.Count, ",", _currentAuxiliaryNodeContext, ref _writeContext); _currentAuxiliaryNodeContext = currentAuxiliaryNodeContext; } else { object currentAuxiliaryNodeContext2 = _currentAuxiliaryNodeContext; _currentAuxiliaryNodeContext = null; _writeContext.SetNodePropertyItemIndex(num); Writer.StartAuxiliaryNodeListItem(num, arrayPattern.Elements.Count, ",", _currentAuxiliaryNodeContext, ref _writeContext); Writer.EndAuxiliaryNodeListItem(num, arrayPattern.Elements.Count, ",", _currentAuxiliaryNodeContext, ref _writeContext); _currentAuxiliaryNodeContext = currentAuxiliaryNodeContext2; } } Writer.EndAuxiliaryNodeList(arrayPattern.Elements.Count, ref _writeContext); Writer.EndArray(arrayPattern.Elements.Count, ref _writeContext); return arrayPattern; } protected internal override object? VisitArrowFunctionExpression(ArrowFunctionExpression arrowFunctionExpression) { if (arrowFunctionExpression.Async) { _writeContext.SetNodeProperty("Async", (Node node) => node.As().Async); Writer.WriteKeyword("async", JavaScriptTextWriter.TokenFlags.TrailingSpaceRecommended, ref _writeContext); } _writeContext.SetNodeProperty("Params", (Node node) => ref node.As().Params); if (arrowFunctionExpression.Params.Count == 1 && arrowFunctionExpression.Params[0].Type == Nodes.Identifier) { VisitAuxiliaryNodeList(in arrowFunctionExpression.Params, ","); } else { Writer.WritePunctuator("(", JavaScriptTextWriter.TokenFlags.Leading, ref _writeContext); VisitAuxiliaryNodeList(in arrowFunctionExpression.Params, ","); Writer.WritePunctuator(")", JavaScriptTextWriter.TokenFlags.Trailing, ref _writeContext); } _writeContext.ClearNodeProperty(); Writer.WritePunctuator("=>", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); _writeContext.SetNodeProperty("Body", (Node node) => node.As().Body); if (arrowFunctionExpression.Body is BlockStatement statement) { VisitStatement(statement, StatementFlags.IsRightMost); } else { Expression expression = arrowFunctionExpression.Body.As(); bool needsBrackets = UnaryOperandNeedsBrackets(arrowFunctionExpression, expression); VisitExpression(expression, SubExpressionFlags(needsBrackets, isLeftMost: false), (AstToJavaScriptConverter @this, Expression expression2, ExpressionFlags flags) => @this.DisambiguateExpression(expression2, ExpressionFlags.IsLeftMostInArrowFunctionBody | ExpressionFlags.IsInsideArrowFunctionBody | @this.PropagateExpressionFlags(flags))); } return arrowFunctionExpression; } protected internal override object? VisitAssignmentExpression(AssignmentExpression assignmentExpression) { _writeContext.SetNodeProperty("Left", (Node node) => node.As().Left); if (assignmentExpression.Left is Expression expression) { VisitSubExpression(expression, SubExpressionFlags(needsBrackets: false, isLeftMost: true)); } else { VisitAuxiliaryNode(assignmentExpression.Left, (AstToJavaScriptConverter , Node ) => s_bindingPatternAllowsExpressionsFlag); } string assignmentOperatorToken = AssignmentExpression.GetAssignmentOperatorToken(assignmentExpression.Operator); _writeContext.SetNodeProperty("Operator", (Node node) => node.As().Operator); Writer.WritePunctuator(assignmentOperatorToken, JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended | JavaScriptTextWriter.TokenFlags.InBetween | JavaScriptTextWriter.TokenFlags.IsAssignmentOperator, ref _writeContext); int associativity; bool needsBrackets = GetOperatorPrecedence(assignmentExpression, out associativity) > GetOperatorPrecedence(assignmentExpression.Right, out associativity); _writeContext.SetNodeProperty("Right", (Node node) => node.As().Right); VisitSubExpression(assignmentExpression.Right, SubExpressionFlags(needsBrackets, isLeftMost: false)); return assignmentExpression; } protected internal override object? VisitAssignmentPattern(AssignmentPattern assignmentPattern) { _writeContext.SetNodeProperty("Left", (Node node) => node.As().Left); if (_currentAuxiliaryNodeContext != s_bindingPatternAllowsExpressionsFlag) { VisitAuxiliaryNode(assignmentPattern.Left); } else if (!(assignmentPattern.Left is Expression expression)) { VisitAuxiliaryNode(assignmentPattern.Left, (AstToJavaScriptConverter , Node ) => s_bindingPatternAllowsExpressionsFlag); } else { VisitRootExpression(expression, RootExpressionFlags(ExpressionNeedsBracketsInList(expression))); } _writeContext.ClearNodeProperty(); Writer.WritePunctuator("=", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended | JavaScriptTextWriter.TokenFlags.InBetween, ref _writeContext); _writeContext.SetNodeProperty("Right", (Node node) => node.As().Right); VisitRootExpression(assignmentPattern.Right, RootExpressionFlags(ExpressionNeedsBracketsInList(assignmentPattern.Right))); return assignmentPattern; } protected internal override object? VisitAwaitExpression(AwaitExpression awaitExpression) { Writer.WriteKeyword("await", JavaScriptTextWriter.TokenFlags.TrailingSpaceRecommended, ref _writeContext); bool needsBrackets = UnaryOperandNeedsBrackets(awaitExpression, awaitExpression.Argument); _writeContext.SetNodeProperty("Argument", (Node node) => node.As().Argument); VisitSubExpression(awaitExpression.Argument, SubExpressionFlags(needsBrackets, isLeftMost: false)); return awaitExpression; } protected internal override object? VisitBinaryExpression(BinaryExpression binaryExpression) { BinaryOperationFlags binaryOperationFlags = BinaryOperandsNeedBrackets(binaryExpression, binaryExpression.Left, binaryExpression.Right); if (!binaryOperationFlags.HasFlagFast(BinaryOperationFlags.LeftOperandNeedsBrackets)) { bool flag = binaryExpression.Operator == BinaryOperator.Exponentiation && binaryExpression.Left.Type == Nodes.UnaryExpression; if (!flag) { bool flag2 = binaryExpression.Operator == BinaryOperator.NullishCoalescing; if (flag2) { bool flag3 = ((binaryExpression.Left is LogicalExpression { Operator: var binaryOperator } && (uint)(binaryOperator - 21) <= 1u) ? true : false); flag2 = flag3; } flag = flag2; } bool flag4 = flag; if (!flag4) { BinaryOperator binaryOperator2 = binaryExpression.Operator; bool flag2 = (uint)(binaryOperator2 - 21) <= 1u; flag4 = flag2 && binaryExpression.Left is LogicalExpression logicalExpression2 && logicalExpression2.Operator == BinaryOperator.NullishCoalescing; } if (flag4) { binaryOperationFlags |= BinaryOperationFlags.LeftOperandNeedsBrackets; } } _writeContext.SetNodeProperty("Left", (Node node) => node.As().Left); VisitSubExpression(binaryExpression.Left, SubExpressionFlags(binaryOperationFlags.HasFlagFast(BinaryOperationFlags.LeftOperandNeedsBrackets), isLeftMost: true)); string binaryOperatorToken = BinaryExpression.GetBinaryOperatorToken(binaryExpression.Operator); _writeContext.SetNodeProperty("Operator", (Node node) => node.As().Operator); if (char.IsLetter(binaryOperatorToken[0])) { Writer.WriteKeyword(binaryOperatorToken, JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); } else { Writer.WritePunctuator(binaryOperatorToken, JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended | JavaScriptTextWriter.TokenFlags.InBetween | JavaScriptTextWriter.TokenFlags.IsBinaryOperator, ref _writeContext); if (!binaryOperationFlags.HasFlagFast(BinaryOperationFlags.RightOperandNeedsBrackets) && binaryExpression.Operator == BinaryOperator.NullishCoalescing && binaryExpression.Right is LogicalExpression { Operator: BinaryOperator.LogicalAnd }) { binaryOperationFlags |= BinaryOperationFlags.RightOperandNeedsBrackets; } } _writeContext.SetNodeProperty("Right", (Node node) => node.As().Right); VisitSubExpression(binaryExpression.Right, SubExpressionFlags(binaryOperationFlags.HasFlagFast(BinaryOperationFlags.RightOperandNeedsBrackets), isLeftMost: false)); return binaryExpression; } protected internal override object? VisitBlockStatement(BlockStatement blockStatement) { _writeContext.SetNodeProperty("Body", (Node node) => ref node.As().Body); Writer.StartBlock(blockStatement.Body.Count, ref _writeContext); VisitStatementList(in blockStatement.Body); Writer.EndBlock(blockStatement.Body.Count, ref _writeContext); return blockStatement; } protected internal override object? VisitBreakStatement(BreakStatement breakStatement) { Writer.WriteKeyword("break", JavaScriptTextWriter.TokenFlags.LeadingSpaceRecommended, ref _writeContext); if (breakStatement.Label != null) { _writeContext.SetNodeProperty("Label", (Node node) => node.As().Label); VisitRootExpression(breakStatement.Label, RootExpressionFlags(needsBrackets: false)); } StatementNeedsSemicolon(); return breakStatement; } protected internal override object? VisitCallExpression(CallExpression callExpression) { bool needsBrackets = UnaryOperandNeedsBrackets(callExpression, callExpression.Callee); _writeContext.SetNodeProperty("Callee", (Node node) => node.As().Callee); VisitSubExpression(callExpression.Callee, SubExpressionFlags(needsBrackets, isLeftMost: true)); if (callExpression.Optional) { _writeContext.ClearNodeProperty(); Writer.WritePunctuator("?.", JavaScriptTextWriter.TokenFlags.InBetween, ref _writeContext); } _writeContext.SetNodeProperty("Arguments", (Node node) => ref node.As().Arguments); Writer.WritePunctuator("(", JavaScriptTextWriter.TokenFlags.Leading, ref _writeContext); VisitSubExpressionList(in callExpression.Arguments); Writer.WritePunctuator(")", JavaScriptTextWriter.TokenFlags.Trailing, ref _writeContext); return callExpression; } protected internal override object? VisitCatchClause(CatchClause catchClause) { if (catchClause.Param != null) { _writeContext.SetNodeProperty("Param", (Node node) => node.As().Param); Writer.WritePunctuator("(", JavaScriptTextWriter.TokenFlags.Leading | JavaScriptTextWriter.TokenFlags.LeadingSpaceRecommended, ref _writeContext); VisitAuxiliaryNode(catchClause.Param); Writer.WritePunctuator(")", JavaScriptTextWriter.TokenFlags.Trailing | JavaScriptTextWriter.TokenFlags.TrailingSpaceRecommended, ref _writeContext); } _writeContext.SetNodeProperty("Body", (Node node) => node.As().Body); VisitStatement(catchClause.Body, StatementBodyFlags(ParentNode.As().Finalizer == null)); return catchClause; } protected internal override object? VisitChainExpression(ChainExpression chainExpression) { _writeContext.SetNodeProperty("Expression", (Node node) => node.As().Expression); VisitSubExpression(chainExpression.Expression, SubExpressionFlags(needsBrackets: false, isLeftMost: true)); return chainExpression; } protected internal override object? VisitClassBody(ClassBody classBody) { _writeContext.SetNodeProperty("Body", (Node node) => ref node.As().Body); Writer.StartBlock(classBody.Body.Count, ref _writeContext); VisitAuxiliaryNodeList(in classBody.Body, string.Empty); Writer.EndBlock(classBody.Body.Count, ref _writeContext); return classBody; } protected internal override object? VisitClassDeclaration(ClassDeclaration classDeclaration) { if (classDeclaration.Decorators.Count > 0) { _writeContext.SetNodeProperty("Decorators", (Node node) => ref node.As().Decorators); VisitAuxiliaryNodeList(in classDeclaration.Decorators, string.Empty); _writeContext.ClearNodeProperty(); } Writer.WriteKeyword("class", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); if (classDeclaration.Id != null) { _writeContext.SetNodeProperty("Id", (Node node) => node.As().Id); VisitAuxiliaryNode(classDeclaration.Id); } if (classDeclaration.SuperClass != null) { _writeContext.ClearNodeProperty(); Writer.WriteKeyword("extends", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); _writeContext.SetNodeProperty("SuperClass", (Node node) => node.As().SuperClass); VisitRootExpression(classDeclaration.SuperClass, ExpressionFlags.IsLeftMostInLeftHandSideExpression | ExpressionFlags.IsInsideLeftHandSideExpression | RootExpressionFlags(needsBrackets: false)); } _writeContext.SetNodeProperty("Body", (Node node) => node.As().Body); VisitAuxiliaryNode(classDeclaration.Body); return classDeclaration; } protected internal override object? VisitClassExpression(ClassExpression classExpression) { if (classExpression.Decorators.Count > 0) { _writeContext.SetNodeProperty("Decorators", (Node node) => ref node.As().Decorators); VisitAuxiliaryNodeList(in classExpression.Decorators, string.Empty); _writeContext.ClearNodeProperty(); } Writer.WriteKeyword("class", JavaScriptTextWriter.TokenFlags.TrailingSpaceRecommended, ref _writeContext); if (classExpression.Id != null) { _writeContext.SetNodeProperty("Id", (Node node) => node.As().Id); VisitAuxiliaryNode(classExpression.Id); } if (classExpression.SuperClass != null) { _writeContext.ClearNodeProperty(); Writer.WriteKeyword("extends", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); _writeContext.SetNodeProperty("SuperClass", (Node node) => node.As().SuperClass); VisitRootExpression(classExpression.SuperClass, ExpressionFlags.IsLeftMostInLeftHandSideExpression | ExpressionFlags.IsInsideLeftHandSideExpression | RootExpressionFlags(needsBrackets: false)); } _writeContext.SetNodeProperty("Body", (Node node) => node.As().Body); VisitAuxiliaryNode(classExpression.Body); return classExpression; } protected internal override object? VisitConditionalExpression(ConditionalExpression conditionalExpression) { bool needsBrackets = GetOperatorPrecedence(conditionalExpression, out var associativity) >= GetOperatorPrecedence(conditionalExpression.Test, out associativity); _writeContext.SetNodeProperty("Test", (Node node) => node.As().Test); VisitSubExpression(conditionalExpression.Test, SubExpressionFlags(needsBrackets, isLeftMost: true)); needsBrackets = GetOperatorPrecedence(conditionalExpression, out associativity) > GetOperatorPrecedence(conditionalExpression.Consequent, out associativity); _writeContext.SetNodeProperty("Consequent", (Node node) => node.As().Consequent); Writer.WritePunctuator("?", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended | JavaScriptTextWriter.TokenFlags.Leading, ref _writeContext); VisitExpression(conditionalExpression.Consequent, SubExpressionFlags(needsBrackets, isLeftMost: false), (AstToJavaScriptConverter @this, Expression expression, ExpressionFlags flags) => @this.DisambiguateExpression(expression, ~ExpressionFlags.IsInAmbiguousInOperatorContext & @this.PropagateExpressionFlags(flags))); needsBrackets = GetOperatorPrecedence(conditionalExpression, out associativity) > GetOperatorPrecedence(conditionalExpression.Alternate, out associativity); _writeContext.SetNodeProperty("Alternate", (Node node) => node.As().Alternate); Writer.WritePunctuator(":", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended | JavaScriptTextWriter.TokenFlags.Leading, ref _writeContext); VisitSubExpression(conditionalExpression.Alternate, SubExpressionFlags(needsBrackets, isLeftMost: false)); return conditionalExpression; } protected internal override object? VisitContinueStatement(ContinueStatement continueStatement) { Writer.WriteKeyword("continue", JavaScriptTextWriter.TokenFlags.LeadingSpaceRecommended, ref _writeContext); if (continueStatement.Label != null) { _writeContext.SetNodeProperty("Label", (Node node) => node.As().Label); VisitRootExpression(continueStatement.Label, RootExpressionFlags(needsBrackets: false)); } StatementNeedsSemicolon(); return continueStatement; } protected internal override object? VisitDebuggerStatement(DebuggerStatement debuggerStatement) { Writer.WriteKeyword("debugger", JavaScriptTextWriter.TokenFlags.LeadingSpaceRecommended, ref _writeContext); StatementNeedsSemicolon(); return debuggerStatement; } protected internal override object? VisitDecorator(Decorator decorator) { Writer.WritePunctuator("@", JavaScriptTextWriter.TokenFlags.Leading | (!(ParentNode is Expression)).ToFlag(JavaScriptTextWriter.TokenFlags.LeadingSpaceRecommended), ref _writeContext); _writeContext.SetNodeProperty("Expression", (Node node) => node.As().Expression); VisitRootExpression(decorator.Expression, ExpressionFlags.IsInsideDecorator | RootExpressionFlags(needsBrackets: false)); Writer.SpaceRecommendedAfterLastToken(); return decorator; } protected internal override object? VisitDoWhileStatement(DoWhileStatement doWhileStatement) { Writer.WriteKeyword("do", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); _writeContext.SetNodeProperty("Body", (Node node) => node.As().Body); StatementFlags previousBodyFlags; VisitStatement(doWhileStatement.Body, previousBodyFlags = StatementBodyFlags(isRightMost: false)); _writeContext.ClearNodeProperty(); Writer.WriteKeyword("while", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended | StatementBodyFlagsToKeywordFlags(previousBodyFlags), ref _writeContext); _writeContext.SetNodeProperty("Test", (Node node) => node.As().Test); VisitRootExpression(doWhileStatement.Test, ExpressionFlags.SpaceBeforeBracketsRecommended | RootExpressionFlags(needsBrackets: true)); return doWhileStatement; } protected internal override object? VisitEmptyStatement(EmptyStatement emptyStatement) { Writer.WritePunctuator(";", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); return emptyStatement; } protected internal override object? VisitExportAllDeclaration(ExportAllDeclaration exportAllDeclaration) { Writer.WriteKeyword("export", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); Writer.WritePunctuator("*", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); if (exportAllDeclaration.Exported != null) { _writeContext.SetNodeProperty("Exported", (Node node) => node.As().Exported); Writer.WriteKeyword("as", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); VisitExportOrImportSpecifierIdentifier(exportAllDeclaration.Exported); } _writeContext.ClearNodeProperty(); Writer.WriteKeyword("from", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); _writeContext.SetNodeProperty("Source", (Node node) => node.As().Source); VisitRootExpression(exportAllDeclaration.Source, RootExpressionFlags(needsBrackets: false)); if (exportAllDeclaration.Attributes.Count > 0) { _writeContext.SetNodeProperty("Attributes", (Node node) => ref node.As().Attributes); VisitImportAttributes(in exportAllDeclaration.Attributes); } StatementNeedsSemicolon(); return exportAllDeclaration; } protected internal override object? VisitExportDefaultDeclaration(ExportDefaultDeclaration exportDefaultDeclaration) { Writer.WriteKeyword("export", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); Writer.WriteKeyword("default", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); _writeContext.SetNodeProperty("Declaration", (Node node) => node.As().Declaration); if (exportDefaultDeclaration.Declaration is Declaration statement) { VisitStatement(statement, StatementFlags.IsRightMost); } else { VisitRootExpression(exportDefaultDeclaration.Declaration.As(), ExpressionFlags.IsInsideExportDefaultExpression | RootExpressionFlags(needsBrackets: false)); StatementNeedsSemicolon(); } return exportDefaultDeclaration; } protected internal override object? VisitExportNamedDeclaration(ExportNamedDeclaration exportNamedDeclaration) { Writer.WriteKeyword("export", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); if (exportNamedDeclaration.Declaration != null) { _writeContext.SetNodeProperty("Declaration", (Node node) => node.As().Declaration); VisitStatement(exportNamedDeclaration.Declaration.As(), StatementFlags.IsRightMost); } else { _writeContext.SetNodeProperty("Specifiers", (Node node) => ref node.As().Specifiers); Writer.WritePunctuator("{", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended | JavaScriptTextWriter.TokenFlags.Leading, ref _writeContext); VisitAuxiliaryNodeList(in exportNamedDeclaration.Specifiers, ","); Writer.WritePunctuator("}", JavaScriptTextWriter.TokenFlags.Trailing | JavaScriptTextWriter.TokenFlags.LeadingSpaceRecommended, ref _writeContext); if (exportNamedDeclaration.Source != null) { _writeContext.ClearNodeProperty(); Writer.WriteKeyword("from", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); _writeContext.SetNodeProperty("Source", (Node node) => node.As().Source); VisitRootExpression(exportNamedDeclaration.Source, RootExpressionFlags(needsBrackets: false)); if (exportNamedDeclaration.Attributes.Count > 0) { _writeContext.SetNodeProperty("Attributes", (Node node) => ref node.As().Attributes); VisitImportAttributes(in exportNamedDeclaration.Attributes); } } StatementNeedsSemicolon(); } return exportNamedDeclaration; } protected internal override object? VisitExportSpecifier(ExportSpecifier exportSpecifier) { _writeContext.SetNodeProperty("Local", (Node node) => node.As().Local); VisitExportOrImportSpecifierIdentifier(exportSpecifier.Local); if (exportSpecifier.Local != exportSpecifier.Exported) { _writeContext.ClearNodeProperty(); Writer.WriteKeyword("as", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); _writeContext.SetNodeProperty("Exported", (Node node) => node.As().Exported); VisitExportOrImportSpecifierIdentifier(exportSpecifier.Exported); } return exportSpecifier; } protected internal override object? VisitExpressionStatement(ExpressionStatement expressionStatement) { Writer.SpaceRecommendedAfterLastToken(); _writeContext.SetNodeProperty("Expression", (Node node) => node.As().Expression); VisitRootExpression(expressionStatement.Expression, ExpressionFlags.IsInsideStatementExpression | RootExpressionFlags(needsBrackets: false)); StatementNeedsSemicolon(); return expressionStatement; } protected internal override object? VisitExtension(Node node) { if (_ignoreExtensions) { Writer.WriteBlockComment(new string[1] { $" Unsupported node type ({node.GetType()}). " }, JavaScriptTextWriter.TriviaFlags.None); return node; } return base.VisitExtension(node); } protected internal override object? VisitForInStatement(ForInStatement forInStatement) { Writer.WriteKeyword("for", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); Writer.WritePunctuator("(", JavaScriptTextWriter.TokenFlags.Leading | JavaScriptTextWriter.TokenFlags.LeadingSpaceRecommended, ref _writeContext); _writeContext.SetNodeProperty("Left", (Node node) => node.As().Left); if (forInStatement.Left is VariableDeclaration statement) { VisitStatement(statement, StatementFlags.NestedVariableDeclaration); } else if (forInStatement.Left is Expression expression) { VisitRootExpression(expression, RootExpressionFlags(needsBrackets: false)); } else { VisitAuxiliaryNode(forInStatement.Left, (AstToJavaScriptConverter , Node ) => s_bindingPatternAllowsExpressionsFlag); } _writeContext.ClearNodeProperty(); Writer.WriteKeyword("in", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended | JavaScriptTextWriter.TokenFlags.InBetween, ref _writeContext); _writeContext.SetNodeProperty("Right", (Node node) => node.As().Right); VisitRootExpression(forInStatement.Right, RootExpressionFlags(needsBrackets: false)); _writeContext.ClearNodeProperty(); Writer.WritePunctuator(")", JavaScriptTextWriter.TokenFlags.Trailing | JavaScriptTextWriter.TokenFlags.TrailingSpaceRecommended, ref _writeContext); _writeContext.SetNodeProperty("Body", (Node node) => node.As().Body); VisitStatement(forInStatement.Body, StatementBodyFlags(isRightMost: true)); return forInStatement; } protected internal override object? VisitForOfStatement(ForOfStatement forOfStatement) { Writer.WriteKeyword("for", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); if (forOfStatement.Await) { _writeContext.SetNodeProperty("Await", (Node node) => node.As().Await); Writer.WriteKeyword("await", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); } Writer.WritePunctuator("(", JavaScriptTextWriter.TokenFlags.Leading | JavaScriptTextWriter.TokenFlags.LeadingSpaceRecommended, ref _writeContext); _writeContext.SetNodeProperty("Left", (Node node) => node.As().Left); if (forOfStatement.Left is VariableDeclaration statement) { VisitStatement(statement, StatementFlags.NestedVariableDeclaration); } else if (forOfStatement.Left is Expression expression) { VisitRootExpression(expression, RootExpressionFlags(needsBrackets: false)); } else { VisitAuxiliaryNode(forOfStatement.Left, (AstToJavaScriptConverter , Node ) => s_bindingPatternAllowsExpressionsFlag); } _writeContext.ClearNodeProperty(); Writer.WriteKeyword("of", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended | JavaScriptTextWriter.TokenFlags.InBetween, ref _writeContext); _writeContext.SetNodeProperty("Right", (Node node) => node.As().Right); VisitRootExpression(forOfStatement.Right, RootExpressionFlags(ExpressionNeedsBracketsInList(forOfStatement.Right))); _writeContext.ClearNodeProperty(); Writer.WritePunctuator(")", JavaScriptTextWriter.TokenFlags.Trailing | JavaScriptTextWriter.TokenFlags.TrailingSpaceRecommended, ref _writeContext); _writeContext.SetNodeProperty("Body", (Node node) => node.As().Body); VisitStatement(forOfStatement.Body, StatementBodyFlags(isRightMost: true)); return forOfStatement; } protected internal override object? VisitForStatement(ForStatement forStatement) { Writer.WriteKeyword("for", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); Writer.WritePunctuator("(", JavaScriptTextWriter.TokenFlags.Leading | JavaScriptTextWriter.TokenFlags.LeadingSpaceRecommended, ref _writeContext); _writeContext.SetNodeProperty("Init", (Node node) => node.As().Init); if (forStatement.Init != null) { if (forStatement.Init is VariableDeclaration statement) { VisitStatement(statement, StatementFlags.NestedVariableDeclaration); } else { VisitRootExpression(forStatement.Init.As(), ExpressionFlags.IsInAmbiguousInOperatorContext | RootExpressionFlags(needsBrackets: false)); } } Writer.WritePunctuator(";", JavaScriptTextWriter.TokenFlags.Trailing | JavaScriptTextWriter.TokenFlags.TrailingSpaceRecommended, ref _writeContext); _writeContext.SetNodeProperty("Test", (Node node) => node.As().Test); if (forStatement.Test != null) { VisitRootExpression(forStatement.Test, RootExpressionFlags(needsBrackets: false)); } Writer.WritePunctuator(";", JavaScriptTextWriter.TokenFlags.Trailing | JavaScriptTextWriter.TokenFlags.TrailingSpaceRecommended, ref _writeContext); if (forStatement.Update != null) { _writeContext.SetNodeProperty("Update", (Node node) => node.As().Update); VisitRootExpression(forStatement.Update, RootExpressionFlags(needsBrackets: false)); } _writeContext.ClearNodeProperty(); Writer.WritePunctuator(")", JavaScriptTextWriter.TokenFlags.Trailing | JavaScriptTextWriter.TokenFlags.TrailingSpaceRecommended, ref _writeContext); _writeContext.SetNodeProperty("Body", (Node node) => node.As().Body); VisitStatement(forStatement.Body, StatementBodyFlags(isRightMost: true)); return forStatement; } protected internal override object? VisitFunctionDeclaration(FunctionDeclaration functionDeclaration) { if (functionDeclaration.Async) { _writeContext.SetNodeProperty("Async", (Node node) => node.As().Async); Writer.WriteKeyword("async", JavaScriptTextWriter.TokenFlags.LeadingSpaceRecommended, ref _writeContext); _writeContext.ClearNodeProperty(); } Writer.WriteKeyword("function", JavaScriptTextWriter.TokenFlags.LeadingSpaceRecommended, ref _writeContext); if (functionDeclaration.Generator) { _writeContext.SetNodeProperty("Generator", (Node node) => node.As().Generator); Writer.WritePunctuator("*", (functionDeclaration.Id != null).ToFlag(JavaScriptTextWriter.TokenFlags.TrailingSpaceRecommended), ref _writeContext); } if (functionDeclaration.Id != null) { _writeContext.SetNodeProperty("Id", (Node node) => node.As().Id); VisitAuxiliaryNode(functionDeclaration.Id); } _writeContext.SetNodeProperty("Params", (Node node) => ref node.As().Params); Writer.WritePunctuator("(", JavaScriptTextWriter.TokenFlags.Leading, ref _writeContext); VisitAuxiliaryNodeList(in functionDeclaration.Params, ","); Writer.WritePunctuator(")", JavaScriptTextWriter.TokenFlags.Trailing, ref _writeContext); _writeContext.SetNodeProperty("Body", (Node node) => node.As().Body); VisitStatement(functionDeclaration.Body, StatementBodyFlags(isRightMost: true)); return functionDeclaration; } protected internal override object? VisitFunctionExpression(FunctionExpression functionExpression) { if (!_currentExpressionFlags.HasFlagFast(ExpressionFlags.IsMethod)) { if (functionExpression.Async) { _writeContext.SetNodeProperty("Async", (Node node) => node.As().Async); Writer.WriteKeyword("async", ref _writeContext); _writeContext.ClearNodeProperty(); } Writer.WriteKeyword("function", ref _writeContext); if (functionExpression.Generator) { _writeContext.SetNodeProperty("Generator", (Node node) => node.As().Generator); Writer.WritePunctuator("*", (functionExpression.Id != null).ToFlag(JavaScriptTextWriter.TokenFlags.TrailingSpaceRecommended), ref _writeContext); } if (functionExpression.Id != null) { _writeContext.SetNodeProperty("Id", (Node node) => node.As().Id); VisitAuxiliaryNode(functionExpression.Id); } } else { bool flag = true; if (functionExpression.Async) { _writeContext.SetNodeProperty("Async", (Node node) => node.As().Async); Writer.WriteKeyword("async", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); flag = false; } if (functionExpression.Generator) { _writeContext.SetNodeProperty("Generator", (Node node) => node.As().Generator); Writer.WritePunctuator("*", JavaScriptTextWriter.TokenFlags.LeadingSpaceRecommended, ref _writeContext); flag = false; } _writeContext.SetNodeProperty("Id", (Node node) => node.As().Id); IProperty property = (IProperty)ParentNode; if (property.Kind != PropertyKind.Constructor || property.Key.Type == Nodes.Literal) { if (flag && !property.Computed) { Writer.SpaceRecommendedAfterLastToken(); } VisitPropertyKey(property.Key, property.Computed, flag.ToFlag(JavaScriptTextWriter.TokenFlags.LeadingSpaceRecommended)); } else { Writer.WriteKeyword("constructor", JavaScriptTextWriter.TokenFlags.LeadingSpaceRecommended, ref _writeContext); } } _writeContext.SetNodeProperty("Params", (Node node) => ref node.As().Params); Writer.WritePunctuator("(", JavaScriptTextWriter.TokenFlags.Leading, ref _writeContext); VisitAuxiliaryNodeList(in functionExpression.Params, ","); Writer.WritePunctuator(")", JavaScriptTextWriter.TokenFlags.Trailing, ref _writeContext); _writeContext.SetNodeProperty("Body", (Node node) => node.As().Body); VisitStatement(functionExpression.Body, StatementBodyFlags(isRightMost: true)); return functionExpression; } protected internal override object? VisitIdentifier(Identifier identifier) { _writeContext.SetNodeProperty("Name", (Node node) => node.As().Name); Writer.WriteIdentifier(identifier.Name, ref _writeContext); return identifier; } protected internal override object? VisitIfStatement(IfStatement ifStatement) { Writer.WriteKeyword("if", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); _writeContext.SetNodeProperty("Test", (Node node) => node.As().Test); VisitRootExpression(ifStatement.Test, ExpressionFlags.SpaceAroundBracketsRecommended | RootExpressionFlags(needsBrackets: true)); _writeContext.SetNodeProperty("Consequent", (Node node) => node.As().Consequent); StatementFlags previousBodyFlags; VisitStatement(ifStatement.Consequent, previousBodyFlags = StatementBodyFlags(ifStatement.Alternate == null)); if (ifStatement.Alternate != null) { _writeContext.ClearNodeProperty(); Writer.WriteKeyword("else", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended | StatementBodyFlagsToKeywordFlags(previousBodyFlags), ref _writeContext); _writeContext.SetNodeProperty("Alternate", (Node node) => node.As().Alternate); VisitStatement(ifStatement.Alternate, StatementBodyFlags(isRightMost: true)); } return ifStatement; } protected internal override object? VisitImportAttribute(ImportAttribute importAttribute) { _writeContext.SetNodeProperty("Key", (Node node) => node.As().Key); VisitPropertyKey(importAttribute.Key, computed: false); Writer.WritePunctuator(":", JavaScriptTextWriter.TokenFlags.Trailing | JavaScriptTextWriter.TokenFlags.TrailingSpaceRecommended, ref _writeContext); _writeContext.SetNodeProperty("Value", (Node node) => node.As().Value); VisitRootExpression(importAttribute.Value, RootExpressionFlags(needsBrackets: false)); return importAttribute; } protected internal override object? VisitImportDeclaration(ImportDeclaration importDeclaration) { Writer.WriteKeyword("import", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); _writeContext.SetNodeProperty("Specifiers", (Node node) => ref node.As().Specifiers); Writer.StartAuxiliaryNodeList(importDeclaration.Specifiers.Count, ref _writeContext); if (importDeclaration.Specifiers.Count == 0) { Writer.EndAuxiliaryNodeList(0, ref _writeContext); goto IL_01f5; } int num = 0; Func getNodeContext = (AstToJavaScriptConverter , Node? , int , int ) => (object?)null; if (importDeclaration.Specifiers[num].Type == Nodes.ImportDefaultSpecifier) { VisitAuxiliaryNodeListItem(importDeclaration.Specifiers[num], num, importDeclaration.Specifiers.Count, ",", getNodeContext); if (++num >= importDeclaration.Specifiers.Count) { goto IL_01b3; } } if (importDeclaration.Specifiers[num].Type == Nodes.ImportNamespaceSpecifier) { VisitAuxiliaryNodeListItem(importDeclaration.Specifiers[num], num, importDeclaration.Specifiers.Count, ",", getNodeContext); if (++num >= importDeclaration.Specifiers.Count) { goto IL_01b3; } } Writer.WritePunctuator("{", JavaScriptTextWriter.TokenFlags.Leading | JavaScriptTextWriter.TokenFlags.TrailingSpaceRecommended, ref _writeContext); for (; num < importDeclaration.Specifiers.Count; num++) { VisitAuxiliaryNodeListItem(importDeclaration.Specifiers[num], num, importDeclaration.Specifiers.Count, ",", getNodeContext); } Writer.WritePunctuator("}", JavaScriptTextWriter.TokenFlags.Trailing | JavaScriptTextWriter.TokenFlags.LeadingSpaceRecommended, ref _writeContext); goto IL_01b3; IL_01f5: _writeContext.SetNodeProperty("Source", (Node node) => node.As().Source); VisitRootExpression(importDeclaration.Source, RootExpressionFlags(needsBrackets: false)); if (importDeclaration.Attributes.Count > 0) { _writeContext.SetNodeProperty("Attributes", (Node node) => ref node.As().Attributes); VisitImportAttributes(in importDeclaration.Attributes); } StatementNeedsSemicolon(); return importDeclaration; IL_01b3: Writer.EndAuxiliaryNodeList(importDeclaration.Specifiers.Count, ref _writeContext); _writeContext.ClearNodeProperty(); Writer.WriteKeyword("from", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); goto IL_01f5; } protected internal override object? VisitImportDefaultSpecifier(ImportDefaultSpecifier importDefaultSpecifier) { _writeContext.SetNodeProperty("Local", (Node node) => node.As().Local); VisitAuxiliaryNode(importDefaultSpecifier.Local); return importDefaultSpecifier; } protected internal override object? VisitImportExpression(ImportExpression importExpression) { Writer.WriteKeyword("import", ref _writeContext); Writer.WritePunctuator("(", JavaScriptTextWriter.TokenFlags.Leading, ref _writeContext); int count = ((importExpression.Options == null) ? 1 : 2); Writer.StartExpressionList(count, ref _writeContext); _writeContext.SetNodeProperty("Source", (Node node) => node.As().Source); VisitExpressionListItem(importExpression.Source, 0, count, (AstToJavaScriptConverter @this, Expression expression, int _, int _) => s_getCombinedSubExpressionFlags(@this, expression, SubExpressionFlags(@this.ExpressionNeedsBracketsInList(expression), isLeftMost: false))); if (importExpression.Options != null) { _writeContext.SetNodeProperty("Options", (Node node) => node.As().Options); VisitExpressionListItem(importExpression.Options, 1, count, (AstToJavaScriptConverter @this, Expression expression, int _, int _) => s_getCombinedSubExpressionFlags(@this, expression, SubExpressionFlags(@this.ExpressionNeedsBracketsInList(expression), isLeftMost: false))); } Writer.EndExpressionList(count, ref _writeContext); _writeContext.ClearNodeProperty(); Writer.WritePunctuator(")", JavaScriptTextWriter.TokenFlags.Trailing, ref _writeContext); return importExpression; } protected internal override object? VisitImportNamespaceSpecifier(ImportNamespaceSpecifier importNamespaceSpecifier) { Writer.WritePunctuator("*", JavaScriptTextWriter.TokenFlags.TrailingSpaceRecommended, ref _writeContext); Writer.WriteKeyword("as", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); _writeContext.SetNodeProperty("Local", (Node node) => node.As().Local); VisitAuxiliaryNode(importNamespaceSpecifier.Local); return importNamespaceSpecifier; } protected internal override object? VisitImportSpecifier(ImportSpecifier importSpecifier) { if (importSpecifier.Imported != importSpecifier.Local) { _writeContext.SetNodeProperty("Imported", (Node node) => node.As().Imported); VisitExportOrImportSpecifierIdentifier(importSpecifier.Imported); _writeContext.ClearNodeProperty(); Writer.WriteKeyword("as", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); } _writeContext.SetNodeProperty("Local", (Node node) => node.As().Local); VisitAuxiliaryNode(importSpecifier.Local); return importSpecifier; } protected internal override object? VisitLabeledStatement(LabeledStatement labeledStatement) { Writer.SpaceRecommendedAfterLastToken(); _writeContext.SetNodeProperty("Label", (Node node) => node.As().Label); VisitAuxiliaryNode(labeledStatement.Label); Writer.WritePunctuator(":", JavaScriptTextWriter.TokenFlags.Trailing | JavaScriptTextWriter.TokenFlags.TrailingSpaceRecommended, ref _writeContext); _writeContext.SetNodeProperty("Body", (Node node) => node.As().Body); VisitStatement(labeledStatement.Body, StatementFlags.IsRightMost); return labeledStatement; } protected internal override object? VisitLiteral(Literal literal) { _writeContext.SetNodeProperty("Raw", (Node node) => node.As().Raw); Writer.WriteLiteral(literal.Raw, literal.TokenType, ref _writeContext); return literal; } protected internal override object? VisitMemberExpression(MemberExpression memberExpression) { BinaryOperationFlags binaryOperationFlags = BinaryOperandsNeedBrackets(memberExpression, memberExpression.Object, memberExpression.Property); if (!binaryOperationFlags.HasFlagFast(BinaryOperationFlags.LeftOperandNeedsBrackets) && memberExpression != null && !memberExpression.Computed && !memberExpression.Optional && memberExpression.Object is Literal { TokenType: TokenType.NumericLiteral } literal && literal.Raw.IndexOf('.') < 0) { binaryOperationFlags |= BinaryOperationFlags.LeftOperandNeedsBrackets; } _writeContext.SetNodeProperty("Object", (Node node) => node.As().Object); VisitSubExpression(memberExpression.Object, SubExpressionFlags(binaryOperationFlags.HasFlagFast(BinaryOperationFlags.LeftOperandNeedsBrackets), isLeftMost: true)); if (memberExpression.Computed) { if (memberExpression.Optional) { _writeContext.ClearNodeProperty(); Writer.WritePunctuator("?.", JavaScriptTextWriter.TokenFlags.InBetween, ref _writeContext); } _writeContext.SetNodeProperty("Property", (Node node) => node.As().Property); Writer.WritePunctuator("[", JavaScriptTextWriter.TokenFlags.Leading, ref _writeContext); VisitSubExpression(memberExpression.Property, SubExpressionFlags(needsBrackets: false, isLeftMost: false)); Writer.WritePunctuator("]", JavaScriptTextWriter.TokenFlags.Trailing, ref _writeContext); } else { _writeContext.ClearNodeProperty(); Writer.WritePunctuator(memberExpression.Optional ? "?." : ".", JavaScriptTextWriter.TokenFlags.InBetween, ref _writeContext); _writeContext.SetNodeProperty("Property", (Node node) => node.As().Property); VisitSubExpression(memberExpression.Property, SubExpressionFlags(needsBrackets: false, isLeftMost: false)); } return memberExpression; } protected internal override object? VisitMetaProperty(MetaProperty metaProperty) { _writeContext.SetNodeProperty("Meta", (Node node) => node.As().Meta); Writer.WriteKeyword(metaProperty.Meta.Name, ref _writeContext); _writeContext.ClearNodeProperty(); Writer.WritePunctuator(".", JavaScriptTextWriter.TokenFlags.InBetween, ref _writeContext); _writeContext.SetNodeProperty("Property", (Node node) => node.As().Property); VisitSubExpression(metaProperty.Property, SubExpressionFlags(needsBrackets: false, isLeftMost: false)); return metaProperty; } protected internal override object? VisitMethodDefinition(MethodDefinition methodDefinition) { if (methodDefinition.Decorators.Count > 0) { _writeContext.SetNodeProperty("Decorators", (Node node) => ref node.As().Decorators); VisitAuxiliaryNodeList(in methodDefinition.Decorators, string.Empty); _writeContext.ClearNodeProperty(); } if (methodDefinition.Static) { _writeContext.SetNodeProperty("Static", (Node node) => node.As().Static); Writer.WriteKeyword("static", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); } switch (methodDefinition.Kind) { case PropertyKind.Get: _writeContext.SetNodeProperty("Kind", (Node node) => node.As().Kind); Writer.WriteKeyword("get", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); break; case PropertyKind.Set: _writeContext.SetNodeProperty("Kind", (Node node) => node.As().Kind); Writer.WriteKeyword("set", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); break; } _writeContext.SetNodeProperty("Value", (Node node) => node.As().Value); VisitRootExpression(methodDefinition.Value, ExpressionFlags.IsMethod | RootExpressionFlags(needsBrackets: false)); return methodDefinition; } protected internal override object? VisitNewExpression(NewExpression newExpression) { Writer.WriteKeyword("new", JavaScriptTextWriter.TokenFlags.TrailingSpaceRecommended, ref _writeContext); bool needsBrackets = UnaryOperandNeedsBrackets(newExpression, newExpression.Callee); _writeContext.SetNodeProperty("Callee", (Node node) => node.As().Callee); VisitExpression(newExpression.Callee, SubExpressionFlags(needsBrackets, isLeftMost: false), (AstToJavaScriptConverter @this, Expression expression, ExpressionFlags flags) => @this.DisambiguateExpression(expression, ExpressionFlags.IsLeftMostInNewCallee | ExpressionFlags.IsInsideNewCallee | @this.PropagateExpressionFlags(flags))); if (newExpression.Arguments.Count > 0) { _writeContext.SetNodeProperty("Arguments", (Node node) => ref node.As().Arguments); Writer.WritePunctuator("(", JavaScriptTextWriter.TokenFlags.Leading, ref _writeContext); VisitSubExpressionList(in newExpression.Arguments); Writer.WritePunctuator(")", JavaScriptTextWriter.TokenFlags.Trailing, ref _writeContext); } return newExpression; } protected internal override object? VisitObjectExpression(ObjectExpression objectExpression) { _writeContext.SetNodeProperty("Properties", (Node node2) => ref node2.As().Properties); Writer.StartObject(objectExpression.Properties.Count, ref _writeContext); Writer.StartAuxiliaryNodeList(objectExpression.Properties.Count, ref _writeContext); for (int num = 0; num < objectExpression.Properties.Count; num++) { Node node = objectExpression.Properties[num]; if (node is SpreadElement expression) { object currentAuxiliaryNodeContext = _currentAuxiliaryNodeContext; _currentAuxiliaryNodeContext = null; _writeContext.SetNodePropertyItemIndex(num); Writer.StartAuxiliaryNodeListItem(num, objectExpression.Properties.Count, ",", _currentAuxiliaryNodeContext, ref _writeContext); VisitRootExpression(expression, RootExpressionFlags(ExpressionNeedsBracketsInList(expression))); Writer.EndAuxiliaryNodeListItem(num, objectExpression.Properties.Count, ",", _currentAuxiliaryNodeContext, ref _writeContext); _currentAuxiliaryNodeContext = currentAuxiliaryNodeContext; } else { VisitAuxiliaryNodeListItem(node, num, objectExpression.Properties.Count, ",", (AstToJavaScriptConverter , Node? , int , int ) => (object?)null); } } Writer.EndAuxiliaryNodeList(objectExpression.Properties.Count, ref _writeContext); Writer.EndObject(objectExpression.Properties.Count, ref _writeContext); return objectExpression; } protected internal override object? VisitObjectPattern(ObjectPattern objectPattern) { _writeContext.SetNodeProperty("Properties", (Node node) => ref node.As().Properties); Writer.StartObject(objectPattern.Properties.Count, ref _writeContext); VisitAuxiliaryNodeList(in objectPattern.Properties, ",", (AstToJavaScriptConverter @this, Node? _, int _, int _) => (@this._currentAuxiliaryNodeContext != s_bindingPatternAllowsExpressionsFlag) ? null : s_bindingPatternAllowsExpressionsFlag); Writer.EndObject(objectPattern.Properties.Count, ref _writeContext); return objectPattern; } protected internal override object? VisitPrivateIdentifier(PrivateIdentifier privateIdentifier) { _writeContext.SetNodeProperty("Name", (Node node) => node.As().Name); Writer.WritePunctuator("#", JavaScriptTextWriter.TokenFlags.Leading, ref _writeContext); Writer.WriteIdentifier(privateIdentifier.Name, ref _writeContext); return privateIdentifier; } protected internal override object? VisitProgram(Program program) { _writeContext.SetNodeProperty("Body", (Node node) => ref node.As().Body); VisitStatementList(in program.Body); return program; } protected internal override object? VisitProperty(Property property) { bool value; switch (property.Kind) { case PropertyKind.Get: _writeContext.SetNodeProperty("Kind", (Node node) => node.As().Kind); Writer.WriteKeyword("get", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); value = true; break; case PropertyKind.Set: _writeContext.SetNodeProperty("Kind", (Node node) => node.As().Kind); Writer.WriteKeyword("set", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); value = true; break; case PropertyKind.Init: if (property.Method) { value = true; break; } goto default; default: if (!property.Shorthand) { _writeContext.SetNodeProperty("Key", (Node node) => node.As().Key); VisitPropertyKey(property.Key, property.Computed, JavaScriptTextWriter.TokenFlags.LeadingSpaceRecommended); Writer.WritePunctuator(":", JavaScriptTextWriter.TokenFlags.Trailing | JavaScriptTextWriter.TokenFlags.TrailingSpaceRecommended, ref _writeContext); } value = false; break; } _writeContext.SetNodeProperty("Value", (Node node) => node.As().Value); Node parentNode = ParentNode; if (parentNode != null && parentNode.Type == Nodes.ObjectPattern) { if (_currentAuxiliaryNodeContext != s_bindingPatternAllowsExpressionsFlag) { VisitAuxiliaryNode(property.Value); } else if (!(property.Value is Expression expression)) { VisitAuxiliaryNode(property.Value, (AstToJavaScriptConverter , Node ) => s_bindingPatternAllowsExpressionsFlag); } else { VisitRootExpression(expression, RootExpressionFlags(ExpressionNeedsBracketsInList(expression))); } } else { Expression expression2 = property.Value.As(); VisitRootExpression(expression2, value.ToFlag(ExpressionFlags.IsMethod) | RootExpressionFlags(ExpressionNeedsBracketsInList(expression2))); } return property; } protected internal override object? VisitPropertyDefinition(PropertyDefinition propertyDefinition) { if (propertyDefinition.Decorators.Count > 0) { _writeContext.SetNodeProperty("Decorators", (Node node) => ref node.As().Decorators); VisitAuxiliaryNodeList(in propertyDefinition.Decorators, string.Empty); _writeContext.ClearNodeProperty(); } if (propertyDefinition.Static) { _writeContext.SetNodeProperty("Static", (Node node) => node.As().Static); Writer.WriteKeyword("static", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); } else { Writer.SpaceRecommendedAfterLastToken(); } _writeContext.SetNodeProperty("Key", (Node node) => node.As().Key); VisitPropertyKey(propertyDefinition.Key, propertyDefinition.Computed, JavaScriptTextWriter.TokenFlags.LeadingSpaceRecommended); if (propertyDefinition.Value != null) { _writeContext.ClearNodeProperty(); Writer.WritePunctuator("=", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended | JavaScriptTextWriter.TokenFlags.InBetween, ref _writeContext); _writeContext.SetNodeProperty("Value", (Node node) => node.As().Value); VisitRootExpression(propertyDefinition.Value, RootExpressionFlags(ExpressionNeedsBracketsInList(propertyDefinition.Value))); } Writer.WritePunctuator(";", JavaScriptTextWriter.TokenFlags.Trailing | JavaScriptTextWriter.TokenFlags.TrailingSpaceRecommended, ref _writeContext); return propertyDefinition; } protected internal override object? VisitRestElement(RestElement restElement) { _writeContext.SetNodeProperty("Argument", (Node node) => node.As().Argument); Writer.WritePunctuator("...", JavaScriptTextWriter.TokenFlags.Leading, ref _writeContext); if (_currentAuxiliaryNodeContext != s_bindingPatternAllowsExpressionsFlag) { VisitAuxiliaryNode(restElement.Argument); } else if (!(restElement.Argument is Expression expression)) { VisitAuxiliaryNode(restElement.Argument, (AstToJavaScriptConverter , Node ) => s_bindingPatternAllowsExpressionsFlag); } else { VisitRootExpression(expression, RootExpressionFlags(ExpressionNeedsBracketsInList(expression))); } return restElement; } protected internal override object? VisitReturnStatement(ReturnStatement returnStatement) { Writer.WriteKeyword("return", (returnStatement.Argument != null).ToFlag(JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, JavaScriptTextWriter.TokenFlags.LeadingSpaceRecommended), ref _writeContext); if (returnStatement.Argument != null) { _writeContext.SetNodeProperty("Argument", (Node node) => node.As().Argument); VisitRootExpression(returnStatement.Argument, RootExpressionFlags(needsBrackets: false)); } StatementNeedsSemicolon(); return returnStatement; } protected internal override object? VisitSequenceExpression(SequenceExpression sequenceExpression) { _writeContext.SetNodeProperty("Expressions", (Node node) => ref node.As().Expressions); VisitExpressionList(in sequenceExpression.Expressions, (AstToJavaScriptConverter @this, Expression expression, int index, int _) => s_getCombinedSubExpressionFlags(@this, expression, SubExpressionFlags(@this.ExpressionNeedsBracketsInList(expression), index == 0))); return sequenceExpression; } protected internal override object? VisitSpreadElement(SpreadElement spreadElement) { bool needsBrackets = UnaryOperandNeedsBrackets(spreadElement, spreadElement.Argument); _writeContext.SetNodeProperty("Argument", (Node node) => node.As().Argument); Writer.WritePunctuator("...", JavaScriptTextWriter.TokenFlags.Leading, ref _writeContext); VisitSubExpression(spreadElement.Argument, SubExpressionFlags(needsBrackets, isLeftMost: false)); return spreadElement; } protected internal override object? VisitStaticBlock(StaticBlock staticBlock) { Writer.WriteKeyword("static", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); _writeContext.SetNodeProperty("Body", (Node node) => ref node.As().Body); Writer.StartBlock(staticBlock.Body.Count, ref _writeContext); VisitStatementList(in staticBlock.Body); Writer.EndBlock(staticBlock.Body.Count, ref _writeContext); return staticBlock; } protected internal override object? VisitSuper(Super super) { Writer.WriteKeyword("super", ref _writeContext); return super; } protected internal override object? VisitSwitchCase(SwitchCase switchCase) { if (switchCase.Test != null) { Writer.WriteKeyword("case", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); _writeContext.SetNodeProperty("Test", (Node node) => node.As().Test); VisitRootExpression(switchCase.Test, RootExpressionFlags(needsBrackets: false)); _writeContext.ClearNodeProperty(); } else { Writer.WriteKeyword("default", JavaScriptTextWriter.TokenFlags.LeadingSpaceRecommended, ref _writeContext); } Writer.WritePunctuator(":", JavaScriptTextWriter.TokenFlags.Trailing | JavaScriptTextWriter.TokenFlags.TrailingSpaceRecommended, ref _writeContext); _writeContext.SetNodeProperty("Consequent", (Node node) => ref node.As().Consequent); if (_currentAuxiliaryNodeContext == s_lastSwitchCaseFlag) { VisitStatementList(in switchCase.Consequent); } else { VisitStatementList(in switchCase.Consequent, (AstToJavaScriptConverter , Statement , int , int ) => StatementFlags.None); } return switchCase; } protected internal override object? VisitSwitchStatement(SwitchStatement switchStatement) { Writer.WriteKeyword("switch", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); _writeContext.SetNodeProperty("Discriminant", (Node node) => node.As().Discriminant); VisitRootExpression(switchStatement.Discriminant, ExpressionFlags.SpaceAroundBracketsRecommended | RootExpressionFlags(needsBrackets: true)); _writeContext.SetNodeProperty("Cases", (Node node) => ref node.As().Cases); Writer.StartBlock(switchStatement.Cases.Count, ref _writeContext); VisitAuxiliaryNodeList(in switchStatement.Cases, string.Empty, (AstToJavaScriptConverter _, Node? _, int index, int count) => (index != count - 1) ? null : s_lastSwitchCaseFlag); Writer.EndBlock(switchStatement.Cases.Count, ref _writeContext); return switchStatement; } protected internal override object? VisitTaggedTemplateExpression(TaggedTemplateExpression taggedTemplateExpression) { _writeContext.SetNodeProperty("Tag", (Node node) => node.As().Tag); VisitExpression(taggedTemplateExpression.Tag, SubExpressionFlags(needsBrackets: false, isLeftMost: true), (AstToJavaScriptConverter @this, Expression expression, ExpressionFlags flags) => @this.DisambiguateExpression(expression, ExpressionFlags.IsLeftMostInLeftHandSideExpression | ExpressionFlags.IsInsideLeftHandSideExpression | @this.PropagateExpressionFlags(flags))); _writeContext.SetNodeProperty("Quasi", (Node node) => node.As().Quasi); VisitSubExpression(taggedTemplateExpression.Quasi, SubExpressionFlags(needsBrackets: false, isLeftMost: false)); return taggedTemplateExpression; } protected internal override object? VisitTemplateElement(TemplateElement templateElement) { _writeContext.SetNodeProperty("Value", (Node node) => node.As().Value); Writer.WriteLiteral(templateElement.Value.Raw, TokenType.Template, ref _writeContext); return templateElement; } protected internal override object? VisitTemplateLiteral(TemplateLiteral templateLiteral) { Writer.WritePunctuator("`", JavaScriptTextWriter.TokenFlags.Leading, ref _writeContext); int num = 0; TemplateElement node; while (!(node = templateLiteral.Quasis[num]).Tail) { _writeContext.SetNodeProperty("Quasis", (Node node2) => ref node2.As().Quasis); _writeContext.SetNodePropertyItemIndex(num); VisitAuxiliaryNode(node); _writeContext.SetNodeProperty("Expressions", (Node node2) => ref node2.As().Expressions); _writeContext.SetNodePropertyItemIndex(num); Writer.WritePunctuator("${", JavaScriptTextWriter.TokenFlags.Leading, ref _writeContext); VisitRootExpression(templateLiteral.Expressions[num], RootExpressionFlags(needsBrackets: false)); Writer.WritePunctuator("}", JavaScriptTextWriter.TokenFlags.Trailing, ref _writeContext); num++; } _writeContext.SetNodeProperty("Quasis", (Node node2) => ref node2.As().Quasis); _writeContext.SetNodePropertyItemIndex(num); VisitAuxiliaryNode(node); Writer.WritePunctuator("`", JavaScriptTextWriter.TokenFlags.Trailing, ref _writeContext); return templateLiteral; } protected internal override object? VisitThisExpression(ThisExpression thisExpression) { Writer.WriteKeyword("this", ref _writeContext); return thisExpression; } protected internal override object? VisitThrowStatement(ThrowStatement throwStatement) { Writer.WriteKeyword("throw", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); _writeContext.SetNodeProperty("Argument", (Node node) => node.As().Argument); VisitRootExpression(throwStatement.Argument, RootExpressionFlags(needsBrackets: false)); StatementNeedsSemicolon(); return throwStatement; } protected internal override object? VisitTryStatement(TryStatement tryStatement) { Writer.WriteKeyword("try", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); _writeContext.SetNodeProperty("Block", (Node node) => node.As().Block); StatementFlags previousBodyFlags; VisitStatement(tryStatement.Block, previousBodyFlags = StatementBodyFlags(isRightMost: false)); if (tryStatement.Handler != null) { _writeContext.ClearNodeProperty(); Writer.WriteKeyword("catch", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended | StatementBodyFlagsToKeywordFlags(previousBodyFlags), ref _writeContext); _writeContext.SetNodeProperty("Handler", (Node node) => node.As().Handler); VisitAuxiliaryNode(tryStatement.Handler); previousBodyFlags = StatementBodyFlags(tryStatement.Finalizer == null); } if (tryStatement.Finalizer != null) { _writeContext.ClearNodeProperty(); Writer.WriteKeyword("finally", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended | StatementBodyFlagsToKeywordFlags(previousBodyFlags), ref _writeContext); _writeContext.SetNodeProperty("Finalizer", (Node node) => node.As().Finalizer); VisitStatement(tryStatement.Finalizer, StatementBodyFlags(isRightMost: true)); } return tryStatement; } protected internal override object? VisitUnaryExpression(UnaryExpression unaryExpression) { bool needsBrackets = UnaryOperandNeedsBrackets(unaryExpression, unaryExpression.Argument); string unaryOperatorToken = UnaryExpression.GetUnaryOperatorToken(unaryExpression.Operator); if (unaryExpression.Prefix) { _writeContext.SetNodeProperty("Operator", (Node node) => node.As().Operator); if (char.IsLetter(unaryOperatorToken[0])) { Writer.WriteKeyword(unaryOperatorToken, JavaScriptTextWriter.TokenFlags.TrailingSpaceRecommended, ref _writeContext); } else { Writer.WritePunctuator(unaryOperatorToken, JavaScriptTextWriter.TokenFlags.Leading | JavaScriptTextWriter.TokenFlags.IsUnaryOperator, ref _writeContext); } _writeContext.SetNodeProperty("Argument", (Node node) => node.As().Argument); VisitSubExpression(unaryExpression.Argument, SubExpressionFlags(needsBrackets, isLeftMost: false)); } else { _writeContext.SetNodeProperty("Argument", (Node node) => node.As().Argument); VisitSubExpression(unaryExpression.Argument, SubExpressionFlags(needsBrackets, isLeftMost: true)); _writeContext.SetNodeProperty("Operator", (Node node) => node.As().Operator); Writer.WritePunctuator(unaryOperatorToken, JavaScriptTextWriter.TokenFlags.Trailing | JavaScriptTextWriter.TokenFlags.IsUnaryOperator, ref _writeContext); } return unaryExpression; } protected internal override object? VisitVariableDeclaration(VariableDeclaration variableDeclaration) { _writeContext.SetNodeProperty("Kind", (Node node) => node.As().Kind); Writer.WriteKeyword(VariableDeclaration.GetVariableDeclarationKindToken(variableDeclaration.Kind), _currentStatementFlags.HasFlagFast(StatementFlags.NestedVariableDeclaration).ToFlag(JavaScriptTextWriter.TokenFlags.TrailingSpaceRecommended, JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended), ref _writeContext); _writeContext.SetNodeProperty("Declarations", (Node node) => ref node.As().Declarations); if (!_currentStatementFlags.HasFlagFast(StatementFlags.NestedVariableDeclaration)) { VisitAuxiliaryNodeList(in variableDeclaration.Declarations, ","); StatementNeedsSemicolon(); goto IL_012b; } Node parentNode = ParentNode; bool flag; if (parentNode != null) { Nodes type = parentNode.Type; if (type == Nodes.ForInStatement || type == Nodes.ForStatement) { flag = true; goto IL_00e5; } } flag = false; goto IL_00e5; IL_012b: return variableDeclaration; IL_00e5: if (!flag) { VisitAuxiliaryNodeList(in variableDeclaration.Declarations, ","); } else { VisitAuxiliaryNodeList(in variableDeclaration.Declarations, ",", (AstToJavaScriptConverter , Node? , int , int ) => s_forLoopInitDeclarationFlag); } goto IL_012b; } protected internal override object? VisitVariableDeclarator(VariableDeclarator variableDeclarator) { _writeContext.SetNodeProperty("Id", (Node node) => node.As().Id); VisitAuxiliaryNode(variableDeclarator.Id); if (variableDeclarator.Init != null) { _writeContext.ClearNodeProperty(); Writer.WritePunctuator("=", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended | JavaScriptTextWriter.TokenFlags.InBetween, ref _writeContext); _writeContext.SetNodeProperty("Init", (Node node) => node.As().Init); if (_currentAuxiliaryNodeContext != s_forLoopInitDeclarationFlag) { VisitRootExpression(variableDeclarator.Init, RootExpressionFlags(ExpressionNeedsBracketsInList(variableDeclarator.Init))); } else { VisitRootExpression(variableDeclarator.Init, ExpressionFlags.IsInAmbiguousInOperatorContext | RootExpressionFlags(ExpressionNeedsBracketsInList(variableDeclarator.Init))); } } return variableDeclarator; } protected internal override object? VisitWhileStatement(WhileStatement whileStatement) { Writer.WriteKeyword("while", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); _writeContext.SetNodeProperty("Test", (Node node) => node.As().Test); VisitRootExpression(whileStatement.Test, ExpressionFlags.SpaceAroundBracketsRecommended | RootExpressionFlags(needsBrackets: true)); _writeContext.SetNodeProperty("Body", (Node node) => node.As().Body); VisitStatement(whileStatement.Body, StatementBodyFlags(isRightMost: true)); return whileStatement; } protected internal override object? VisitWithStatement(WithStatement withStatement) { Writer.WriteKeyword("with", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); _writeContext.SetNodeProperty("Object", (Node node) => node.As().Object); VisitRootExpression(withStatement.Object, ExpressionFlags.SpaceAroundBracketsRecommended | RootExpressionFlags(needsBrackets: true)); _writeContext.SetNodeProperty("Body", (Node node) => node.As().Body); VisitStatement(withStatement.Body, StatementBodyFlags(isRightMost: true)); return withStatement; } protected internal override object? VisitYieldExpression(YieldExpression yieldExpression) { Writer.WriteKeyword("yield", (!yieldExpression.Delegate && yieldExpression.Argument != null).ToFlag(JavaScriptTextWriter.TokenFlags.TrailingSpaceRecommended), ref _writeContext); if (yieldExpression.Delegate) { _writeContext.SetNodeProperty("Delegate", (Node node) => node.As().Delegate); Writer.WritePunctuator("*", (yieldExpression.Argument != null).ToFlag(JavaScriptTextWriter.TokenFlags.TrailingSpaceRecommended), ref _writeContext); } if (yieldExpression.Argument != null) { bool needsBrackets = UnaryOperandNeedsBrackets(yieldExpression, yieldExpression.Argument); _writeContext.SetNodeProperty("Argument", (Node node) => node.As().Argument); VisitSubExpression(yieldExpression.Argument, SubExpressionFlags(needsBrackets, isLeftMost: false)); } return yieldExpression; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private protected static StatementFlags StatementBodyFlags(bool isRightMost) { return StatementFlags.IsStatementBody | isRightMost.ToFlag(StatementFlags.IsRightMost); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private protected static JavaScriptTextWriter.TokenFlags StatementBodyFlagsToKeywordFlags(StatementFlags previousBodyFlags) { return (JavaScriptTextWriter.TokenFlags)(previousBodyFlags & StatementFlags.IsStatementBody); } protected StatementFlags PropagateStatementFlags(StatementFlags flags) { flags &= ~StatementFlags.IsRightMost | (_currentStatementFlags & StatementFlags.IsRightMost); flags |= _currentStatementFlags & StatementFlags.MayOmitRightMostSemicolon; return flags; } [MethodImpl(MethodImplOptions.AggressiveInlining)] protected void VisitStatement(Statement statement, StatementFlags flags) { VisitStatement(statement, flags, s_getCombinedStatementFlags); } protected void VisitStatement(Statement statement, StatementFlags flags, Func getCombinedFlags) { StatementFlags currentStatementFlags = _currentStatementFlags; _currentStatementFlags = getCombinedFlags(this, statement, flags); Writer.StartStatement((JavaScriptTextWriter.StatementFlags)_currentStatementFlags, ref _writeContext); Visit(statement); Writer.EndStatement((JavaScriptTextWriter.StatementFlags)_currentStatementFlags, ref _writeContext); _currentStatementFlags = currentStatementFlags; } [MethodImpl(MethodImplOptions.AggressiveInlining)] protected void VisitStatementList(in NodeList statementList) { VisitStatementList(in statementList, (AstToJavaScriptConverter _, Statement _, int index, int count) => (index == count - 1).ToFlag(StatementFlags.MayOmitRightMostSemicolon | StatementFlags.IsRightMost)); } protected void VisitStatementList(in NodeList statementList, Func getCombinedItemFlags) { Writer.StartStatementList(statementList.Count, ref _writeContext); for (int i = 0; i < statementList.Count; i++) { VisitStatementListItem(statementList[i], i, statementList.Count, getCombinedItemFlags); } Writer.EndStatementList(statementList.Count, ref _writeContext); } protected void VisitStatementListItem(Statement statement, int index, int count, Func getCombinedFlags) { StatementFlags currentStatementFlags = _currentStatementFlags; _currentStatementFlags = getCombinedFlags(this, statement, index, count); _writeContext.SetNodePropertyItemIndex(index); Writer.StartStatementListItem(index, count, (JavaScriptTextWriter.StatementFlags)_currentStatementFlags, ref _writeContext); Visit(statement); Writer.EndStatementListItem(index, count, (JavaScriptTextWriter.StatementFlags)_currentStatementFlags, ref _writeContext); _currentStatementFlags = currentStatementFlags; } [MethodImpl(MethodImplOptions.AggressiveInlining)] protected void StatementNeedsSemicolon() { _currentStatementFlags |= StatementFlags.NeedsSemicolon; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private protected static ExpressionFlags RootExpressionFlags(bool needsBrackets) { return ExpressionFlags.IsLeftMost | ExpressionFlags.IsRootExpression | needsBrackets.ToFlag(ExpressionFlags.NeedsBrackets); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private protected static ExpressionFlags SubExpressionFlags(bool needsBrackets, bool isLeftMost) { return needsBrackets.ToFlag(ExpressionFlags.NeedsBrackets) | isLeftMost.ToFlag(ExpressionFlags.IsLeftMost); } protected ExpressionFlags PropagateExpressionFlags(ExpressionFlags flags) { flags = ((!_currentExpressionFlags.HasFlagFast(ExpressionFlags.NeedsBrackets) && flags.HasFlagFast(ExpressionFlags.IsLeftMost)) ? ((flags & ~(ExpressionFlags.IsLeftMost | ExpressionFlags.IsLeftMostInArrowFunctionBody | ExpressionFlags.IsLeftMostInNewCallee | ExpressionFlags.IsLeftMostInLeftHandSideExpression)) | (_currentExpressionFlags & (ExpressionFlags.IsLeftMost | ExpressionFlags.IsLeftMostInArrowFunctionBody | ExpressionFlags.IsLeftMostInNewCallee | ExpressionFlags.IsLeftMostInLeftHandSideExpression))) : (flags & ~(ExpressionFlags.IsLeftMost | ExpressionFlags.IsLeftMostInArrowFunctionBody | ExpressionFlags.IsLeftMostInNewCallee | ExpressionFlags.IsLeftMostInLeftHandSideExpression))); flags |= _currentExpressionFlags & ExpressionFlags.IsInPotentiallyAmbiguousContext; return flags; } protected ExpressionFlags DisambiguateExpression(Expression expression, ExpressionFlags flags) { if (flags.HasFlagFast(ExpressionFlags.NeedsBrackets)) { return flags & ~ExpressionFlags.IsInAmbiguousInOperatorContext; } if ((flags & ExpressionFlags.IsInPotentiallyAmbiguousContext) != ExpressionFlags.None && ((flags.HasFlag(ExpressionFlags.IsLeftMost) && ((flags.HasFlagFast(ExpressionFlags.IsInsideStatementExpression) && ExpressionIsAmbiguousAsStatementExpression(expression)) || (flags.HasFlagFast(ExpressionFlags.IsInsideExportDefaultExpression) && ExpressionIsAmbiguousAsExportDefaultExpression(expression)) || (flags.HasFlagFast(ExpressionFlags.IsInsideDecorator) && DecoratorLeftMostExpressionIsParenthesized(expression, flags.HasFlagFast(ExpressionFlags.IsRootExpression))))) || (flags.HasFlagFast(ExpressionFlags.IsLeftMostInArrowFunctionBody | ExpressionFlags.IsInsideArrowFunctionBody) && ExpressionIsAmbiguousAsArrowFunctionBody(expression)) || (flags.HasFlagFast(ExpressionFlags.IsLeftMostInNewCallee | ExpressionFlags.IsInsideNewCallee) && ExpressionIsAmbiguousAsNewCallee(expression)) || (flags.HasFlagFast(ExpressionFlags.IsLeftMostInLeftHandSideExpression | ExpressionFlags.IsInsideLeftHandSideExpression) && LeftHandSideExpressionIsParenthesized(expression)) || (flags.HasFlagFast(ExpressionFlags.IsInAmbiguousInOperatorContext) && expression is BinaryExpression { Operator: BinaryOperator.In }))) { return (flags | ExpressionFlags.NeedsBrackets) & ~ExpressionFlags.IsInAmbiguousInOperatorContext; } return flags; } [MethodImpl(MethodImplOptions.AggressiveInlining)] protected void VisitRootExpression(Expression expression, ExpressionFlags flags) { VisitExpression(expression, flags, s_getCombinedRootExpressionFlags); } [MethodImpl(MethodImplOptions.AggressiveInlining)] protected void VisitSubExpression(Expression expression, ExpressionFlags flags) { VisitExpression(expression, flags, s_getCombinedSubExpressionFlags); } protected void VisitExpression(Expression expression, ExpressionFlags flags, Func getCombinedFlags) { ExpressionFlags currentExpressionFlags = _currentExpressionFlags; _currentExpressionFlags = getCombinedFlags(this, expression, flags); Writer.StartExpression((JavaScriptTextWriter.ExpressionFlags)_currentExpressionFlags, ref _writeContext); Visit(expression); Writer.EndExpression((JavaScriptTextWriter.ExpressionFlags)_currentExpressionFlags, ref _writeContext); _currentExpressionFlags = currentExpressionFlags; } [MethodImpl(MethodImplOptions.AggressiveInlining)] protected void VisitSubExpressionList(in NodeList expressionList) { VisitExpressionList(in expressionList, (AstToJavaScriptConverter @this, Expression expression, int index, int _) => s_getCombinedSubExpressionFlags(@this, expression, SubExpressionFlags(@this.ExpressionNeedsBracketsInList(expression), isLeftMost: false))); } protected void VisitExpressionList(in NodeList expressionList, Func getCombinedItemFlags) { Writer.StartExpressionList(expressionList.Count, ref _writeContext); for (int i = 0; i < expressionList.Count; i++) { VisitExpressionListItem(expressionList[i], i, expressionList.Count, getCombinedItemFlags); } Writer.EndExpressionList(expressionList.Count, ref _writeContext); } protected void VisitExpressionListItem(Expression expression, int index, int count, Func getCombinedFlags) { ExpressionFlags currentExpressionFlags = _currentExpressionFlags; _currentExpressionFlags = getCombinedFlags(this, expression, index, count); _writeContext.SetNodePropertyItemIndex(index); Writer.StartExpressionListItem(index, count, (JavaScriptTextWriter.ExpressionFlags)_currentExpressionFlags, ref _writeContext); Visit(expression); Writer.EndExpressionListItem(index, count, (JavaScriptTextWriter.ExpressionFlags)_currentExpressionFlags, ref _writeContext); _currentExpressionFlags = currentExpressionFlags; } private void VisitImportAttributes(in NodeList attributes) { Writer.WriteKeyword("with", JavaScriptTextWriter.TokenFlags.SurroundingSpaceRecommended, ref _writeContext); Writer.StartObject(attributes.Count, ref _writeContext); VisitAuxiliaryNodeList(in attributes, ","); Writer.EndObject(attributes.Count, ref _writeContext); } private void VisitExportOrImportSpecifierIdentifier(Expression identifierExpression) { if (identifierExpression is Identifier { Name: "default" }) { Writer.WriteKeyword("default", ref _writeContext); } else { VisitRootExpression(identifierExpression, RootExpressionFlags(needsBrackets: false)); } } private void VisitPropertyKey(Expression key, bool computed, JavaScriptTextWriter.TokenFlags leadingBracketFlags = JavaScriptTextWriter.TokenFlags.None, JavaScriptTextWriter.TokenFlags trailingBracketFlags = JavaScriptTextWriter.TokenFlags.None) { if (computed) { Writer.WritePunctuator("[", JavaScriptTextWriter.TokenFlags.Leading | leadingBracketFlags, ref _writeContext); VisitRootExpression(key, RootExpressionFlags(ExpressionNeedsBracketsInList(key))); Writer.WritePunctuator("]", JavaScriptTextWriter.TokenFlags.Trailing | trailingBracketFlags, ref _writeContext); } else if (key.Type == Nodes.Identifier) { VisitAuxiliaryNode(key); } else { VisitRootExpression(key, RootExpressionFlags(needsBrackets: false)); } } protected virtual bool ExpressionIsAmbiguousAsStatementExpression(Expression expression) { Nodes type = expression.Type; if (type <= Nodes.ClassExpression) { if (type != Nodes.AssignmentExpression) { if (type == Nodes.ClassExpression) { goto IL_005a; } } else { AssignmentExpression assignmentExpression = expression.As(); if (assignmentExpression != null) { Node left = assignmentExpression.Left; if (left != null && left.Type == Nodes.ObjectPattern) { goto IL_005a; } } } } else { if (type == Nodes.FunctionExpression) { goto IL_005a; } if (type != Nodes.Identifier) { if (type == Nodes.ObjectExpression) { goto IL_005a; } } else if (Scanner.IsStrictModeReservedWord(expression.As().Name)) { goto IL_005a; } } return false; IL_005a: return true; } protected virtual bool ExpressionIsAmbiguousAsExportDefaultExpression(Expression expression) { Nodes type = expression.Type; if (type <= Nodes.FunctionExpression) { if (type == Nodes.ClassExpression || type == Nodes.FunctionExpression) { goto IL_0036; } } else if (type != Nodes.Identifier) { if (type == Nodes.SequenceExpression) { goto IL_0036; } } else if (Scanner.IsStrictModeReservedWord(expression.As().Name)) { goto IL_0036; } return false; IL_0036: return true; } protected virtual bool ExpressionIsAmbiguousAsArrowFunctionBody(Expression expression) { Nodes type = expression.Type; if (type != Nodes.AssignmentExpression) { if (type == Nodes.ObjectExpression) { goto IL_0030; } } else { AssignmentExpression assignmentExpression = expression.As(); if (assignmentExpression != null) { Node left = assignmentExpression.Left; if (left != null && left.Type == Nodes.ObjectPattern) { goto IL_0030; } } } return false; IL_0030: return true; } protected virtual bool ExpressionIsAmbiguousAsNewCallee(Expression expression) { if (expression.Type == Nodes.CallExpression) { return true; } return false; } protected virtual bool LeftHandSideExpressionIsParenthesized(Expression expression) { switch (expression.Type) { case Nodes.ClassExpression: if (expression.As().Decorators.Count <= 0) { break; } goto case Nodes.ArrowFunctionExpression; case Nodes.NewExpression: if (expression.As().Arguments.Count != 0) { break; } goto case Nodes.ArrowFunctionExpression; case Nodes.ArrowFunctionExpression: case Nodes.AssignmentExpression: case Nodes.AwaitExpression: case Nodes.BinaryExpression: case Nodes.ChainExpression: case Nodes.ConditionalExpression: case Nodes.LogicalExpression: case Nodes.SequenceExpression: case Nodes.UnaryExpression: case Nodes.UpdateExpression: case Nodes.YieldExpression: return true; } return false; } protected virtual bool DecoratorLeftMostExpressionIsParenthesized(Expression expression, bool isRoot) { Nodes type = expression.Type; if (type != Nodes.CallExpression) { if (type != Nodes.Identifier) { if (type == Nodes.MemberExpression) { MemberExpression memberExpression = expression.As(); if (memberExpression != null && !memberExpression.Computed) { goto IL_0028; } } return true; } goto IL_0028; } return !isRoot; IL_0028: return false; } protected virtual bool ExpressionNeedsBracketsInList(Expression expression) { return expression.Type == Nodes.SequenceExpression; } protected virtual int GetOperatorPrecedence(Expression expression, out int associativity) { int operatorPrecedence = expression.GetOperatorPrecedence(out associativity); if (operatorPrecedence >= 0) { return operatorPrecedence; } if (_ignoreExtensions) { return int.MinValue; } throw new NotImplementedException($"Operator precedence for expression of type {expression.GetType()} is not defined."); } protected bool UnaryOperandNeedsBrackets(Expression operation, Expression operand) { int associativity; return GetOperatorPrecedence(operation, out associativity) > GetOperatorPrecedence(operand, out associativity); } protected BinaryOperationFlags BinaryOperandsNeedBrackets(Expression operation, Expression leftOperand, Expression rightOperand) { int associativity; int operatorPrecedence = GetOperatorPrecedence(operation, out associativity); int associativity2; int operatorPrecedence2 = GetOperatorPrecedence(leftOperand, out associativity2); int operatorPrecedence3 = GetOperatorPrecedence(rightOperand, out associativity2); BinaryOperationFlags binaryOperationFlags = BinaryOperationFlags.None; if (operatorPrecedence > operatorPrecedence2 || (operatorPrecedence == operatorPrecedence2 && associativity > 0)) { binaryOperationFlags |= BinaryOperationFlags.LeftOperandNeedsBrackets; } if (operatorPrecedence > operatorPrecedence3 || (operatorPrecedence == operatorPrecedence3 && associativity < 0)) { binaryOperationFlags |= BinaryOperationFlags.RightOperandNeedsBrackets; } return binaryOperationFlags; } [MethodImpl(MethodImplOptions.AggressiveInlining)] protected void VisitAuxiliaryNode(Node node) { VisitAuxiliaryNode(node, (AstToJavaScriptConverter , Node ) => (object?)null); } protected void VisitAuxiliaryNode(Node node, Func getNodeContext) { object currentAuxiliaryNodeContext = _currentAuxiliaryNodeContext; _currentAuxiliaryNodeContext = getNodeContext(this, node); Writer.StartAuxiliaryNode(_currentAuxiliaryNodeContext, ref _writeContext); Visit(node); Writer.EndAuxiliaryNode(_currentAuxiliaryNodeContext, ref _writeContext); _currentAuxiliaryNodeContext = currentAuxiliaryNodeContext; } [MethodImpl(MethodImplOptions.AggressiveInlining)] protected void VisitAuxiliaryNodeList(in NodeList nodeList, string separator) where TNode : Node { VisitAuxiliaryNodeList(in nodeList, separator, (AstToJavaScriptConverter , Node? , int , int ) => (object?)null); } protected void VisitAuxiliaryNodeList(in NodeList nodeList, string separator, Func getNodeContext) where TNode : Node { Writer.StartAuxiliaryNodeList(nodeList.Count, ref _writeContext); for (int i = 0; i < nodeList.Count; i++) { VisitAuxiliaryNodeListItem(nodeList[i], i, nodeList.Count, separator, getNodeContext); } Writer.EndAuxiliaryNodeList(nodeList.Count, ref _writeContext); } protected void VisitAuxiliaryNodeListItem(TNode node, int index, int count, string separator, Func getNodeContext) where TNode : Node { object currentAuxiliaryNodeContext = _currentAuxiliaryNodeContext; _currentAuxiliaryNodeContext = getNodeContext(this, node, index, count); _writeContext.SetNodePropertyItemIndex(index); Writer.StartAuxiliaryNodeListItem(index, count, separator, _currentAuxiliaryNodeContext, ref _writeContext); Visit(node); Writer.EndAuxiliaryNodeListItem(index, count, separator, _currentAuxiliaryNodeContext, ref _writeContext); _currentAuxiliaryNodeContext = currentAuxiliaryNodeContext; } } public enum LocationMembersPlacement { End, Start } internal enum AstToJsonTestCompatibilityMode { None, EsprimaOrg } public record AstToJsonOptions { public bool IncludeTokens { get; init; } public bool IncludeComments { get; init; } public bool IncludeLineColumn { get; init; } public bool IncludeRange { get; init; } public LocationMembersPlacement LocationMembersPlacement { get; init; } internal AstToJsonTestCompatibilityMode TestCompatibilityMode { get; init; } public static readonly AstToJsonOptions Default = new AstToJsonOptions(); protected internal virtual AstToJsonConverter CreateConverter(JsonWriter writer) { return new AstToJsonConverter(writer, this); } [CompilerGenerated] protected virtual bool PrintMembers(StringBuilder builder) { RuntimeHelpers.EnsureSufficientExecutionStack(); builder.Append("IncludeTokens = "); builder.Append(IncludeTokens.ToString()); builder.Append(", IncludeComments = "); builder.Append(IncludeComments.ToString()); builder.Append(", IncludeLineColumn = "); builder.Append(IncludeLineColumn.ToString()); builder.Append(", IncludeRange = "); builder.Append(IncludeRange.ToString()); builder.Append(", LocationMembersPlacement = "); builder.Append(LocationMembersPlacement.ToString()); return true; } [CompilerGenerated] protected AstToJsonOptions(AstToJsonOptions original) { IncludeTokens = original.IncludeTokens; IncludeComments = original.IncludeComments; IncludeLineColumn = original.IncludeLineColumn; IncludeRange = original.IncludeRange; LocationMembersPlacement = original.LocationMembersPlacement; TestCompatibilityMode = original.TestCompatibilityMode; } public AstToJsonOptions() { } } public static class AstToJson { public static string ToJsonString(this Node node) { return node.ToJsonString((string?)null); } public static string ToJsonString(this Node node, string? indent) { return node.ToJsonString(AstToJsonOptions.Default, indent); } public static string ToJsonString(this Node node, AstToJsonOptions options) { return node.ToJsonString(options, null); } public static string ToJsonString(this Node node, AstToJsonOptions options, string? indent) { using StringWriter stringWriter = new StringWriter(); node.WriteJson(stringWriter, options, indent); return stringWriter.ToString(); } public static void WriteJson(this Node node, TextWriter writer) { node.WriteJson(writer, (string?)null); } public static void WriteJson(this Node node, TextWriter writer, string? indent) { node.WriteJson(writer, AstToJsonOptions.Default, indent); } public static void WriteJson(this Node node, TextWriter writer, AstToJsonOptions options) { node.WriteJson(writer, options, null); } public static void WriteJson(this Node node, TextWriter writer, AstToJsonOptions options, string? indent) { node.WriteJson(new JsonTextWriter(writer, indent), options); } public static void WriteJson(this Node node, JsonWriter writer, AstToJsonOptions options) { if ((object)options == null) { throw new ArgumentNullException("options"); } options.CreateConverter(writer).Convert(node); } } public class AstToJsonConverter : AstVisitor { protected readonly struct NodeObjectDisposable : IDisposable { private readonly AstToJsonConverter _converter; private readonly Node _node; public NodeObjectDisposable(AstToJsonConverter converter, Node node) { _converter = converter; _node = node; } public void Dispose() { if (_node is ISyntaxTreeRoot syntaxTreeRoot) { if (_converter._includeComments) { IReadOnlyList comments = syntaxTreeRoot.Comments; if (comments != null) { _converter._writer.Member("comments"); _converter.WriteComments(comments); } } if (_converter._includeTokens) { IReadOnlyList tokens = syntaxTreeRoot.Tokens; if (tokens != null) { _converter._writer.Member("tokens"); _converter.WriteTokens(tokens); } } } _converter.OnEndSyntaxElementObject(_node); } } private sealed class ImportCompat : Expression { public ImportCompat() : base(Nodes.ImportExpression) { } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return null; } protected internal override object? Accept(AstVisitor visitor) { return ((AstToJsonConverter)visitor).VisitImportCompat(this); } } private readonly JsonWriter _writer; private protected readonly bool _includeTokens; private protected readonly bool _includeComments; private protected readonly bool _includeLineColumn; private protected readonly bool _includeRange; private protected readonly LocationMembersPlacement _locationMembersPlacement; private protected readonly AstToJsonTestCompatibilityMode _testCompatibilityMode; private static readonly ConditionalWeakTable EnumMap = new ConditionalWeakTable(); public AstToJsonConverter(JsonWriter writer, AstToJsonOptions options) { _writer = writer ?? throw new ArgumentNullException("writer"); if ((object)options == null) { throw new ArgumentNullException("options"); } _includeTokens = options.IncludeTokens; _includeComments = options.IncludeComments; _includeLineColumn = options.IncludeLineColumn; _includeRange = options.IncludeRange; _locationMembersPlacement = options.LocationMembersPlacement; _testCompatibilityMode = options.TestCompatibilityMode; } protected virtual string GetNodeType(Node node) { return node.Type.ToString(); } protected virtual string GetTokenType(SyntaxToken token) { return token.Type.ToString(); } protected virtual string GetCommentType(SyntaxComment comment) { return comment.Type.ToString(); } private void WriteLocationInfo(SyntaxElement element) { if (_testCompatibilityMode != AstToJsonTestCompatibilityMode.EsprimaOrg || !(element is ChainExpression)) { if (_includeRange) { _writer.Member("range"); _writer.StartArray(); _writer.Number(element.Range.Start); _writer.Number(element.Range.End); _writer.EndArray(); } if (_includeLineColumn) { _writer.Member("loc"); _writer.StartObject(); _writer.Member("start"); Write(element.Location.Start); _writer.Member("end"); Write(element.Location.End); _writer.EndObject(); } } void Write(Position position) { _writer.StartObject(); Member("line", position.Line); Member("column", position.Column); _writer.EndObject(); } } private void WriteRegexValue(RegexValue value) { _writer.StartObject(); Member("pattern", value.Pattern); Member("flags", value.Flags); _writer.EndObject(); } private void WriteTokens(IReadOnlyList tokens) { _writer.StartArray(); foreach (SyntaxToken token in tokens) { OnStartSyntaxElementObject(token); Member("type", GetTokenType(token)); Member("value", token.Value); if ((object)token.RegexValue != null) { _writer.Member("regex"); WriteRegexValue(token.RegexValue); } OnEndSyntaxElementObject(token); } _writer.EndArray(); } private void WriteComments(IReadOnlyList comments) { _writer.StartArray(); foreach (SyntaxComment comment in comments) { OnStartSyntaxElementObject(comment); Member("type", GetCommentType(comment)); Member("value", comment.Value); OnEndSyntaxElementObject(comment); } _writer.EndArray(); } private void OnStartSyntaxElementObject(SyntaxElement element) { _writer.StartObject(); if ((_includeLineColumn || _includeRange) && _locationMembersPlacement == LocationMembersPlacement.Start) { WriteLocationInfo(element); } } private void OnEndSyntaxElementObject(SyntaxElement element) { if ((_includeLineColumn || _includeRange) && _locationMembersPlacement == LocationMembersPlacement.End) { WriteLocationInfo(element); } _writer.EndObject(); } protected NodeObjectDisposable StartNodeObject(Node node) { OnStartSyntaxElementObject(node); Member("type", GetNodeType(node)); return new NodeObjectDisposable(this, node); } protected void EmptyNodeObject(Node node) { using (StartNodeObject(node)) { } } protected void Member(string name) { _writer.Member(name); } protected void Member(string name, Node? node) { Member(name); Visit(node); } protected void Member(string name, string? value) { Member(name); _writer.String(value); } protected void Member(string name, bool value) { Member(name); _writer.Boolean(value); } protected void Member(string name, int value) { Member(name); _writer.Number(value); } protected void Member(string name, T value) where T : Enum { Dictionary dictionary = (Dictionary)EnumMap.GetValue(value.GetType(), (Type t) => (from f in t.GetRuntimeFields() where f.IsStatic select f).ToDictionary((FieldInfo f) => (T)f.GetValue(null), (FieldInfo f) => f.Name.ToLowerInvariant())); Member(name, dictionary[value]); } protected void Member(string name, in NodeList nodes) where T : Node? { Member(name, in nodes, (T node) => node); } protected void Member(string name, in NodeList list, Func nodeSelector) where T : Node? { Member(name); _writer.StartArray(); foreach (T item in list) { Visit(nodeSelector(item)); } _writer.EndArray(); } public void Convert(Node node) { Visit(node ?? throw new ArgumentNullException("node")); } public override object? Visit(Node? node) { if (node != null) { return base.Visit(node); } _writer.Null(); return node; } protected internal override object? VisitAccessorProperty(AccessorProperty accessorProperty) { using (StartNodeObject(accessorProperty)) { Member("key", (Node?)accessorProperty.Key); Member("computed", accessorProperty.Computed); Member("value", (Node?)accessorProperty.Value); Member("kind", accessorProperty.Kind); Member("static", accessorProperty.Static); if (accessorProperty.Decorators.Count > 0) { Member("decorators", in accessorProperty.Decorators); } } return accessorProperty; } protected internal override object? VisitArrayExpression(ArrayExpression arrayExpression) { using (StartNodeObject(arrayExpression)) { Member("elements", in arrayExpression.Elements); return arrayExpression; } } protected internal override object? VisitArrayPattern(ArrayPattern arrayPattern) { using (StartNodeObject(arrayPattern)) { Member("elements", in arrayPattern.Elements); return arrayPattern; } } protected internal override object? VisitArrowFunctionExpression(ArrowFunctionExpression arrowFunctionExpression) { using (StartNodeObject(arrowFunctionExpression)) { Member("id", (Node?)((IFunction)arrowFunctionExpression).Id); Member("params", in arrowFunctionExpression.Params); Member("body", (Node?)arrowFunctionExpression.Body); Member("generator", ((IFunction)arrowFunctionExpression).Generator); Member("expression", arrowFunctionExpression.Expression); if (_testCompatibilityMode != AstToJsonTestCompatibilityMode.EsprimaOrg) { Member("strict", arrowFunctionExpression.Strict); } Member("async", arrowFunctionExpression.Async); return arrowFunctionExpression; } } protected internal override object? VisitAssignmentExpression(AssignmentExpression assignmentExpression) { using (StartNodeObject(assignmentExpression)) { Member("operator", AssignmentExpression.GetAssignmentOperatorToken(assignmentExpression.Operator)); Member("left", assignmentExpression.Left); Member("right", (Node?)assignmentExpression.Right); return assignmentExpression; } } protected internal override object? VisitAssignmentPattern(AssignmentPattern assignmentPattern) { using (StartNodeObject(assignmentPattern)) { Member("left", assignmentPattern.Left); Member("right", (Node?)assignmentPattern.Right); return assignmentPattern; } } protected internal override object? VisitAwaitExpression(AwaitExpression awaitExpression) { using (StartNodeObject(awaitExpression)) { Member("argument", (Node?)awaitExpression.Argument); return awaitExpression; } } protected internal override object? VisitBinaryExpression(BinaryExpression binaryExpression) { using (StartNodeObject(binaryExpression)) { Member("operator", BinaryExpression.GetBinaryOperatorToken(binaryExpression.Operator)); Member("left", (Node?)binaryExpression.Left); Member("right", (Node?)binaryExpression.Right); return binaryExpression; } } protected internal override object? VisitBlockStatement(BlockStatement blockStatement) { using (StartNodeObject(blockStatement)) { Member("body", in blockStatement.Body, (Statement e) => e); return blockStatement; } } protected internal override object? VisitBreakStatement(BreakStatement breakStatement) { using (StartNodeObject(breakStatement)) { Member("label", (Node?)breakStatement.Label); return breakStatement; } } protected internal override object? VisitCallExpression(CallExpression callExpression) { using (StartNodeObject(callExpression)) { Member("callee", (Node?)callExpression.Callee); Member("arguments", in callExpression.Arguments, (Expression e) => e); Member("optional", callExpression.Optional); return callExpression; } } protected internal override object? VisitCatchClause(CatchClause catchClause) { using (StartNodeObject(catchClause)) { Member("param", catchClause.Param); Member("body", (Node?)catchClause.Body); return catchClause; } } protected internal override object? VisitChainExpression(ChainExpression chainExpression) { using (StartNodeObject(chainExpression)) { Member("expression", (Node?)chainExpression.Expression); return chainExpression; } } protected internal override object? VisitClassBody(ClassBody classBody) { using (StartNodeObject(classBody)) { Member("body", in classBody.Body); return classBody; } } protected internal override object? VisitClassDeclaration(ClassDeclaration classDeclaration) { using (StartNodeObject(classDeclaration)) { Member("id", (Node?)classDeclaration.Id); Member("superClass", (Node?)classDeclaration.SuperClass); Member("body", (Node?)classDeclaration.Body); if (classDeclaration.Decorators.Count > 0) { Member("decorators", in classDeclaration.Decorators); } } return classDeclaration; } protected internal override object? VisitClassExpression(ClassExpression classExpression) { using (StartNodeObject(classExpression)) { Member("id", (Node?)classExpression.Id); Member("superClass", (Node?)classExpression.SuperClass); Member("body", (Node?)classExpression.Body); if (classExpression.Decorators.Count > 0) { Member("decorators", in classExpression.Decorators); } } return classExpression; } protected internal override object? VisitConditionalExpression(ConditionalExpression conditionalExpression) { using (StartNodeObject(conditionalExpression)) { Member("test", (Node?)conditionalExpression.Test); Member("consequent", (Node?)conditionalExpression.Consequent); Member("alternate", (Node?)conditionalExpression.Alternate); return conditionalExpression; } } protected internal override object? VisitContinueStatement(ContinueStatement continueStatement) { using (StartNodeObject(continueStatement)) { Member("label", (Node?)continueStatement.Label); return continueStatement; } } protected internal override object? VisitDebuggerStatement(DebuggerStatement debuggerStatement) { EmptyNodeObject(debuggerStatement); return debuggerStatement; } protected internal override object? VisitDecorator(Decorator decorator) { using (StartNodeObject(decorator)) { Member("expression", (Node?)decorator.Expression); return decorator; } } protected internal override object? VisitDoWhileStatement(DoWhileStatement doWhileStatement) { using (StartNodeObject(doWhileStatement)) { Member("body", (Node?)doWhileStatement.Body); Member("test", (Node?)doWhileStatement.Test); return doWhileStatement; } } protected internal override object? VisitEmptyStatement(EmptyStatement emptyStatement) { EmptyNodeObject(emptyStatement); return emptyStatement; } protected internal override object? VisitExportAllDeclaration(ExportAllDeclaration exportAllDeclaration) { using (StartNodeObject(exportAllDeclaration)) { Member("source", (Node?)exportAllDeclaration.Source); if (_testCompatibilityMode != AstToJsonTestCompatibilityMode.EsprimaOrg) { Member("exported", (Node?)exportAllDeclaration.Exported); if (exportAllDeclaration.Attributes.Count > 0) { Member("attributes", in exportAllDeclaration.Attributes); } } } return exportAllDeclaration; } protected internal override object? VisitExportDefaultDeclaration(ExportDefaultDeclaration exportDefaultDeclaration) { using (StartNodeObject(exportDefaultDeclaration)) { Member("declaration", (Node?)exportDefaultDeclaration.Declaration); return exportDefaultDeclaration; } } protected internal override object? VisitExportNamedDeclaration(ExportNamedDeclaration exportNamedDeclaration) { using (StartNodeObject(exportNamedDeclaration)) { Member("declaration", (Node?)exportNamedDeclaration.Declaration); Member("specifiers", in exportNamedDeclaration.Specifiers); Member("source", (Node?)exportNamedDeclaration.Source); if (_testCompatibilityMode != AstToJsonTestCompatibilityMode.EsprimaOrg && exportNamedDeclaration.Attributes.Count > 0) { Member("attributes", in exportNamedDeclaration.Attributes); } } return exportNamedDeclaration; } protected internal override object? VisitExportSpecifier(ExportSpecifier exportSpecifier) { using (StartNodeObject(exportSpecifier)) { Member("exported", (Node?)exportSpecifier.Exported); Member("local", (Node?)exportSpecifier.Local); return exportSpecifier; } } protected internal override object? VisitExpressionStatement(ExpressionStatement expressionStatement) { using (StartNodeObject(expressionStatement)) { if (expressionStatement is Directive directive) { Member("directive", directive.Value); } Member("expression", (Node?)expressionStatement.Expression); return expressionStatement; } } protected internal override object? VisitForInStatement(ForInStatement forInStatement) { using (StartNodeObject(forInStatement)) { Member("left", forInStatement.Left); Member("right", (Node?)forInStatement.Right); Member("body", (Node?)forInStatement.Body); Member("each", value: false); return forInStatement; } } protected internal override object? VisitForOfStatement(ForOfStatement forOfStatement) { using (StartNodeObject(forOfStatement)) { Member("await", forOfStatement.Await); Member("left", forOfStatement.Left); Member("right", (Node?)forOfStatement.Right); Member("body", (Node?)forOfStatement.Body); return forOfStatement; } } protected internal override object? VisitForStatement(ForStatement forStatement) { using (StartNodeObject(forStatement)) { Member("init", (Node?)forStatement.Init); Member("test", (Node?)forStatement.Test); Member("update", (Node?)forStatement.Update); Member("body", (Node?)forStatement.Body); return forStatement; } } protected internal override object? VisitFunctionDeclaration(FunctionDeclaration functionDeclaration) { using (StartNodeObject(functionDeclaration)) { Member("id", (Node?)functionDeclaration.Id); Member("params", in functionDeclaration.Params); Member("body", (Node?)functionDeclaration.Body); Member("generator", functionDeclaration.Generator); Member("expression", ((IFunction)functionDeclaration).Expression); if (_testCompatibilityMode != AstToJsonTestCompatibilityMode.EsprimaOrg) { Member("strict", functionDeclaration.Strict); } Member("async", functionDeclaration.Async); return functionDeclaration; } } protected internal override object? VisitFunctionExpression(FunctionExpression functionExpression) { using (StartNodeObject(functionExpression)) { Member("id", (Node?)functionExpression.Id); Member("params", in functionExpression.Params); Member("body", (Node?)functionExpression.Body); Member("generator", functionExpression.Generator); Member("expression", ((IFunction)functionExpression).Expression); if (_testCompatibilityMode != AstToJsonTestCompatibilityMode.EsprimaOrg) { Member("strict", functionExpression.Strict); } Member("async", functionExpression.Async); return functionExpression; } } protected internal override object? VisitIdentifier(Identifier identifier) { using (StartNodeObject(identifier)) { Member("name", identifier.Name); return identifier; } } protected internal override object? VisitIfStatement(IfStatement ifStatement) { using (StartNodeObject(ifStatement)) { Member("test", (Node?)ifStatement.Test); Member("consequent", (Node?)ifStatement.Consequent); Member("alternate", (Node?)ifStatement.Alternate); return ifStatement; } } protected internal override object? VisitImportAttribute(ImportAttribute importAttribute) { using (StartNodeObject(importAttribute)) { Member("key", (Node?)importAttribute.Key); Member("value", (Node?)importAttribute.Value); return importAttribute; } } private ImportCompat VisitImportCompat(ImportCompat import) { OnStartSyntaxElementObject(import); Member("type", "Import"); using (new NodeObjectDisposable(this, import)) { return import; } } protected internal override object? VisitImportDeclaration(ImportDeclaration importDeclaration) { using (StartNodeObject(importDeclaration)) { Member("specifiers", in importDeclaration.Specifiers, (ImportDeclarationSpecifier e) => e); Member("source", (Node?)importDeclaration.Source); if (_testCompatibilityMode != AstToJsonTestCompatibilityMode.EsprimaOrg && importDeclaration.Attributes.Count > 0) { Member("attributes", in importDeclaration.Attributes); } } return importDeclaration; } protected internal override object? VisitImportDefaultSpecifier(ImportDefaultSpecifier importDefaultSpecifier) { using (StartNodeObject(importDefaultSpecifier)) { Member("local", (Node?)importDefaultSpecifier.Local); return importDefaultSpecifier; } } protected internal override object? VisitImportExpression(ImportExpression importExpression) { if (_testCompatibilityMode == AstToJsonTestCompatibilityMode.EsprimaOrg) { ImportCompat callee = new ImportCompat { Location = new Location(importExpression.Location.Start, new Position(importExpression.Location.Start.Line, importExpression.Location.Start.Column + "import".Length)), Range = new Range(importExpression.Range.Start, importExpression.Range.Start + "import".Length) }; NodeList args = new NodeList(new Expression[1] { importExpression.Source }, 1); CallExpression node = new CallExpression(callee, in args, optional: false) { Location = importExpression.Location, Range = importExpression.Range }; return Visit(node); } using (StartNodeObject(importExpression)) { if (_testCompatibilityMode != AstToJsonTestCompatibilityMode.EsprimaOrg) { Member("source", (Node?)importExpression.Source); if (importExpression.Options != null) { Member("options", (Node?)importExpression.Options); } } } return importExpression; } protected internal override object? VisitImportNamespaceSpecifier(ImportNamespaceSpecifier importNamespaceSpecifier) { using (StartNodeObject(importNamespaceSpecifier)) { Member("local", (Node?)importNamespaceSpecifier.Local); return importNamespaceSpecifier; } } protected internal override object? VisitImportSpecifier(ImportSpecifier importSpecifier) { using (StartNodeObject(importSpecifier)) { Member("local", (Node?)importSpecifier.Local); Member("imported", (Node?)importSpecifier.Imported); return importSpecifier; } } protected internal override object? VisitLabeledStatement(LabeledStatement labeledStatement) { using (StartNodeObject(labeledStatement)) { Member("label", (Node?)labeledStatement.Label); Member("body", (Node?)labeledStatement.Body); return labeledStatement; } } protected internal override object? VisitLiteral(Literal literal) { using (StartNodeObject(literal)) { _writer.Member("value"); switch (literal.TokenType) { case TokenType.RegularExpression: if (literal.Value != null) { _writer.StartObject(); _writer.EndObject(); break; } goto case TokenType.NullLiteral; case TokenType.NullLiteral: _writer.Null(); break; case TokenType.BooleanLiteral: _writer.Boolean((bool)literal.Value); break; case TokenType.NumericLiteral: { double num = (double)literal.Value; if (!double.IsPositiveInfinity(num)) { _writer.Number(num); break; } goto default; } default: _writer.String(System.Convert.ToString(literal.Value, CultureInfo.InvariantCulture)); break; } Member("raw", literal.Raw); if (literal is RegExpLiteral regExpLiteral) { _writer.Member("regex"); WriteRegexValue(regExpLiteral.Regex); } else if (literal.Value is BigInteger bigInteger) { Member("bigint", bigInteger.ToString(CultureInfo.InvariantCulture)); } } return literal; } protected internal override object? VisitMemberExpression(MemberExpression memberExpression) { using (StartNodeObject(memberExpression)) { Member("computed", memberExpression.Computed); Member("object", (Node?)memberExpression.Object); Member("property", (Node?)memberExpression.Property); Member("optional", memberExpression.Optional); return memberExpression; } } protected internal override object? VisitMetaProperty(MetaProperty metaProperty) { using (StartNodeObject(metaProperty)) { Member("meta", (Node?)metaProperty.Meta); Member("property", (Node?)metaProperty.Property); return metaProperty; } } protected internal override object? VisitMethodDefinition(MethodDefinition methodDefinition) { using (StartNodeObject(methodDefinition)) { Member("key", (Node?)methodDefinition.Key); Member("computed", methodDefinition.Computed); Member("value", (Node?)methodDefinition.Value); Member("kind", methodDefinition.Kind); Member("static", methodDefinition.Static); if (methodDefinition.Decorators.Count > 0) { Member("decorators", in methodDefinition.Decorators); } } return methodDefinition; } protected internal override object? VisitNewExpression(NewExpression newExpression) { using (StartNodeObject(newExpression)) { Member("callee", (Node?)newExpression.Callee); Member("arguments", in newExpression.Arguments, (Expression e) => e); return newExpression; } } protected internal override object? VisitObjectExpression(ObjectExpression objectExpression) { using (StartNodeObject(objectExpression)) { Member("properties", in objectExpression.Properties); return objectExpression; } } protected internal override object? VisitObjectPattern(ObjectPattern objectPattern) { using (StartNodeObject(objectPattern)) { Member("properties", in objectPattern.Properties); return objectPattern; } } protected internal override object? VisitPrivateIdentifier(PrivateIdentifier privateIdentifier) { using (StartNodeObject(privateIdentifier)) { Member("name", privateIdentifier.Name); return privateIdentifier; } } protected internal override object? VisitProgram(Program program) { using (StartNodeObject(program)) { Member("body", in program.Body, (Statement e) => e); Member("sourceType", program.SourceType); if (_testCompatibilityMode != AstToJsonTestCompatibilityMode.EsprimaOrg && program is Script script) { Member("strict", script.Strict); } } return program; } protected internal override object? VisitProperty(Property property) { using (StartNodeObject(property)) { Member("key", (Node?)property.Key); Member("computed", property.Computed); Member("value", property.Value); Member("kind", property.Kind); Member("method", property.Method); Member("shorthand", property.Shorthand); return property; } } protected internal override object? VisitPropertyDefinition(PropertyDefinition propertyDefinition) { using (StartNodeObject(propertyDefinition)) { Member("key", (Node?)propertyDefinition.Key); Member("computed", propertyDefinition.Computed); Member("value", (Node?)propertyDefinition.Value); Member("kind", propertyDefinition.Kind); Member("static", propertyDefinition.Static); if (propertyDefinition.Decorators.Count > 0) { Member("decorators", in propertyDefinition.Decorators); } } return propertyDefinition; } protected internal override object? VisitRestElement(RestElement restElement) { using (StartNodeObject(restElement)) { Member("argument", restElement.Argument); return restElement; } } protected internal override object? VisitReturnStatement(ReturnStatement returnStatement) { using (StartNodeObject(returnStatement)) { Member("argument", (Node?)returnStatement.Argument); return returnStatement; } } protected internal override object? VisitSequenceExpression(SequenceExpression sequenceExpression) { using (StartNodeObject(sequenceExpression)) { Member("expressions", in sequenceExpression.Expressions); return sequenceExpression; } } protected internal override object? VisitSpreadElement(SpreadElement spreadElement) { using (StartNodeObject(spreadElement)) { Member("argument", (Node?)spreadElement.Argument); return spreadElement; } } protected internal override object? VisitStaticBlock(StaticBlock staticBlock) { using (StartNodeObject(staticBlock)) { Member("body", in staticBlock.Body, (Statement e) => e); return staticBlock; } } protected internal override object? VisitSuper(Super super) { EmptyNodeObject(super); return super; } protected internal override object? VisitSwitchCase(SwitchCase switchCase) { using (StartNodeObject(switchCase)) { Member("test", (Node?)switchCase.Test); Member("consequent", in switchCase.Consequent, (Statement e) => e); return switchCase; } } protected internal override object? VisitSwitchStatement(SwitchStatement switchStatement) { using (StartNodeObject(switchStatement)) { Member("discriminant", (Node?)switchStatement.Discriminant); Member("cases", in switchStatement.Cases); return switchStatement; } } protected internal override object? VisitTaggedTemplateExpression(TaggedTemplateExpression taggedTemplateExpression) { using (StartNodeObject(taggedTemplateExpression)) { Member("tag", (Node?)taggedTemplateExpression.Tag); Member("quasi", (Node?)taggedTemplateExpression.Quasi); return taggedTemplateExpression; } } protected internal override object? VisitTemplateElement(TemplateElement templateElement) { using (StartNodeObject(templateElement)) { _writer.Member("value"); _writer.StartObject(); Member("raw", templateElement.Value.Raw); Member("cooked", templateElement.Value.Cooked); _writer.EndObject(); Member("tail", templateElement.Tail); return templateElement; } } protected internal override object? VisitTemplateLiteral(TemplateLiteral templateLiteral) { using (StartNodeObject(templateLiteral)) { Member("quasis", in templateLiteral.Quasis); Member("expressions", in templateLiteral.Expressions); return templateLiteral; } } protected internal override object? VisitThisExpression(ThisExpression thisExpression) { EmptyNodeObject(thisExpression); return thisExpression; } protected internal override object? VisitThrowStatement(ThrowStatement throwStatement) { using (StartNodeObject(throwStatement)) { Member("argument", (Node?)throwStatement.Argument); return throwStatement; } } protected internal override object? VisitTryStatement(TryStatement tryStatement) { using (StartNodeObject(tryStatement)) { Member("block", (Node?)tryStatement.Block); Member("handler", (Node?)tryStatement.Handler); Member("finalizer", (Node?)tryStatement.Finalizer); return tryStatement; } } protected internal override object? VisitUnaryExpression(UnaryExpression unaryExpression) { using (StartNodeObject(unaryExpression)) { Member("operator", UnaryExpression.GetUnaryOperatorToken(unaryExpression.Operator)); Member("argument", (Node?)unaryExpression.Argument); Member("prefix", unaryExpression.Prefix); return unaryExpression; } } protected internal override object? VisitVariableDeclaration(VariableDeclaration variableDeclaration) { using (StartNodeObject(variableDeclaration)) { Member("declarations", in variableDeclaration.Declarations); Member("kind", variableDeclaration.Kind); return variableDeclaration; } } protected internal override object? VisitVariableDeclarator(VariableDeclarator variableDeclarator) { using (StartNodeObject(variableDeclarator)) { Member("id", variableDeclarator.Id); Member("init", (Node?)variableDeclarator.Init); return variableDeclarator; } } protected internal override object? VisitWhileStatement(WhileStatement whileStatement) { using (StartNodeObject(whileStatement)) { Member("test", (Node?)whileStatement.Test); Member("body", (Node?)whileStatement.Body); return whileStatement; } } protected internal override object? VisitWithStatement(WithStatement withStatement) { using (StartNodeObject(withStatement)) { Member("object", (Node?)withStatement.Object); Member("body", (Node?)withStatement.Body); return withStatement; } } protected internal override object? VisitYieldExpression(YieldExpression yieldExpression) { using (StartNodeObject(yieldExpression)) { Member("argument", (Node?)yieldExpression.Argument); Member("delegate", yieldExpression.Delegate); return yieldExpression; } } } [AutoGeneratedAstVisitor] public class AstVisitor { private static NotImplementedException UnsupportedNodeType(Type nodeType, [CallerMemberName] string? callerName = null) { return new NotImplementedException($"The visitor does not support nodes of type {nodeType}. You can override {callerName} to handle this case."); } public virtual object? Visit(Node node) { return node.Accept(this); } protected internal virtual object? VisitExportSpecifier(ExportSpecifier exportSpecifier) { Visit(exportSpecifier.Local); if (exportSpecifier.Exported != exportSpecifier.Local) { Visit(exportSpecifier.Exported); } return exportSpecifier; } protected internal virtual object? VisitExtension(Node node) { throw UnsupportedNodeType(node.GetType(), "VisitExtension"); } protected internal virtual object? VisitImportSpecifier(ImportSpecifier importSpecifier) { if (importSpecifier.Imported != importSpecifier.Local) { Visit(importSpecifier.Imported); } Visit(importSpecifier.Local); return importSpecifier; } protected internal virtual object? VisitProperty(Property property) { if (!property.Shorthand) { Visit(property.Key); } Visit(property.Value); return property; } protected internal virtual object? VisitTemplateLiteral(TemplateLiteral templateLiteral) { ref readonly NodeList quasis = ref templateLiteral.Quasis; ref readonly NodeList expressions = ref templateLiteral.Expressions; int num = 0; TemplateElement node; while (!(node = quasis[num]).Tail) { Visit(node); Visit(expressions[num]); num++; } Visit(node); return templateLiteral; } protected internal virtual object? VisitAccessorProperty(AccessorProperty accessorProperty) { ref readonly NodeList decorators = ref accessorProperty.Decorators; for (int i = 0; i < decorators.Count; i++) { Visit(decorators[i]); } Visit(accessorProperty.Key); if (accessorProperty.Value != null) { Visit(accessorProperty.Value); } return accessorProperty; } protected internal virtual object? VisitArrayExpression(ArrayExpression arrayExpression) { ref readonly NodeList elements = ref arrayExpression.Elements; for (int i = 0; i < elements.Count; i++) { Expression expression = elements[i]; if (expression != null) { Visit(expression); } } return arrayExpression; } protected internal virtual object? VisitArrayPattern(ArrayPattern arrayPattern) { ref readonly NodeList elements = ref arrayPattern.Elements; for (int i = 0; i < elements.Count; i++) { Node node = elements[i]; if (node != null) { Visit(node); } } return arrayPattern; } protected internal virtual object? VisitArrowFunctionExpression(ArrowFunctionExpression arrowFunctionExpression) { ref readonly NodeList reference = ref arrowFunctionExpression.Params; for (int i = 0; i < reference.Count; i++) { Visit(reference[i]); } Visit(arrowFunctionExpression.Body); return arrowFunctionExpression; } protected internal virtual object? VisitAssignmentExpression(AssignmentExpression assignmentExpression) { Visit(assignmentExpression.Left); Visit(assignmentExpression.Right); return assignmentExpression; } protected internal virtual object? VisitAssignmentPattern(AssignmentPattern assignmentPattern) { Visit(assignmentPattern.Left); Visit(assignmentPattern.Right); return assignmentPattern; } protected internal virtual object? VisitAwaitExpression(AwaitExpression awaitExpression) { Visit(awaitExpression.Argument); return awaitExpression; } protected internal virtual object? VisitBinaryExpression(BinaryExpression binaryExpression) { Visit(binaryExpression.Left); Visit(binaryExpression.Right); return binaryExpression; } protected internal virtual object? VisitBlockStatement(BlockStatement blockStatement) { ref readonly NodeList body = ref blockStatement.Body; for (int i = 0; i < body.Count; i++) { Visit(body[i]); } return blockStatement; } protected internal virtual object? VisitBreakStatement(BreakStatement breakStatement) { if (breakStatement.Label != null) { Visit(breakStatement.Label); } return breakStatement; } protected internal virtual object? VisitCallExpression(CallExpression callExpression) { Visit(callExpression.Callee); ref readonly NodeList arguments = ref callExpression.Arguments; for (int i = 0; i < arguments.Count; i++) { Visit(arguments[i]); } return callExpression; } protected internal virtual object? VisitCatchClause(CatchClause catchClause) { if (catchClause.Param != null) { Visit(catchClause.Param); } Visit(catchClause.Body); return catchClause; } protected internal virtual object? VisitChainExpression(ChainExpression chainExpression) { Visit(chainExpression.Expression); return chainExpression; } protected internal virtual object? VisitClassBody(ClassBody classBody) { ref readonly NodeList body = ref classBody.Body; for (int i = 0; i < body.Count; i++) { Visit(body[i]); } return classBody; } protected internal virtual object? VisitClassDeclaration(ClassDeclaration classDeclaration) { ref readonly NodeList decorators = ref classDeclaration.Decorators; for (int i = 0; i < decorators.Count; i++) { Visit(decorators[i]); } if (classDeclaration.Id != null) { Visit(classDeclaration.Id); } if (classDeclaration.SuperClass != null) { Visit(classDeclaration.SuperClass); } Visit(classDeclaration.Body); return classDeclaration; } protected internal virtual object? VisitClassExpression(ClassExpression classExpression) { ref readonly NodeList decorators = ref classExpression.Decorators; for (int i = 0; i < decorators.Count; i++) { Visit(decorators[i]); } if (classExpression.Id != null) { Visit(classExpression.Id); } if (classExpression.SuperClass != null) { Visit(classExpression.SuperClass); } Visit(classExpression.Body); return classExpression; } protected internal virtual object? VisitConditionalExpression(ConditionalExpression conditionalExpression) { Visit(conditionalExpression.Test); Visit(conditionalExpression.Consequent); Visit(conditionalExpression.Alternate); return conditionalExpression; } protected internal virtual object? VisitContinueStatement(ContinueStatement continueStatement) { if (continueStatement.Label != null) { Visit(continueStatement.Label); } return continueStatement; } protected internal virtual object? VisitDebuggerStatement(DebuggerStatement debuggerStatement) { return debuggerStatement; } protected internal virtual object? VisitDecorator(Decorator decorator) { Visit(decorator.Expression); return decorator; } protected internal virtual object? VisitDoWhileStatement(DoWhileStatement doWhileStatement) { Visit(doWhileStatement.Body); Visit(doWhileStatement.Test); return doWhileStatement; } protected internal virtual object? VisitEmptyStatement(EmptyStatement emptyStatement) { return emptyStatement; } protected internal virtual object? VisitExportAllDeclaration(ExportAllDeclaration exportAllDeclaration) { if (exportAllDeclaration.Exported != null) { Visit(exportAllDeclaration.Exported); } Visit(exportAllDeclaration.Source); ref readonly NodeList attributes = ref exportAllDeclaration.Attributes; for (int i = 0; i < attributes.Count; i++) { Visit(attributes[i]); } return exportAllDeclaration; } protected internal virtual object? VisitExportDefaultDeclaration(ExportDefaultDeclaration exportDefaultDeclaration) { Visit(exportDefaultDeclaration.Declaration); return exportDefaultDeclaration; } protected internal virtual object? VisitExportNamedDeclaration(ExportNamedDeclaration exportNamedDeclaration) { if (exportNamedDeclaration.Declaration != null) { Visit(exportNamedDeclaration.Declaration); } ref readonly NodeList specifiers = ref exportNamedDeclaration.Specifiers; for (int i = 0; i < specifiers.Count; i++) { Visit(specifiers[i]); } if (exportNamedDeclaration.Source != null) { Visit(exportNamedDeclaration.Source); } ref readonly NodeList attributes = ref exportNamedDeclaration.Attributes; for (int j = 0; j < attributes.Count; j++) { Visit(attributes[j]); } return exportNamedDeclaration; } protected internal virtual object? VisitExpressionStatement(ExpressionStatement expressionStatement) { Visit(expressionStatement.Expression); return expressionStatement; } protected internal virtual object? VisitForInStatement(ForInStatement forInStatement) { Visit(forInStatement.Left); Visit(forInStatement.Right); Visit(forInStatement.Body); return forInStatement; } protected internal virtual object? VisitForOfStatement(ForOfStatement forOfStatement) { Visit(forOfStatement.Left); Visit(forOfStatement.Right); Visit(forOfStatement.Body); return forOfStatement; } protected internal virtual object? VisitForStatement(ForStatement forStatement) { if (forStatement.Init != null) { Visit(forStatement.Init); } if (forStatement.Test != null) { Visit(forStatement.Test); } if (forStatement.Update != null) { Visit(forStatement.Update); } Visit(forStatement.Body); return forStatement; } protected internal virtual object? VisitFunctionDeclaration(FunctionDeclaration functionDeclaration) { if (functionDeclaration.Id != null) { Visit(functionDeclaration.Id); } ref readonly NodeList reference = ref functionDeclaration.Params; for (int i = 0; i < reference.Count; i++) { Visit(reference[i]); } Visit(functionDeclaration.Body); return functionDeclaration; } protected internal virtual object? VisitFunctionExpression(FunctionExpression functionExpression) { if (functionExpression.Id != null) { Visit(functionExpression.Id); } ref readonly NodeList reference = ref functionExpression.Params; for (int i = 0; i < reference.Count; i++) { Visit(reference[i]); } Visit(functionExpression.Body); return functionExpression; } protected internal virtual object? VisitIdentifier(Identifier identifier) { return identifier; } protected internal virtual object? VisitIfStatement(IfStatement ifStatement) { Visit(ifStatement.Test); Visit(ifStatement.Consequent); if (ifStatement.Alternate != null) { Visit(ifStatement.Alternate); } return ifStatement; } protected internal virtual object? VisitImportAttribute(ImportAttribute importAttribute) { Visit(importAttribute.Key); Visit(importAttribute.Value); return importAttribute; } protected internal virtual object? VisitImportDeclaration(ImportDeclaration importDeclaration) { ref readonly NodeList specifiers = ref importDeclaration.Specifiers; for (int i = 0; i < specifiers.Count; i++) { Visit(specifiers[i]); } Visit(importDeclaration.Source); ref readonly NodeList attributes = ref importDeclaration.Attributes; for (int j = 0; j < attributes.Count; j++) { Visit(attributes[j]); } return importDeclaration; } protected internal virtual object? VisitImportDefaultSpecifier(ImportDefaultSpecifier importDefaultSpecifier) { Visit(importDefaultSpecifier.Local); return importDefaultSpecifier; } protected internal virtual object? VisitImportExpression(ImportExpression importExpression) { Visit(importExpression.Source); if (importExpression.Options != null) { Visit(importExpression.Options); } return importExpression; } protected internal virtual object? VisitImportNamespaceSpecifier(ImportNamespaceSpecifier importNamespaceSpecifier) { Visit(importNamespaceSpecifier.Local); return importNamespaceSpecifier; } protected internal virtual object? VisitLabeledStatement(LabeledStatement labeledStatement) { Visit(labeledStatement.Label); Visit(labeledStatement.Body); return labeledStatement; } protected internal virtual object? VisitLiteral(Literal literal) { return literal; } protected internal virtual object? VisitMemberExpression(MemberExpression memberExpression) { Visit(memberExpression.Object); Visit(memberExpression.Property); return memberExpression; } protected internal virtual object? VisitMetaProperty(MetaProperty metaProperty) { Visit(metaProperty.Meta); Visit(metaProperty.Property); return metaProperty; } protected internal virtual object? VisitMethodDefinition(MethodDefinition methodDefinition) { ref readonly NodeList decorators = ref methodDefinition.Decorators; for (int i = 0; i < decorators.Count; i++) { Visit(decorators[i]); } Visit(methodDefinition.Key); Visit(methodDefinition.Value); return methodDefinition; } protected internal virtual object? VisitNewExpression(NewExpression newExpression) { Visit(newExpression.Callee); ref readonly NodeList arguments = ref newExpression.Arguments; for (int i = 0; i < arguments.Count; i++) { Visit(arguments[i]); } return newExpression; } protected internal virtual object? VisitObjectExpression(ObjectExpression objectExpression) { ref readonly NodeList properties = ref objectExpression.Properties; for (int i = 0; i < properties.Count; i++) { Visit(properties[i]); } return objectExpression; } protected internal virtual object? VisitObjectPattern(ObjectPattern objectPattern) { ref readonly NodeList properties = ref objectPattern.Properties; for (int i = 0; i < properties.Count; i++) { Visit(properties[i]); } return objectPattern; } protected internal virtual object? VisitPrivateIdentifier(PrivateIdentifier privateIdentifier) { return privateIdentifier; } protected internal virtual object? VisitProgram(Program program) { ref readonly NodeList body = ref program.Body; for (int i = 0; i < body.Count; i++) { Visit(body[i]); } return program; } protected internal virtual object? VisitPropertyDefinition(PropertyDefinition propertyDefinition) { ref readonly NodeList decorators = ref propertyDefinition.Decorators; for (int i = 0; i < decorators.Count; i++) { Visit(decorators[i]); } Visit(propertyDefinition.Key); if (propertyDefinition.Value != null) { Visit(propertyDefinition.Value); } return propertyDefinition; } protected internal virtual object? VisitRestElement(RestElement restElement) { Visit(restElement.Argument); return restElement; } protected internal virtual object? VisitReturnStatement(ReturnStatement returnStatement) { if (returnStatement.Argument != null) { Visit(returnStatement.Argument); } return returnStatement; } protected internal virtual object? VisitSequenceExpression(SequenceExpression sequenceExpression) { ref readonly NodeList expressions = ref sequenceExpression.Expressions; for (int i = 0; i < expressions.Count; i++) { Visit(expressions[i]); } return sequenceExpression; } protected internal virtual object? VisitSpreadElement(SpreadElement spreadElement) { Visit(spreadElement.Argument); return spreadElement; } protected internal virtual object? VisitStaticBlock(StaticBlock staticBlock) { ref readonly NodeList body = ref staticBlock.Body; for (int i = 0; i < body.Count; i++) { Visit(body[i]); } return staticBlock; } protected internal virtual object? VisitSuper(Super super) { return super; } protected internal virtual object? VisitSwitchCase(SwitchCase switchCase) { if (switchCase.Test != null) { Visit(switchCase.Test); } ref readonly NodeList consequent = ref switchCase.Consequent; for (int i = 0; i < consequent.Count; i++) { Visit(consequent[i]); } return switchCase; } protected internal virtual object? VisitSwitchStatement(SwitchStatement switchStatement) { Visit(switchStatement.Discriminant); ref readonly NodeList cases = ref switchStatement.Cases; for (int i = 0; i < cases.Count; i++) { Visit(cases[i]); } return switchStatement; } protected internal virtual object? VisitTaggedTemplateExpression(TaggedTemplateExpression taggedTemplateExpression) { Visit(taggedTemplateExpression.Tag); Visit(taggedTemplateExpression.Quasi); return taggedTemplateExpression; } protected internal virtual object? VisitTemplateElement(TemplateElement templateElement) { return templateElement; } protected internal virtual object? VisitThisExpression(ThisExpression thisExpression) { return thisExpression; } protected internal virtual object? VisitThrowStatement(ThrowStatement throwStatement) { Visit(throwStatement.Argument); return throwStatement; } protected internal virtual object? VisitTryStatement(TryStatement tryStatement) { Visit(tryStatement.Block); if (tryStatement.Handler != null) { Visit(tryStatement.Handler); } if (tryStatement.Finalizer != null) { Visit(tryStatement.Finalizer); } return tryStatement; } protected internal virtual object? VisitUnaryExpression(UnaryExpression unaryExpression) { Visit(unaryExpression.Argument); return unaryExpression; } protected internal virtual object? VisitVariableDeclaration(VariableDeclaration variableDeclaration) { ref readonly NodeList declarations = ref variableDeclaration.Declarations; for (int i = 0; i < declarations.Count; i++) { Visit(declarations[i]); } return variableDeclaration; } protected internal virtual object? VisitVariableDeclarator(VariableDeclarator variableDeclarator) { Visit(variableDeclarator.Id); if (variableDeclarator.Init != null) { Visit(variableDeclarator.Init); } return variableDeclarator; } protected internal virtual object? VisitWhileStatement(WhileStatement whileStatement) { Visit(whileStatement.Test); Visit(whileStatement.Body); return whileStatement; } protected internal virtual object? VisitWithStatement(WithStatement withStatement) { Visit(withStatement.Object); Visit(withStatement.Body); return withStatement; } protected internal virtual object? VisitYieldExpression(YieldExpression yieldExpression) { if (yieldExpression.Argument != null) { Visit(yieldExpression.Argument); } return yieldExpression; } } internal static class EnumHelper { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TEnum ToFlag(this bool value, TEnum flag) where TEnum : struct, Enum { return value.ToFlag(flag, default(TEnum)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TEnum ToFlag(this bool value, TEnum flag, TEnum fallbackFlag) where TEnum : struct, Enum { if (!value) { return fallbackFlag; } return flag; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool HasFlagFast(this AstToJavaScriptConverter.BinaryOperationFlags flags, AstToJavaScriptConverter.BinaryOperationFlags flag) { return (flags & flag) == flag; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool HasFlagFast(this AstToJavaScriptConverter.StatementFlags flags, AstToJavaScriptConverter.StatementFlags flag) { return (flags & flag) == flag; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool HasFlagFast(this AstToJavaScriptConverter.ExpressionFlags flags, AstToJavaScriptConverter.ExpressionFlags flag) { return (flags & flag) == flag; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool HasFlagFast(this JavaScriptTextWriter.TriviaType flags, JavaScriptTextWriter.TriviaType flag) { return (flags & flag) == flag; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool HasFlagFast(this JavaScriptTextWriter.TriviaFlags flags, JavaScriptTextWriter.TriviaFlags flag) { return (flags & flag) == flag; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool HasFlagFast(this JavaScriptTextWriter.TokenFlags flags, JavaScriptTextWriter.TokenFlags flag) { return (flags & flag) == flag; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool HasFlagFast(this JavaScriptTextWriter.StatementFlags flags, JavaScriptTextWriter.StatementFlags flag) { return (flags & flag) == flag; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool HasFlagFast(this JavaScriptTextWriter.ExpressionFlags flags, JavaScriptTextWriter.ExpressionFlags flag) { return (flags & flag) == flag; } } internal static class ExpressionHelper { public static int GetOperatorPrecedence(this Expression expression, out int associativity) { associativity = 0; switch (expression.Type) { case Nodes.ArrayExpression: case Nodes.ClassExpression: case Nodes.FunctionExpression: case Nodes.Identifier: case Nodes.Literal: case Nodes.ObjectExpression: case Nodes.PrivateIdentifier: case Nodes.Super: case Nodes.TaggedTemplateExpression: case Nodes.TemplateLiteral: case Nodes.ThisExpression: return int.MaxValue; case Nodes.MemberExpression: if (!expression.As().Computed) { goto case Nodes.MetaProperty; } goto case Nodes.CallExpression; case Nodes.MetaProperty: associativity = -1; goto case Nodes.CallExpression; case Nodes.NewExpression: if (expression.As().Arguments.Count <= 0) { return 1600; } goto case Nodes.CallExpression; case Nodes.CallExpression: case Nodes.ImportExpression: return 1700; case Nodes.ChainExpression: return 1550; case Nodes.UpdateExpression: if (!expression.As().Prefix) { return 1500; } goto case Nodes.AwaitExpression; case Nodes.AwaitExpression: case Nodes.UnaryExpression: return 1400; case Nodes.BinaryExpression: switch (expression.As().Operator) { case BinaryOperator.Exponentiation: associativity = 1; return 1300; case BinaryOperator.Times: case BinaryOperator.Divide: case BinaryOperator.Modulo: associativity = -1; return 1200; case BinaryOperator.Plus: case BinaryOperator.Minus: associativity = -1; return 1100; case BinaryOperator.LeftShift: case BinaryOperator.RightShift: case BinaryOperator.UnsignedRightShift: associativity = -1; return 1000; case BinaryOperator.Greater: case BinaryOperator.GreaterOrEqual: case BinaryOperator.Less: case BinaryOperator.LessOrEqual: case BinaryOperator.InstanceOf: case BinaryOperator.In: associativity = -1; return 900; case BinaryOperator.Equal: case BinaryOperator.NotEqual: case BinaryOperator.StrictlyEqual: case BinaryOperator.StrictlyNotEqual: associativity = -1; return 800; case BinaryOperator.BitwiseAnd: associativity = -1; return 700; case BinaryOperator.BitwiseXor: associativity = -1; return 600; case BinaryOperator.BitwiseOr: associativity = -1; return 500; } break; case Nodes.LogicalExpression: switch (expression.As().Operator) { case BinaryOperator.LogicalAnd: associativity = -1; return 400; case BinaryOperator.LogicalOr: case BinaryOperator.NullishCoalescing: associativity = -1; return 300; } break; case Nodes.AssignmentExpression: case Nodes.ConditionalExpression: associativity = 1; goto case Nodes.ArrowFunctionExpression; case Nodes.ArrowFunctionExpression: case Nodes.SpreadElement: case Nodes.YieldExpression: return 200; case Nodes.SequenceExpression: associativity = -1; return 100; } return -1; } } public abstract record JavaScriptTextFormatterOptions : JavaScriptTextWriterOptions { public string? Indent { get; init; } public bool KeepSingleStatementBodyInLine { get; init; } public bool KeepEmptyBlockBodyInLine { get; init; } public int MultiLineArrayLiteralThreshold { get; init; } = 7; public int MultiLineObjectLiteralThreshold { get; init; } = 3; protected abstract JavaScriptTextFormatter CreateFormatter(TextWriter writer); protected internal sealed override JavaScriptTextWriter CreateWriter(TextWriter writer) { return CreateFormatter(writer); } } public abstract class JavaScriptTextFormatter : JavaScriptTextWriter { private readonly string _indent; private int _indentionLevel; protected bool KeepSingleStatementBodyInLine { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } protected bool KeepEmptyBlockBodyInLine { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } protected int MultiLineArrayLiteralThreshold { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } protected int MultiLineObjectLiteralThreshold { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public JavaScriptTextFormatter(TextWriter writer, JavaScriptTextFormatterOptions options) : base(writer, options) { if (!string.IsNullOrWhiteSpace(options.Indent)) { throw new ArgumentException("Indent must be null or white-space.", "options"); } _indent = options.Indent ?? " "; KeepSingleStatementBodyInLine = options.KeepSingleStatementBodyInLine; KeepEmptyBlockBodyInLine = options.KeepEmptyBlockBodyInLine; MultiLineArrayLiteralThreshold = ((options.MultiLineArrayLiteralThreshold >= 0) ? options.MultiLineArrayLiteralThreshold : int.MaxValue); MultiLineObjectLiteralThreshold = ((options.MultiLineObjectLiteralThreshold >= 0) ? options.MultiLineObjectLiteralThreshold : int.MaxValue); } protected void IncreaseIndent() { _indentionLevel++; } protected void DecreaseIndent() { _indentionLevel--; } protected void WriteIndent() { for (int num = _indentionLevel; num > 0; num--) { WriteWhiteSpace(_indent); } } protected override void WriteLine() { WriteEndOfLine(); WriteIndent(); } protected override void WriteLineCommentCore(TextWriter writer, string line, TriviaFlags flags) { if (!base.LastTriviaType.HasFlag(TriviaType.WhiteSpace)) { WriteSpace(); } base.WriteLineCommentCore(writer, line, flags); } protected override void WriteBlockCommentLine(TextWriter writer, string line, bool isFirst) { if (!isFirst) { for (int num = _indentionLevel; num > 0; num--) { writer.Write(_indent); } } base.WriteBlockCommentLine(writer, line, isFirst); } protected override void WriteBlockCommentCore(TextWriter writer, IEnumerable lines, TriviaFlags flags) { if (!base.LastTriviaType.HasFlag(TriviaType.WhiteSpace)) { WriteSpace(); } base.WriteBlockCommentCore(writer, lines, flags); } protected virtual void WriteWhiteSpaceBetweenTokenAndIdentifier(string value, TokenFlags flags, ref WriteContext context) { if (flags.HasFlagFast(TokenFlags.LeadingSpaceRecommended) || base.LastTokenFlags.HasFlagFast(TokenFlags.TrailingSpaceRecommended)) { WriteSpace(); } else { WriteRequiredSpaceBetweenTokenAndIdentifier(); } } protected override void StartIdentifier(string value, TokenFlags flags, ref WriteContext context) { if (base.LastTriviaType == TriviaType.None) { WriteWhiteSpaceBetweenTokenAndIdentifier(value, flags, ref context); } else if (!base.LastTriviaType.HasFlag(TriviaType.WhiteSpace)) { WriteSpace(); } } protected virtual void WriteWhiteSpaceBetweenTokenAndKeyword(string value, TokenFlags flags, ref WriteContext context) { if (flags.HasFlagFast(TokenFlags.FollowsStatementBody)) { WriteLine(); } else if (flags.HasFlagFast(TokenFlags.LeadingSpaceRecommended) || base.LastTokenFlags.HasFlagFast(TokenFlags.TrailingSpaceRecommended)) { WriteSpace(); } else { WriteRequiredSpaceBetweenTokenAndKeyword(); } } protected override void StartKeyword(string value, TokenFlags flags, ref WriteContext context) { if (base.LastTriviaType == TriviaType.None) { WriteWhiteSpaceBetweenTokenAndKeyword(value, flags, ref context); } else if (!base.LastTriviaType.HasFlag(TriviaType.WhiteSpace)) { WriteSpace(); } } protected virtual void WriteWhiteSpaceBetweenTokenAndLiteral(string value, TokenType type, TokenFlags flags, ref WriteContext context) { if (flags.HasFlagFast(TokenFlags.LeadingSpaceRecommended) || base.LastTokenFlags.HasFlagFast(TokenFlags.TrailingSpaceRecommended)) { WriteSpace(); } else { WriteRequiredSpaceBetweenTokenAndLiteral(type); } } protected override void StartLiteral(string value, TokenType type, TokenFlags flags, ref WriteContext context) { if (base.LastTriviaType == TriviaType.None) { WriteWhiteSpaceBetweenTokenAndLiteral(value, type, flags, ref context); } else if (!base.LastTriviaType.HasFlag(TriviaType.WhiteSpace)) { WriteSpace(); } } protected virtual void WriteWhiteSpaceBetweenTokenAndPunctuator(string value, TokenFlags flags, ref WriteContext context) { if (flags.HasFlagFast(TokenFlags.LeadingSpaceRecommended) || base.LastTokenFlags.HasFlagFast(TokenFlags.TrailingSpaceRecommended)) { WriteSpace(); } else { WriteRequiredSpaceBetweenTokenAndPunctuator(value, flags, ref context); } } protected override void StartPunctuator(string value, TokenFlags flags, ref WriteContext context) { if (base.LastTriviaType == TriviaType.None) { WriteWhiteSpaceBetweenTokenAndPunctuator(value, flags, ref context); } else if (!base.LastTriviaType.HasFlag(TriviaType.WhiteSpace)) { WriteSpace(); } } public override void StartArray(int elementCount, ref WriteContext context) { base.StartArray(elementCount, ref context); if (!CanKeepArrayInLine(elementCount, ref context)) { WriteEndOfLine(); IncreaseIndent(); } } public override void EndArray(int elementCount, ref WriteContext context) { if (!CanKeepArrayInLine(elementCount, ref context)) { DecreaseIndent(); WriteIndent(); } base.EndArray(elementCount, ref context); } protected virtual bool CanKeepArrayInLine(int elementCount, ref WriteContext context) { if (context.Node.Type == Nodes.ArrayExpression) { return elementCount < MultiLineArrayLiteralThreshold; } return true; } public override void StartObject(int propertyCount, ref WriteContext context) { base.StartObject(propertyCount, ref context); if (!CanKeepObjectInLine(propertyCount, ref context)) { WriteEndOfLine(); IncreaseIndent(); } } public override void EndObject(int propertyCount, ref WriteContext context) { if (!CanKeepObjectInLine(propertyCount, ref context)) { DecreaseIndent(); WriteIndent(); } base.EndObject(propertyCount, ref context); } protected virtual bool CanKeepObjectInLine(int propertyCount, ref WriteContext context) { if (context.Node.Type == Nodes.ObjectExpression) { return propertyCount < MultiLineObjectLiteralThreshold; } return true; } public override void StartBlock(int statementCount, ref WriteContext context) { base.StartBlock(statementCount, ref context); if (!CanKeepBlockInLine(statementCount, ref context)) { WriteEndOfLine(); IncreaseIndent(); } } public override void EndBlock(int statementCount, ref WriteContext context) { if (!CanKeepBlockInLine(statementCount, ref context)) { DecreaseIndent(); WriteIndent(); } base.EndBlock(statementCount, ref context); } protected virtual bool CanKeepBlockInLine(int statementCount, ref WriteContext context) { if (statementCount == 0) { return KeepEmptyBlockBodyInLine; } return false; } protected void StoreStatementBodyIntoContext(Statement statement, ref WriteContext context) { context._additionalDataSlot.PrimaryData = statement; } protected Statement RetrieveStatementBodyFromContext(ref WriteContext context) { return (Statement)(context._additionalDataSlot.PrimaryData ?? throw new InvalidOperationException()); } public override void StartStatement(StatementFlags flags, ref WriteContext context) { if (!flags.HasFlagFast(StatementFlags.IsStatementBody)) { return; } Statement nodePropertyValue = context.GetNodePropertyValue(); StoreStatementBodyIntoContext(nodePropertyValue, ref context); if (nodePropertyValue.Type != Nodes.BlockStatement) { if (CanKeepSingleStatementBodyInLine(nodePropertyValue, flags, ref context)) { WriteSpace(); return; } WriteEndOfLine(); IncreaseIndent(); WriteIndent(); } } public override void EndStatement(StatementFlags flags, ref WriteContext context) { if (flags.HasFlagFast(StatementFlags.IsStatementBody)) { Statement statement = RetrieveStatementBodyFromContext(ref context); if (statement.Type != Nodes.BlockStatement && !CanKeepSingleStatementBodyInLine(statement, flags, ref context)) { DecreaseIndent(); } } if (flags.HasFlagFast(StatementFlags.NeedsSemicolon) || ShouldTerminateStatementAnyway(context.GetNodePropertyValue(), flags, ref context)) { WritePunctuator(";", TokenFlags.Trailing | TokenFlags.TrailingSpaceRecommended, ref context); } } public override void StartStatementList(int count, ref WriteContext context) { if (context.Node.Type == Nodes.SwitchCase) { if (count == 1 && context.GetNodePropertyListValue()[0].Type == Nodes.BlockStatement) { WriteSpace(); return; } WriteEndOfLine(); IncreaseIndent(); } } public override void StartStatementListItem(int index, int count, StatementFlags flags, ref WriteContext context) { if (context.Node.Type != Nodes.SwitchCase || index != 0 || count != 1 || context.GetNodePropertyListValue()[0].Type != Nodes.BlockStatement) { WriteIndent(); } } public override void EndStatementListItem(int index, int count, StatementFlags flags, ref WriteContext context) { if (flags.HasFlagFast(StatementFlags.NeedsSemicolon) || ShouldTerminateStatementAnyway(context.GetNodePropertyListValue()[index], flags, ref context)) { WritePunctuator(";", TokenFlags.Trailing | TokenFlags.TrailingSpaceRecommended, ref context); } WriteEndOfLine(); } public override void EndStatementList(int count, ref WriteContext context) { if (context.Node.Type == Nodes.SwitchCase && (count != 1 || context.GetNodePropertyListValue()[0].Type != Nodes.BlockStatement)) { DecreaseIndent(); } } protected virtual bool CanKeepSingleStatementBodyInLine(Statement statement, StatementFlags flags, ref WriteContext context) { switch (statement.Type) { case Nodes.BreakStatement: case Nodes.ContinueStatement: case Nodes.DebuggerStatement: case Nodes.EmptyStatement: case Nodes.ExpressionStatement: case Nodes.ReturnStatement: case Nodes.ThrowStatement: return KeepSingleStatementBodyInLine; case Nodes.BlockStatement: case Nodes.DoWhileStatement: case Nodes.ForInStatement: case Nodes.ForOfStatement: case Nodes.ForStatement: case Nodes.LabeledStatement: case Nodes.SwitchStatement: case Nodes.TryStatement: case Nodes.WhileStatement: case Nodes.WithStatement: return false; case Nodes.IfStatement: { WriteContext writeContext = context; return writeContext.Node is IfStatement && writeContext.NodePropertyName == "Alternate"; } case Nodes.FunctionDeclaration: case Nodes.VariableDeclaration: return KeepSingleStatementBodyInLine; case Nodes.ClassDeclaration: case Nodes.ExportAllDeclaration: case Nodes.ExportDefaultDeclaration: case Nodes.ExportNamedDeclaration: case Nodes.ImportDeclaration: throw new ArgumentException($"Operation is not defined for nodes of type {statement.Type}.", "statement"); default: return false; } } protected virtual bool ShouldTerminateStatementAnyway(Statement statement, StatementFlags flags, ref WriteContext context) { if (statement.Type == Nodes.DoWhileStatement) { return true; } return false; } public override void StartExpression(ExpressionFlags flags, ref WriteContext context) { if (!flags.HasFlagFast(ExpressionFlags.NeedsBrackets)) { Expression expression = ((!context.NodePropertyHasListValue) ? context.GetNodePropertyValue() : context.GetNodePropertyListItem()); bool flag = ShouldWrapExpressionInBracketsAnyway(expression, flags, ref context); context._additionalDataSlot.PrimaryData = flag.AsCachedObject(); if (flag) { flags |= ExpressionFlags.NeedsBrackets; } } base.StartExpression(flags, ref context); } public override void EndExpression(ExpressionFlags flags, ref WriteContext context) { if (!flags.HasFlagFast(ExpressionFlags.NeedsBrackets) && (bool)context._additionalDataSlot.PrimaryData) { flags |= ExpressionFlags.NeedsBrackets; } base.EndExpression(flags, ref context); } public override void StartExpressionListItem(int index, int count, ExpressionFlags flags, ref WriteContext context) { if (context.Node.Type == Nodes.ArrayExpression && count >= MultiLineArrayLiteralThreshold) { WriteIndent(); } base.StartExpressionListItem(index, count, flags, ref context); } public override void EndExpressionListItem(int index, int count, ExpressionFlags flags, ref WriteContext context) { base.EndExpressionListItem(index, count, flags, ref context); if (context.Node.Type == Nodes.ArrayExpression && count >= MultiLineArrayLiteralThreshold) { WriteEndOfLine(); } } protected virtual bool ShouldWrapExpressionInBracketsAnyway(Expression expression, ExpressionFlags flags, ref WriteContext context) { if (base.LastTokenType == TokenType.Punctuator && base.LastTokenFlags.HasFlagFast(TokenFlags.IsUnaryOperator) && expression is UnaryExpression { Prefix: not false } unaryExpression) { return !char.IsLetter(UnaryExpression.GetUnaryOperatorToken(unaryExpression.Operator)[0]); } return false; } public override void StartAuxiliaryNodeListItem(int index, int count, string separator, object? nodeContext, ref WriteContext context) { if (typeof(T) == typeof(SwitchCase) || context.Node.Type == Nodes.ClassBody || (context.Node.Type == Nodes.ObjectExpression && count >= MultiLineObjectLiteralThreshold)) { WriteIndent(); } } public override void EndAuxiliaryNodeListItem(int index, int count, string separator, object? nodeContext, ref WriteContext context) { base.EndAuxiliaryNodeListItem(index, count, separator, nodeContext, ref context); if (context.Node.Type == Nodes.ClassBody || (context.Node.Type == Nodes.ObjectExpression && count >= MultiLineObjectLiteralThreshold)) { WriteEndOfLine(); } else if (typeof(T) == typeof(Decorator)) { WriteLine(); } } public override void Finish() { if (base.LastTriviaType.HasFlagFast(TriviaType.LineComment)) { WriteEndOfLine(); } base.Finish(); } } public record JavaScriptTextWriterOptions { public static readonly JavaScriptTextWriterOptions Default = new JavaScriptTextWriterOptions(); protected internal virtual JavaScriptTextWriter CreateWriter(TextWriter writer) { return new JavaScriptTextWriter(writer, this); } [CompilerGenerated] protected JavaScriptTextWriterOptions(JavaScriptTextWriterOptions original) { } public JavaScriptTextWriterOptions() { } } public class JavaScriptTextWriter { private enum TokenSequence : byte { None, BinaryPlus, BinaryMinus, BinaryDivide, BinaryLess, BinaryLessThenUnaryLogicalNot, UnaryPlus, UnaryMinus, UnaryPostfixDecrement } protected internal enum TriviaType { None = 0, WhiteSpace = 2, EndOfLine = 3, LineComment = 4, BlockComment = 5 } [Flags] public enum TriviaFlags { None = 0, LeadingNewLineRequired = 1, TrailingNewLineRequired = 2, SurroundingNewLineRequired = 3 } [Flags] public enum TokenFlags { None = 0, Leading = 1, InBetween = 2, Trailing = 4, FollowsStatementBody = 8, IsAssignmentOperator = 0x100, IsUnaryOperator = 0x200, IsBinaryOperator = 0x400, LeadingSpaceRecommended = 0x4000, TrailingSpaceRecommended = 0x8000, SurroundingSpaceRecommended = 0xC000 } [Flags] public enum StatementFlags { None = 0, NeedsSemicolon = 1, MayOmitRightMostSemicolon = 2, IsRightMost = 4, IsStatementBody = 8 } [Flags] public enum ExpressionFlags { None = 0, NeedsBrackets = 1, IsLeftMost = 2, SpaceBeforeBracketsRecommended = 0x4000, SpaceAfterBracketsRecommended = 0x8000, SpaceAroundBracketsRecommended = 0xC000 } public struct WriteContext { private string? _nodePropertyName; private Delegate? _nodePropertyAccessor; private NodePropertyListValueHelper? _nodePropertyListValueHelper; private int _nodePropertyItemIndex; internal AdditionalDataSlot _additionalDataSlot; public Node? ParentNode { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Node Node { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public string? NodePropertyName { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _nodePropertyName; } } public bool NodePropertyHasListValue { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _nodePropertyListValueHelper != null; } } public object? AssociatedData { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _additionalDataSlot[1]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] set { _additionalDataSlot[1] = value; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public WriteContext From(Node? parentNode, Node node) { return new WriteContext(parentNode, node ?? EsprimaExceptionHelper.ThrowArgumentNullException("node")); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal WriteContext(Node? parentNode, Node node) { ParentNode = parentNode; Node = node; _nodePropertyName = null; _nodePropertyAccessor = null; _nodePropertyListValueHelper = null; _nodePropertyItemIndex = -1; _additionalDataSlot = default(AdditionalDataSlot); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private Delegate EnsureNodePropertyAccessor() { return _nodePropertyAccessor ?? EsprimaExceptionHelper.ThrowInvalidOperationException("The context has no associated node property."); } private NodePropertyValueAccessor EnsureNodePropertyValueAccessor() { if (_nodePropertyAccessor is NodePropertyValueAccessor result) { return result; } EnsureNodePropertyAccessor(); return EsprimaExceptionHelper.ThrowInvalidOperationException("The context has an associated node property but its value is a node list."); } private NodePropertyListValueHelper EnsureNodePropertyListValueAccessor() { if (_nodePropertyListValueHelper != null) { return _nodePropertyListValueHelper; } EnsureNodePropertyAccessor(); return EsprimaExceptionHelper.ThrowInvalidOperationException("The context has an associated node property but its value is not a node list."); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public T GetNodePropertyValue() { return (T)EnsureNodePropertyValueAccessor()(Node); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ref readonly NodeList GetNodePropertyListValue() where T : Node? { EnsureNodePropertyListValueAccessor(); return ref ((NodePropertyListValueAccessor)_nodePropertyAccessor)(Node); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public NodeList GetNodePropertyListValue() { return EnsureNodePropertyListValueAccessor().GetNodeList(ref this); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public T GetNodePropertyListItem() where T : Node? { return (T)GetNodePropertyListValue()[_nodePropertyItemIndex]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ClearNodeProperty() { _nodePropertyName = null; _nodePropertyAccessor = null; _nodePropertyListValueHelper = null; _nodePropertyItemIndex = -1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void SetNodeProperty(string name, NodePropertyValueAccessor valueAccessor) { _nodePropertyName = name; _nodePropertyAccessor = valueAccessor; _nodePropertyListValueHelper = null; _nodePropertyItemIndex = -1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ChangeNodeProperty(string name, NodePropertyValueAccessor valueAccessor) { SetNodeProperty(name ?? EsprimaExceptionHelper.ThrowArgumentNullException("name"), valueAccessor ?? EsprimaExceptionHelper.ThrowArgumentNullException("valueAccessor")); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void SetNodeProperty(string name, NodePropertyListValueAccessor listValueAccessor) where T : Node? { _nodePropertyName = name; _nodePropertyAccessor = listValueAccessor; _nodePropertyListValueHelper = NodePropertyListValueHelper.Instance; _nodePropertyItemIndex = -1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ChangeNodeProperty(string name, NodePropertyListValueAccessor listValueAccessor) where T : Node? { SetNodeProperty(name ?? EsprimaExceptionHelper.ThrowArgumentNullException("name"), listValueAccessor ?? EsprimaExceptionHelper.ThrowArgumentNullException>("listValueAccessor")); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void SetNodePropertyItemIndex(int index) { _nodePropertyItemIndex = index; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ChangeNodePropertyItemIndex(int index) { EnsureNodePropertyAccessor(); if (index < 0) { EsprimaExceptionHelper.ThrowArgumentOutOfRangeException("index", index); } SetNodePropertyItemIndex(index); } } private readonly TextWriter _writer; private TokenSequence _lookbehind; private protected const TriviaType WhiteSpaceTriviaFlag = TriviaType.WhiteSpace; private protected const TriviaType CommentTriviaFlag = TriviaType.LineComment; protected TokenType LastTokenType { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; [MethodImpl(MethodImplOptions.AggressiveInlining)] private set; } protected TokenFlags LastTokenFlags { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; [MethodImpl(MethodImplOptions.AggressiveInlining)] private set; } protected TriviaType LastTriviaType { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; [MethodImpl(MethodImplOptions.AggressiveInlining)] private set; } protected bool CurrentLineIsEmptyOrWhiteSpace { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; [MethodImpl(MethodImplOptions.AggressiveInlining)] private set; } protected bool PendingRequiredNewLine { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; [MethodImpl(MethodImplOptions.AggressiveInlining)] private set; } public JavaScriptTextWriter(TextWriter writer, JavaScriptTextWriterOptions options) { _writer = writer ?? throw new ArgumentNullException("writer"); if ((object)options == null) { throw new ArgumentNullException("options"); } LastTokenType = TokenType.EOF; LastTriviaType = TriviaType.EndOfLine; CurrentLineIsEmptyOrWhiteSpace = true; } protected virtual void OnTriviaWritten(TriviaType type, TriviaFlags flags) { LastTriviaType = type; } [MethodImpl(MethodImplOptions.AggressiveInlining)] protected void WriteSpace() { WriteWhiteSpace(" "); } protected void WriteWhiteSpace(string value) { _writer.Write(value); OnTriviaWritten(TriviaType.WhiteSpace, TriviaFlags.None); _lookbehind = TokenSequence.None; } protected void WriteEndOfLine() { _writer.WriteLine(); OnTriviaWritten(TriviaType.EndOfLine, TriviaFlags.None); CurrentLineIsEmptyOrWhiteSpace = true; PendingRequiredNewLine = false; _lookbehind = TokenSequence.None; } protected virtual void WriteLine() { WriteEndOfLine(); } protected virtual void WriteLineCommentCore(TextWriter writer, string line, TriviaFlags flags) { writer.Write("//"); writer.Write(line); } public void WriteLineComment(string line, TriviaFlags flags) { if (PendingRequiredNewLine || (!CurrentLineIsEmptyOrWhiteSpace && flags.HasFlagFast(TriviaFlags.LeadingNewLineRequired))) { WriteLine(); } WriteLineCommentCore(_writer, line, flags); OnTriviaWritten(TriviaType.LineComment, flags); CurrentLineIsEmptyOrWhiteSpace = false; PendingRequiredNewLine = true; _lookbehind = TokenSequence.None; } protected virtual void WriteBlockCommentLine(TextWriter writer, string line, bool isFirst) { writer.Write(line); } protected virtual void WriteBlockCommentCore(TextWriter writer, IEnumerable lines, TriviaFlags flags) { writer.Write("/*"); using (IEnumerator enumerator = lines.GetEnumerator()) { if (enumerator.MoveNext()) { WriteBlockCommentLine(writer, enumerator.Current, isFirst: true); while (enumerator.MoveNext()) { writer.WriteLine(); WriteBlockCommentLine(writer, enumerator.Current, isFirst: false); } } } writer.Write("*/"); } public void WriteBlockComment(IEnumerable lines, TriviaFlags flags) { if (PendingRequiredNewLine || (!CurrentLineIsEmptyOrWhiteSpace && flags.HasFlagFast(TriviaFlags.LeadingNewLineRequired))) { WriteLine(); } WriteBlockCommentCore(_writer, lines, flags); OnTriviaWritten(TriviaType.BlockComment, flags); CurrentLineIsEmptyOrWhiteSpace = false; PendingRequiredNewLine = flags.HasFlagFast(TriviaFlags.TrailingNewLineRequired); _lookbehind = TokenSequence.None; } protected virtual void OnTokenWritten(TokenType type, TokenFlags flags) { LastTokenType = type; LastTokenFlags = flags; LastTriviaType = TriviaType.None; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void SpaceRecommendedAfterLastToken() { LastTokenFlags |= TokenFlags.TrailingSpaceRecommended; } protected void WriteRequiredSpaceBetweenTokenAndIdentifier() { switch (LastTokenType) { case TokenType.BooleanLiteral: case TokenType.Identifier: case TokenType.Keyword: case TokenType.NullLiteral: case TokenType.NumericLiteral: case TokenType.RegularExpression: case TokenType.BigIntLiteral: WriteSpace(); break; default: throw new InvalidOperationException(); case TokenType.EOF: case TokenType.Punctuator: case TokenType.StringLiteral: case TokenType.Template: break; } } protected virtual void StartIdentifier(string value, TokenFlags flags, ref WriteContext context) { if (LastTriviaType == TriviaType.None) { WriteRequiredSpaceBetweenTokenAndIdentifier(); } } public void WriteIdentifier(string value, TokenFlags flags, ref WriteContext context) { if (PendingRequiredNewLine) { WriteLine(); } StartIdentifier(value, flags, ref context); _writer.Write(value); EndIdentifier(value, flags, ref context); OnTokenWritten(TokenType.Identifier, flags); CurrentLineIsEmptyOrWhiteSpace = false; _lookbehind = TokenSequence.None; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void WriteIdentifier(string value, ref WriteContext context) { WriteIdentifier(value, TokenFlags.None, ref context); } protected virtual void EndIdentifier(string value, TokenFlags flags, ref WriteContext context) { } protected void WriteRequiredSpaceBetweenTokenAndKeyword() { switch (LastTokenType) { case TokenType.BooleanLiteral: case TokenType.Identifier: case TokenType.Keyword: case TokenType.NullLiteral: case TokenType.NumericLiteral: case TokenType.RegularExpression: case TokenType.BigIntLiteral: WriteSpace(); break; default: throw new InvalidOperationException(); case TokenType.EOF: case TokenType.Punctuator: case TokenType.StringLiteral: case TokenType.Template: break; } } protected virtual void StartKeyword(string value, TokenFlags flags, ref WriteContext context) { if (LastTriviaType == TriviaType.None) { WriteRequiredSpaceBetweenTokenAndKeyword(); } } public void WriteKeyword(string value, TokenFlags flags, ref WriteContext context) { if (PendingRequiredNewLine) { WriteLine(); } StartKeyword(value, flags, ref context); _writer.Write(value); EndKeyword(value, flags, ref context); OnTokenWritten(TokenType.Keyword, flags); CurrentLineIsEmptyOrWhiteSpace = false; _lookbehind = TokenSequence.None; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void WriteKeyword(string value, ref WriteContext context) { WriteKeyword(value, TokenFlags.None, ref context); } protected virtual void EndKeyword(string value, TokenFlags flags, ref WriteContext context) { } protected void WriteRequiredSpaceBetweenTokenAndLiteral(TokenType type) { switch (LastTokenType) { case TokenType.BooleanLiteral: case TokenType.Identifier: case TokenType.Keyword: case TokenType.NullLiteral: case TokenType.NumericLiteral: case TokenType.RegularExpression: case TokenType.BigIntLiteral: if (type - 8 > TokenType.BooleanLiteral) { WriteSpace(); } break; case TokenType.Punctuator: if (type == TokenType.RegularExpression && _lookbehind == TokenSequence.BinaryDivide) { WriteSpace(); } break; default: throw new InvalidOperationException(); case TokenType.EOF: case TokenType.StringLiteral: case TokenType.Template: break; } } protected virtual void StartLiteral(string value, TokenType type, TokenFlags flags, ref WriteContext context) { if (LastTriviaType == TriviaType.None) { WriteRequiredSpaceBetweenTokenAndLiteral(type); } } public void WriteLiteral(string value, TokenType type, TokenFlags flags, ref WriteContext context) { if (PendingRequiredNewLine) { WriteLine(); } StartLiteral(value, type, flags, ref context); _writer.Write(value); EndLiteral(value, type, flags, ref context); OnTokenWritten(type, flags); CurrentLineIsEmptyOrWhiteSpace = false; _lookbehind = TokenSequence.None; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void WriteLiteral(string value, TokenType tokenType, ref WriteContext context) { WriteLiteral(value, tokenType, TokenFlags.None, ref context); } protected virtual void EndLiteral(string value, TokenType type, TokenFlags flags, ref WriteContext context) { } protected virtual bool ShouldDisambiguatePunctuator(string value, TokenFlags flags, ref WriteContext context) { if (_lookbehind != TokenSequence.None) { switch (_lookbehind) { case TokenSequence.BinaryPlus: case TokenSequence.UnaryPlus: if (value[0] != '+') { break; } goto IL_0076; case TokenSequence.BinaryMinus: case TokenSequence.UnaryMinus: if (value[0] != '-') { break; } goto IL_0076; case TokenSequence.BinaryLessThenUnaryLogicalNot: if (value[0] != '-' || value.CharCodeAt(1) != '-') { break; } goto IL_0076; case TokenSequence.UnaryPostfixDecrement: { if (value[0] != '>') { break; } goto IL_0076; } IL_0076: return true; } } return false; } protected void WriteRequiredSpaceBetweenTokenAndPunctuator(string value, TokenFlags flags, ref WriteContext context) { if (ShouldDisambiguatePunctuator(value, flags, ref context)) { WriteSpace(); } } protected virtual void StartPunctuator(string value, TokenFlags flags, ref WriteContext context) { if (LastTriviaType == TriviaType.None) { WriteRequiredSpaceBetweenTokenAndPunctuator(value, flags, ref context); } } public void WritePunctuator(string value, TokenFlags flags, ref WriteContext context) { if (PendingRequiredNewLine) { WriteLine(); } StartPunctuator(value, flags, ref context); _writer.Write(value); EndPunctuator(value, flags, ref context); OnTokenWritten(TokenType.Punctuator, flags); CurrentLineIsEmptyOrWhiteSpace = false; TokenSequence lookbehind; if ((flags & (TokenFlags.IsUnaryOperator | TokenFlags.IsBinaryOperator)) != TokenFlags.None) { if (_lookbehind == TokenSequence.BinaryLess && context.Node is UnaryExpression { Operator: UnaryOperator.LogicalNot }) { _lookbehind = TokenSequence.BinaryLessThenUnaryLogicalNot; return; } Node node = context.Node; if (node is BinaryExpression { Operator: var binaryOperator }) { switch (binaryOperator) { case BinaryOperator.Plus: break; case BinaryOperator.Minus: goto IL_00d6; case BinaryOperator.Divide: goto IL_00da; case BinaryOperator.Less: goto IL_00de; default: goto IL_00ee; } lookbehind = TokenSequence.BinaryPlus; } else { if (!(node is UnaryExpression { Operator: var unaryOperator } unaryExpression2)) { goto IL_00ee; } if (unaryOperator != UnaryOperator.Plus) { if (unaryOperator != UnaryOperator.Minus) { if (unaryOperator != UnaryOperator.Decrement || unaryExpression2.Prefix) { goto IL_00ee; } lookbehind = TokenSequence.UnaryPostfixDecrement; } else { lookbehind = TokenSequence.UnaryMinus; } } else { lookbehind = TokenSequence.UnaryPlus; } } goto IL_00f0; } _lookbehind = TokenSequence.None; return; IL_00d6: lookbehind = TokenSequence.BinaryMinus; goto IL_00f0; IL_00de: lookbehind = TokenSequence.BinaryLess; goto IL_00f0; IL_00f0: _lookbehind = lookbehind; return; IL_00ee: lookbehind = TokenSequence.None; goto IL_00f0; IL_00da: lookbehind = TokenSequence.BinaryDivide; goto IL_00f0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void WritePunctuator(string value, ref WriteContext context) { WritePunctuator(value, TokenFlags.None, ref context); } protected virtual void EndPunctuator(string value, TokenFlags flags, ref WriteContext context) { } public virtual void StartArray(int elementCount, ref WriteContext context) { WritePunctuator("[", TokenFlags.Leading, ref context); } public virtual void EndArray(int elementCount, ref WriteContext context) { WritePunctuator("]", TokenFlags.Trailing, ref context); } public virtual void StartObject(int propertyCount, ref WriteContext context) { WritePunctuator("{", TokenFlags.Leading | TokenFlags.TrailingSpaceRecommended, ref context); } public virtual void EndObject(int propertyCount, ref WriteContext context) { WritePunctuator("}", TokenFlags.Trailing | TokenFlags.LeadingSpaceRecommended, ref context); } public virtual void StartBlock(int statementCount, ref WriteContext context) { WritePunctuator("{", TokenFlags.SurroundingSpaceRecommended | TokenFlags.Leading, ref context); } public virtual void EndBlock(int statementCount, ref WriteContext context) { WritePunctuator("}", TokenFlags.Trailing | TokenFlags.LeadingSpaceRecommended, ref context); } public virtual void StartStatement(StatementFlags flags, ref WriteContext context) { } public virtual void EndStatement(StatementFlags flags, ref WriteContext context) { if (flags.HasFlagFast(StatementFlags.NeedsSemicolon) && !flags.HasFlagFast(StatementFlags.MayOmitRightMostSemicolon | StatementFlags.IsRightMost)) { WritePunctuator(";", TokenFlags.Trailing | TokenFlags.TrailingSpaceRecommended, ref context); } } public virtual void StartStatementList(int count, ref WriteContext context) { } public virtual void StartStatementListItem(int index, int count, StatementFlags flags, ref WriteContext context) { } public virtual void EndStatementListItem(int index, int count, StatementFlags flags, ref WriteContext context) { if (flags.HasFlagFast(StatementFlags.NeedsSemicolon) && !flags.HasFlagFast(StatementFlags.MayOmitRightMostSemicolon | StatementFlags.IsRightMost)) { WritePunctuator(";", TokenFlags.Trailing | TokenFlags.TrailingSpaceRecommended, ref context); } } public virtual void EndStatementList(int count, ref WriteContext context) { } public virtual void StartExpression(ExpressionFlags flags, ref WriteContext context) { if (flags.HasFlagFast(ExpressionFlags.NeedsBrackets)) { WritePunctuator("(", TokenFlags.Leading | flags.HasFlagFast(ExpressionFlags.SpaceAroundBracketsRecommended).ToFlag(TokenFlags.LeadingSpaceRecommended), ref context); } } public virtual void EndExpression(ExpressionFlags flags, ref WriteContext context) { if (flags.HasFlagFast(ExpressionFlags.NeedsBrackets)) { WritePunctuator(")", TokenFlags.Trailing | flags.HasFlagFast(ExpressionFlags.SpaceAroundBracketsRecommended).ToFlag(TokenFlags.TrailingSpaceRecommended), ref context); } } public virtual void StartExpressionList(int count, ref WriteContext context) { } public virtual void StartExpressionListItem(int index, int count, ExpressionFlags flags, ref WriteContext context) { if (flags.HasFlagFast(ExpressionFlags.NeedsBrackets)) { WritePunctuator("(", TokenFlags.Leading, ref context); } } public virtual void EndExpressionListItem(int index, int count, ExpressionFlags flags, ref WriteContext context) { if (flags.HasFlagFast(ExpressionFlags.NeedsBrackets)) { WritePunctuator(")", TokenFlags.Trailing, ref context); } if (index < count - 1) { WritePunctuator(",", TokenFlags.InBetween | TokenFlags.TrailingSpaceRecommended, ref context); } } public virtual void EndExpressionList(int count, ref WriteContext context) { } public virtual void StartAuxiliaryNode(object? nodeContext, ref WriteContext context) { } public virtual void EndAuxiliaryNode(object? nodeContext, ref WriteContext context) { } public virtual void StartAuxiliaryNodeList(int count, ref WriteContext context) where T : Node? { } public virtual void StartAuxiliaryNodeListItem(int index, int count, string separator, object? nodeContext, ref WriteContext context) where T : Node? { } public virtual void EndAuxiliaryNodeListItem(int index, int count, string separator, object? nodeContext, ref WriteContext context) where T : Node? { if (separator.Length > 0 && index < count - 1) { WritePunctuator(separator, TokenFlags.InBetween | TokenFlags.TrailingSpaceRecommended, ref context); } } public virtual void EndAuxiliaryNodeList(int count, ref WriteContext context) where T : Node? { } public virtual void Finish() { OnTokenWritten(TokenType.EOF, TokenFlags.None); _lookbehind = TokenSequence.None; } } public delegate object? NodePropertyValueAccessor(Node node); public delegate ref readonly NodeList NodePropertyListValueAccessor(Node node) where T : Node?; internal abstract class NodePropertyListValueHelper { public abstract Type ItemType { get; } public abstract NodeList GetNodeList(ref JavaScriptTextWriter.WriteContext context); } internal sealed class NodePropertyListValueHelper : NodePropertyListValueHelper where T : Node? { public static readonly NodePropertyListValueHelper Instance = new NodePropertyListValueHelper(); public override Type ItemType => typeof(T); private NodePropertyListValueHelper() { } public override NodeList GetNodeList(ref JavaScriptTextWriter.WriteContext context) { return context.GetNodePropertyListValue().As(); } } internal sealed class JsonTextWriter : JsonWriter { private enum StructureKind : byte { Array, Object } private enum TokenKind { Scalar, String, Structure } private struct Stack : IEnumerable, IEnumerable where T : struct { private T[] _items; private int Capacity => _items.Length; public int Count { get; private set; } public ref T Top { get { if (Count <= 0) { throw new InvalidOperationException(); } return ref _items[Count - 1]; } } public Stack(int capacity) { _items = new T[capacity]; Count = 0; } public IEnumerator GetEnumerator() { for (int i = 0; i < Count; i++) { yield return _items[i]; } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public void Push(T item) { int capacity = Capacity; if (Count == capacity) { Array.Resize(ref _items, Math.Max(capacity * 2, 4)); } _items[Count] = item; Count++; } public T Pop() { if (Count == 0) { throw new InvalidOperationException(); } T top = Top; Top = default(T); Count--; return top; } } private readonly TextWriter _writer; private readonly string _indent; private Stack _structures; private Stack _counters; private string? _memberName; public int Depth => _structures.Count; private bool Pretty => _indent != ""; public JsonTextWriter(TextWriter writer) : this(writer, null) { } public JsonTextWriter(TextWriter writer, string? indent) { _writer = writer ?? throw new ArgumentNullException("writer"); if (!string.IsNullOrWhiteSpace(indent)) { throw new ArgumentException("Indent must be null or white-space.", "indent"); } _indent = indent ?? ""; _counters = new Stack(8); _structures = new Stack(8); } public override void StartObject() { StartStructured(StructureKind.Object); } public override void EndObject() { EndStructured(); } public override void StartArray() { StartStructured(StructureKind.Array); } public override void EndArray() { EndStructured(); } public override void Member(string name) { if (name == null) { throw new ArgumentNullException("name"); } if (Depth == 0 || _structures.Top != StructureKind.Object) { throw new InvalidOperationException("Member must be within an object."); } if (_memberName != null) { throw new InvalidOperationException("Missing value for member: " + _memberName); } _memberName = name; } public override void String(string? str) { if (str == null) { Null(); } else { Write(str, TokenKind.String); } } public override void Null() { Write("null", TokenKind.Scalar); } public override void Boolean(bool flag) { Write(flag ? "true" : "false", TokenKind.Scalar); } public void Number(int n) { Write(n.ToString(CultureInfo.InvariantCulture), TokenKind.Scalar); } public override void Number(long n) { Write(n.ToString(CultureInfo.InvariantCulture), TokenKind.Scalar); } public override void Number(double n) { if (double.IsNaN(n) || double.IsInfinity(n)) { throw new ArgumentOutOfRangeException("n", n, null); } Write(n.ToString(CultureInfo.InvariantCulture), TokenKind.Scalar); } private void Eol() { if (Pretty) { _writer.WriteLine(); } } private void Indent(int? depth = null) { if (Pretty) { int num = depth ?? Depth; for (int i = 0; i < num; i++) { _writer.Write(_indent); } } } private void StartStructured(StructureKind kind) { Write((kind == StructureKind.Array) ? "[" : "{", TokenKind.Structure); _counters.Push(0); _structures.Push(kind); } private void EndStructured() { if (Depth == 0) { throw new InvalidOperationException("No JSON structure in effect."); } if (_memberName != null) { throw new InvalidOperationException("Missing value for member: " + _memberName); } if (_counters.Top > 0) { Eol(); Indent(Depth - 1); } _writer.Write((_structures.Pop() == StructureKind.Array) ? "]" : "}"); _counters.Pop(); } private void Write(string token, TokenKind kind) { if (Depth == 0 && kind == TokenKind.Scalar) { throw new InvalidOperationException("JSON text must start with an object or an array."); } TextWriter writer = _writer; if (Depth > 0) { if (_structures.Top == StructureKind.Object && _memberName == null) { throw new InvalidOperationException("JSON object member name is undefined."); } if (_counters.Top > 0) { writer.Write(','); } Eol(); } string memberName = _memberName; _memberName = null; if (memberName != null) { Indent(); Enquote(memberName, writer); writer.Write(Pretty ? ": " : ":"); } if (Depth > 0 && _structures.Top == StructureKind.Array) { Indent(); } if (kind == TokenKind.String) { Enquote(token, writer); } else { writer.Write(token); } if (Depth > 0) { _counters.Top++; } } private static void Enquote(string s, TextWriter writer) { int length = (s ?? string.Empty).Length; writer.Write('"'); for (int i = 0; i < length; i++) { char c = s[i]; switch (c) { case '"': case '\\': writer.Write('\\'); writer.Write(c); continue; case '\b': writer.Write("\\b"); continue; case '\t': writer.Write("\\t"); continue; case '\n': writer.Write("\\n"); continue; case '\f': writer.Write("\\f"); continue; case '\r': writer.Write("\\r"); continue; } if (c < ' ') { writer.Write("\\u"); int num = c; writer.Write(num.ToString("x4", CultureInfo.InvariantCulture)); } else { writer.Write(c); } } writer.Write('"'); } } public abstract class JsonWriter { public abstract void Null(); public abstract void Number(long n); public abstract void Number(double n); public abstract void String(string? value); public abstract void Boolean(bool flag); public abstract void StartArray(); public abstract void EndArray(); public abstract void StartObject(); public abstract void Member(string name); public abstract void EndObject(); } public record KnRJavaScriptTextFormatterOptions : JavaScriptTextFormatterOptions { public bool UseEgyptianBraces { get; init; } = true; public new static readonly KnRJavaScriptTextFormatterOptions Default = new KnRJavaScriptTextFormatterOptions(); public KnRJavaScriptTextFormatterOptions() { base.KeepEmptyBlockBodyInLine = true; } protected override JavaScriptTextFormatter CreateFormatter(TextWriter writer) { return new KnRJavaScriptTextFormatter(writer, this); } [CompilerGenerated] protected KnRJavaScriptTextFormatterOptions(KnRJavaScriptTextFormatterOptions original) : base(original) { UseEgyptianBraces = original.UseEgyptianBraces; } } public class KnRJavaScriptTextFormatter : JavaScriptTextFormatter { protected bool UseEgyptianBraces { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public KnRJavaScriptTextFormatter(TextWriter writer, KnRJavaScriptTextFormatterOptions options) : base(writer, options) { UseEgyptianBraces = options.UseEgyptianBraces; } protected override void WriteWhiteSpaceBetweenTokenAndKeyword(string value, TokenFlags flags, ref WriteContext context) { if (flags.HasFlagFast(TokenFlags.FollowsStatementBody)) { if (UseEgyptianBraces && CanUseEgyptianBraces(ref context)) { WriteSpace(); } else { WriteLine(); } } else if (flags.HasFlagFast(TokenFlags.LeadingSpaceRecommended) || base.LastTokenFlags.HasFlagFast(TokenFlags.TrailingSpaceRecommended)) { WriteSpace(); } else { WriteRequiredSpaceBetweenTokenAndKeyword(); } } protected virtual bool CanUseEgyptianBraces(ref WriteContext context) { if (!base.KeepEmptyBlockBodyInLine) { return RetrieveStatementBodyFromContext(ref context).Type == Nodes.BlockStatement; } if (RetrieveStatementBodyFromContext(ref context) is BlockStatement blockStatement) { NodeList body = blockStatement.Body; return body.Count > 0; } return false; } } [AttributeUsage(AttributeTargets.Class, Inherited = false)] internal class AutoGeneratedAstVisitorAttribute : Attribute { public Type? VisitorType { get; set; } public string? TargetVisitorFieldName { get; set; } public string? BaseVisitorFieldName { get; set; } } } namespace Esprima.Utils.Jsx { public interface IJsxAstVisitor { object? VisitJsxAttribute(JsxAttribute jsxAttribute); object? VisitJsxClosingElement(JsxClosingElement jsxClosingElement); object? VisitJsxClosingFragment(JsxClosingFragment jsxClosingFragment); object? VisitJsxElement(JsxElement jsxElement); object? VisitJsxEmptyExpression(JsxEmptyExpression jsxEmptyExpression); object? VisitJsxExpressionContainer(JsxExpressionContainer jsxExpressionContainer); object? VisitJsxIdentifier(JsxIdentifier jsxIdentifier); object? VisitJsxMemberExpression(JsxMemberExpression jsxMemberExpression); object? VisitJsxNamespacedName(JsxNamespacedName jsxNamespacedName); object? VisitJsxOpeningElement(JsxOpeningElement jsxOpeningElement); object? VisitJsxOpeningFragment(JsxOpeningFragment jsxOpeningFragment); object? VisitJsxSpreadAttribute(JsxSpreadAttribute jsxSpreadAttribute); object? VisitJsxText(JsxText jsxText); } [AutoGeneratedAstVisitor(VisitorType = typeof(IJsxAstVisitor), TargetVisitorFieldName = "_rewriter", BaseVisitorFieldName = "_jsxVisitor")] public class JsxAstRewriter : AstRewriter, IJsxAstVisitor { private readonly AstRewriter _rewriter; private readonly IJsxAstVisitor _jsxVisitor; public static IJsxAstVisitor CreateJsxRewriterFor(TRewriter rewriter) where TRewriter : AstRewriter, IJsxAstVisitor { return new JsxAstRewriter(rewriter); } public JsxAstRewriter() { _rewriter = this; _jsxVisitor = JsxAstVisitor.CreateJsxVisitorFor(this); } private JsxAstRewriter(AstRewriter rewriter) { _rewriter = rewriter; _jsxVisitor = JsxAstVisitor.CreateJsxVisitorFor(this); } public virtual object? VisitJsxAttribute(JsxAttribute jsxAttribute) { JsxExpression name = _rewriter.VisitAndConvert(jsxAttribute.Name, allowNull: false, "VisitJsxAttribute"); Expression value = _rewriter.VisitAndConvert(jsxAttribute.Value, allowNull: true, "VisitJsxAttribute"); return jsxAttribute.UpdateWith(name, value); } public virtual object? VisitJsxClosingElement(JsxClosingElement jsxClosingElement) { JsxExpression name = _rewriter.VisitAndConvert(jsxClosingElement.Name, allowNull: false, "VisitJsxClosingElement"); return jsxClosingElement.UpdateWith(name); } public virtual object? VisitJsxClosingFragment(JsxClosingFragment jsxClosingFragment) { return _jsxVisitor.VisitJsxClosingFragment(jsxClosingFragment); } public virtual object? VisitJsxElement(JsxElement jsxElement) { Node openingElement = _rewriter.VisitAndConvert(jsxElement.OpeningElement, allowNull: false, "VisitJsxElement"); _rewriter.VisitAndConvert(in jsxElement.Children, out var newNodes, allowNullElement: false, "VisitJsxElement"); Node closingElement = _rewriter.VisitAndConvert(jsxElement.ClosingElement, allowNull: true, "VisitJsxElement"); return jsxElement.UpdateWith(openingElement, in newNodes, closingElement); } public virtual object? VisitJsxEmptyExpression(JsxEmptyExpression jsxEmptyExpression) { return _jsxVisitor.VisitJsxEmptyExpression(jsxEmptyExpression); } public virtual object? VisitJsxExpressionContainer(JsxExpressionContainer jsxExpressionContainer) { Expression expression = _rewriter.VisitAndConvert(jsxExpressionContainer.Expression, allowNull: false, "VisitJsxExpressionContainer"); return jsxExpressionContainer.UpdateWith(expression); } public virtual object? VisitJsxIdentifier(JsxIdentifier jsxIdentifier) { return _jsxVisitor.VisitJsxIdentifier(jsxIdentifier); } public virtual object? VisitJsxMemberExpression(JsxMemberExpression jsxMemberExpression) { JsxExpression jsxExpression = _rewriter.VisitAndConvert(jsxMemberExpression.Object, allowNull: false, "VisitJsxMemberExpression"); JsxIdentifier property = _rewriter.VisitAndConvert(jsxMemberExpression.Property, allowNull: false, "VisitJsxMemberExpression"); return jsxMemberExpression.UpdateWith(jsxExpression, property); } public virtual object? VisitJsxNamespacedName(JsxNamespacedName jsxNamespacedName) { JsxIdentifier name = _rewriter.VisitAndConvert(jsxNamespacedName.Name, allowNull: false, "VisitJsxNamespacedName"); JsxIdentifier jsxIdentifier = _rewriter.VisitAndConvert(jsxNamespacedName.Namespace, allowNull: false, "VisitJsxNamespacedName"); return jsxNamespacedName.UpdateWith(name, jsxIdentifier); } public virtual object? VisitJsxOpeningElement(JsxOpeningElement jsxOpeningElement) { JsxExpression name = _rewriter.VisitAndConvert(jsxOpeningElement.Name, allowNull: false, "VisitJsxOpeningElement"); _rewriter.VisitAndConvert(in jsxOpeningElement.Attributes, out var newNodes, allowNullElement: false, "VisitJsxOpeningElement"); return jsxOpeningElement.UpdateWith(name, in newNodes); } public virtual object? VisitJsxOpeningFragment(JsxOpeningFragment jsxOpeningFragment) { return _jsxVisitor.VisitJsxOpeningFragment(jsxOpeningFragment); } public virtual object? VisitJsxSpreadAttribute(JsxSpreadAttribute jsxSpreadAttribute) { Expression argument = _rewriter.VisitAndConvert(jsxSpreadAttribute.Argument, allowNull: false, "VisitJsxSpreadAttribute"); return jsxSpreadAttribute.UpdateWith(argument); } public virtual object? VisitJsxText(JsxText jsxText) { return _jsxVisitor.VisitJsxText(jsxText); } } public record JsxAstToJavaScriptOptions : AstToJavaScriptOptions { public new static readonly JsxAstToJavaScriptOptions Default = new JsxAstToJavaScriptOptions(); protected internal override AstToJavaScriptConverter CreateConverter(JavaScriptTextWriter writer) { return new JsxAstToJavaScriptConverter(writer, this); } [CompilerGenerated] protected JsxAstToJavaScriptOptions(JsxAstToJavaScriptOptions original) : base(original) { } public JsxAstToJavaScriptOptions() { } } public class JsxAstToJavaScriptConverter : AstToJavaScriptConverter, IJsxAstVisitor { public JsxAstToJavaScriptConverter(JavaScriptTextWriter writer, JsxAstToJavaScriptOptions options) : base(writer, options) { } object? IJsxAstVisitor.VisitJsxAttribute(JsxAttribute jsxAttribute) { base.Writer.SpaceRecommendedAfterLastToken(); base.WriteContext.SetNodeProperty("Name", (Node node) => node.As().Name); VisitAuxiliaryNode(jsxAttribute.Name); if (jsxAttribute.Value != null) { base.WriteContext.ClearNodeProperty(); base.Writer.WritePunctuator("=", JavaScriptTextWriter.TokenFlags.InBetween, ref base.WriteContext); base.WriteContext.SetNodeProperty("Value", (Node node) => node.As().Value); VisitAuxiliaryNode(jsxAttribute.Value); } return jsxAttribute; } object? IJsxAstVisitor.VisitJsxClosingElement(JsxClosingElement jsxClosingElement) { base.Writer.WritePunctuator("<", JavaScriptTextWriter.TokenFlags.Leading, ref base.WriteContext); base.Writer.WritePunctuator("/", ref base.WriteContext); base.WriteContext.SetNodeProperty("Name", (Node node) => node.As().Name); VisitAuxiliaryNode(jsxClosingElement.Name); base.WriteContext.ClearNodeProperty(); base.Writer.WritePunctuator(">", JavaScriptTextWriter.TokenFlags.Trailing, ref base.WriteContext); return jsxClosingElement; } object? IJsxAstVisitor.VisitJsxClosingFragment(JsxClosingFragment jsxClosingFragment) { base.Writer.WritePunctuator("<", JavaScriptTextWriter.TokenFlags.Leading, ref base.WriteContext); base.Writer.WritePunctuator("/", ref base.WriteContext); base.Writer.WritePunctuator(">", JavaScriptTextWriter.TokenFlags.Trailing, ref base.WriteContext); return jsxClosingFragment; } object? IJsxAstVisitor.VisitJsxElement(JsxElement jsxElement) { base.WriteContext.SetNodeProperty("OpeningElement", (Node node) => node.As().OpeningElement); VisitAuxiliaryNode(jsxElement.OpeningElement); base.WriteContext.SetNodeProperty("Children", (Node node) => ref node.As().Children); VisitAuxiliaryNodeList(in jsxElement.Children, string.Empty); if (jsxElement.ClosingElement != null) { base.WriteContext.SetNodeProperty("ClosingElement", (Node node) => node.As().ClosingElement); VisitAuxiliaryNode(jsxElement.ClosingElement); } return jsxElement; } object? IJsxAstVisitor.VisitJsxEmptyExpression(JsxEmptyExpression jsxEmptyExpression) { return jsxEmptyExpression; } object? IJsxAstVisitor.VisitJsxExpressionContainer(JsxExpressionContainer jsxExpressionContainer) { base.Writer.WritePunctuator("{", JavaScriptTextWriter.TokenFlags.Leading, ref base.WriteContext); base.WriteContext.SetNodeProperty("Expression", (Node node) => node.As().Expression); VisitRootExpression(jsxExpressionContainer.Expression, AstToJavaScriptConverter.RootExpressionFlags(needsBrackets: false)); base.WriteContext.ClearNodeProperty(); base.Writer.WritePunctuator("}", JavaScriptTextWriter.TokenFlags.Trailing, ref base.WriteContext); return jsxExpressionContainer; } object? IJsxAstVisitor.VisitJsxIdentifier(JsxIdentifier jsxIdentifier) { base.WriteContext.SetNodeProperty("Name", (Node node) => node.As().Name); base.Writer.WriteIdentifier(jsxIdentifier.Name, ref base.WriteContext); return jsxIdentifier; } object? IJsxAstVisitor.VisitJsxMemberExpression(JsxMemberExpression jsxMemberExpression) { base.WriteContext.SetNodeProperty("Object", (Node node) => node.As().Object); VisitAuxiliaryNode(jsxMemberExpression.Object); base.WriteContext.ClearNodeProperty(); base.Writer.WritePunctuator(".", JavaScriptTextWriter.TokenFlags.InBetween, ref base.WriteContext); base.WriteContext.SetNodeProperty("Property", (Node node) => node.As().Property); VisitAuxiliaryNode(jsxMemberExpression.Property); return jsxMemberExpression; } object? IJsxAstVisitor.VisitJsxNamespacedName(JsxNamespacedName jsxNamespacedName) { base.WriteContext.SetNodeProperty("Namespace", (Node node) => node.As().Namespace); VisitAuxiliaryNode(jsxNamespacedName.Namespace); base.WriteContext.ClearNodeProperty(); base.Writer.WritePunctuator(":", JavaScriptTextWriter.TokenFlags.InBetween, ref base.WriteContext); base.WriteContext.SetNodeProperty("Name", (Node node) => node.As().Name); VisitAuxiliaryNode(jsxNamespacedName.Name); return jsxNamespacedName; } object? IJsxAstVisitor.VisitJsxOpeningElement(JsxOpeningElement jsxOpeningElement) { base.Writer.WritePunctuator("<", JavaScriptTextWriter.TokenFlags.Leading, ref base.WriteContext); base.WriteContext.SetNodeProperty("Name", (Node node) => node.As().Name); VisitAuxiliaryNode(jsxOpeningElement.Name); base.WriteContext.SetNodeProperty("Attributes", (Node node) => ref node.As().Attributes); VisitAuxiliaryNodeList(in jsxOpeningElement.Attributes, string.Empty); if (jsxOpeningElement.SelfClosing) { base.WriteContext.SetNodeProperty("SelfClosing", (Node node) => node.As().SelfClosing); base.Writer.WritePunctuator("/", JavaScriptTextWriter.TokenFlags.LeadingSpaceRecommended, ref base.WriteContext); } base.WriteContext.ClearNodeProperty(); base.Writer.WritePunctuator(">", JavaScriptTextWriter.TokenFlags.Trailing, ref base.WriteContext); return jsxOpeningElement; } object? IJsxAstVisitor.VisitJsxOpeningFragment(JsxOpeningFragment jsxOpeningFragment) { base.Writer.WritePunctuator("<", JavaScriptTextWriter.TokenFlags.Leading, ref base.WriteContext); if (jsxOpeningFragment.SelfClosing) { base.WriteContext.SetNodeProperty("SelfClosing", (Node node) => node.As().SelfClosing); base.Writer.WritePunctuator("/", ref base.WriteContext); base.WriteContext.ClearNodeProperty(); } base.Writer.WritePunctuator(">", JavaScriptTextWriter.TokenFlags.Trailing, ref base.WriteContext); return jsxOpeningFragment; } object? IJsxAstVisitor.VisitJsxSpreadAttribute(JsxSpreadAttribute jsxSpreadAttribute) { base.Writer.WritePunctuator("{", JavaScriptTextWriter.TokenFlags.Leading | JavaScriptTextWriter.TokenFlags.LeadingSpaceRecommended, ref base.WriteContext); bool needsBrackets = UnaryOperandNeedsBrackets(jsxSpreadAttribute, jsxSpreadAttribute.Argument); base.WriteContext.SetNodeProperty("Argument", (Node node) => node.As().Argument); base.Writer.WritePunctuator("...", JavaScriptTextWriter.TokenFlags.Leading, ref base.WriteContext); VisitRootExpression(jsxSpreadAttribute.Argument, AstToJavaScriptConverter.RootExpressionFlags(needsBrackets)); base.WriteContext.ClearNodeProperty(); base.Writer.WritePunctuator("}", JavaScriptTextWriter.TokenFlags.Trailing, ref base.WriteContext); return jsxSpreadAttribute; } object? IJsxAstVisitor.VisitJsxText(JsxText jsxText) { base.Writer.WriteLiteral(jsxText.Raw, TokenType.Extension, ref base.WriteContext); return jsxText; } protected override int GetOperatorPrecedence(Expression expression, out int associativity) { if (expression.Type == Nodes.Extension && expression is JsxExpression { Type: var type }) { switch (type) { case JsxNodeType.Element: associativity = 0; return int.MaxValue; case JsxNodeType.SpreadAttribute: associativity = 0; return 200; } } return base.GetOperatorPrecedence(expression, out associativity); } } public record JsxAstToJsonOptions : AstToJsonOptions { public new static readonly JsxAstToJsonOptions Default = new JsxAstToJsonOptions(); protected internal override AstToJsonConverter CreateConverter(JsonWriter writer) { return new JsxAstToJsonConverter(writer, this); } [CompilerGenerated] protected JsxAstToJsonOptions(JsxAstToJsonOptions original) : base(original) { } public JsxAstToJsonOptions() { } } public class JsxAstToJsonConverter : AstToJsonConverter, IJsxAstVisitor { public JsxAstToJsonConverter(JsonWriter writer, JsxAstToJsonOptions options) : base(writer, options) { } protected override string GetNodeType(Node node) { if (node is JsxExpression jsxExpression) { return "JSX" + jsxExpression.Type; } return base.GetNodeType(node); } protected override string GetTokenType(SyntaxToken token) { if (token is JsxSyntaxToken jsxSyntaxToken) { return "JSX" + jsxSyntaxToken.Type; } return base.GetTokenType(token); } object? IJsxAstVisitor.VisitJsxAttribute(JsxAttribute jsxAttribute) { using (StartNodeObject(jsxAttribute)) { Member("name", (Node?)jsxAttribute.Name); Member("value", (Node?)jsxAttribute.Value); return jsxAttribute; } } object? IJsxAstVisitor.VisitJsxClosingElement(JsxClosingElement jsxClosingElement) { using (StartNodeObject(jsxClosingElement)) { Member("name", (Node?)jsxClosingElement.Name); return jsxClosingElement; } } object? IJsxAstVisitor.VisitJsxClosingFragment(JsxClosingFragment jsxClosingFragment) { using (StartNodeObject(jsxClosingFragment)) { return jsxClosingFragment; } } object? IJsxAstVisitor.VisitJsxElement(JsxElement jsxElement) { using (StartNodeObject(jsxElement)) { Member("openingElement", jsxElement.OpeningElement); Member("children", in jsxElement.Children); Member("closingElement", jsxElement.ClosingElement); return jsxElement; } } object? IJsxAstVisitor.VisitJsxEmptyExpression(JsxEmptyExpression jsxEmptyExpression) { using (StartNodeObject(jsxEmptyExpression)) { return jsxEmptyExpression; } } object? IJsxAstVisitor.VisitJsxExpressionContainer(JsxExpressionContainer jsxExpressionContainer) { using (StartNodeObject(jsxExpressionContainer)) { Member("expression", (Node?)jsxExpressionContainer.Expression); return jsxExpressionContainer; } } object? IJsxAstVisitor.VisitJsxIdentifier(JsxIdentifier jsxIdentifier) { using (StartNodeObject(jsxIdentifier)) { Member("name", jsxIdentifier.Name); return jsxIdentifier; } } object? IJsxAstVisitor.VisitJsxMemberExpression(JsxMemberExpression jsxMemberExpression) { using (StartNodeObject(jsxMemberExpression)) { Member("object", (Node?)jsxMemberExpression.Object); Member("property", (Node?)jsxMemberExpression.Property); return jsxMemberExpression; } } object? IJsxAstVisitor.VisitJsxNamespacedName(JsxNamespacedName jsxNamespacedName) { using (StartNodeObject(jsxNamespacedName)) { Member("namespace", (Node?)jsxNamespacedName.Namespace); Member("name", (Node?)jsxNamespacedName.Name); return jsxNamespacedName; } } object? IJsxAstVisitor.VisitJsxOpeningElement(JsxOpeningElement jsxOpeningElement) { using (StartNodeObject(jsxOpeningElement)) { Member("name", (Node?)jsxOpeningElement.Name); Member("selfClosing", jsxOpeningElement.SelfClosing); Member("attributes", in jsxOpeningElement.Attributes); return jsxOpeningElement; } } object? IJsxAstVisitor.VisitJsxOpeningFragment(JsxOpeningFragment jsxOpeningFragment) { using (StartNodeObject(jsxOpeningFragment)) { Member("selfClosing", jsxOpeningFragment.SelfClosing); return jsxOpeningFragment; } } object? IJsxAstVisitor.VisitJsxSpreadAttribute(JsxSpreadAttribute jsxSpreadAttribute) { using (StartNodeObject(jsxSpreadAttribute)) { Member("argument", (Node?)jsxSpreadAttribute.Argument); return jsxSpreadAttribute; } } object? IJsxAstVisitor.VisitJsxText(JsxText jsxText) { using (StartNodeObject(jsxText)) { Member("value", jsxText.Value); Member("raw", jsxText.Raw); return jsxText; } } } [AutoGeneratedAstVisitor(VisitorType = typeof(IJsxAstVisitor), TargetVisitorFieldName = "_visitor")] public class JsxAstVisitor : AstVisitor, IJsxAstVisitor { private readonly AstVisitor _visitor; public static IJsxAstVisitor CreateJsxVisitorFor(TVisitor visitor) where TVisitor : AstVisitor, IJsxAstVisitor { return new JsxAstVisitor(visitor); } public JsxAstVisitor() { _visitor = this; } private JsxAstVisitor(AstVisitor visitor) { _visitor = visitor; } public virtual object? VisitJsxAttribute(JsxAttribute jsxAttribute) { _visitor.Visit(jsxAttribute.Name); if (jsxAttribute.Value != null) { _visitor.Visit(jsxAttribute.Value); } return jsxAttribute; } public virtual object? VisitJsxClosingElement(JsxClosingElement jsxClosingElement) { _visitor.Visit(jsxClosingElement.Name); return jsxClosingElement; } public virtual object? VisitJsxClosingFragment(JsxClosingFragment jsxClosingFragment) { return jsxClosingFragment; } public virtual object? VisitJsxElement(JsxElement jsxElement) { _visitor.Visit(jsxElement.OpeningElement); ref readonly NodeList children = ref jsxElement.Children; for (int i = 0; i < children.Count; i++) { _visitor.Visit(children[i]); } if (jsxElement.ClosingElement != null) { _visitor.Visit(jsxElement.ClosingElement); } return jsxElement; } public virtual object? VisitJsxEmptyExpression(JsxEmptyExpression jsxEmptyExpression) { return jsxEmptyExpression; } public virtual object? VisitJsxExpressionContainer(JsxExpressionContainer jsxExpressionContainer) { _visitor.Visit(jsxExpressionContainer.Expression); return jsxExpressionContainer; } public virtual object? VisitJsxIdentifier(JsxIdentifier jsxIdentifier) { return jsxIdentifier; } public virtual object? VisitJsxMemberExpression(JsxMemberExpression jsxMemberExpression) { _visitor.Visit(jsxMemberExpression.Object); _visitor.Visit(jsxMemberExpression.Property); return jsxMemberExpression; } public virtual object? VisitJsxNamespacedName(JsxNamespacedName jsxNamespacedName) { _visitor.Visit(jsxNamespacedName.Name); _visitor.Visit(jsxNamespacedName.Namespace); return jsxNamespacedName; } public virtual object? VisitJsxOpeningElement(JsxOpeningElement jsxOpeningElement) { _visitor.Visit(jsxOpeningElement.Name); ref readonly NodeList attributes = ref jsxOpeningElement.Attributes; for (int i = 0; i < attributes.Count; i++) { _visitor.Visit(attributes[i]); } return jsxOpeningElement; } public virtual object? VisitJsxOpeningFragment(JsxOpeningFragment jsxOpeningFragment) { return jsxOpeningFragment; } public virtual object? VisitJsxSpreadAttribute(JsxSpreadAttribute jsxSpreadAttribute) { _visitor.Visit(jsxSpreadAttribute.Argument); return jsxSpreadAttribute; } public virtual object? VisitJsxText(JsxText jsxText) { return jsxText; } } } namespace Esprima.Ast { [VisitableNode(ChildProperties = new string[] { "Decorators", "Key", "Value" })] public sealed class AccessorProperty : ClassProperty { private readonly NodeList _decorators; public new Expression? Value { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public bool Static { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ref readonly NodeList Decorators { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _decorators; } } public AccessorProperty(Expression key, bool computed, Expression? value, bool isStatic, in NodeList decorators) : base(Nodes.AccessorProperty, PropertyKind.Property, key, computed) { Value = value; Static = isStatic; _decorators = decorators; } protected override Expression? GetValue() { return Value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private AccessorProperty Rewrite(in NodeList decorators, Expression key, Expression? value) { return new AccessorProperty(key, base.Computed, value, Static, in decorators); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNextNullableAt2(in Decorators, base.Key, Value); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitAccessorProperty(this); } public AccessorProperty UpdateWith(in NodeList decorators, Expression key, Expression? value) { if (decorators.IsSameAs(in Decorators) && key == base.Key && value == Value) { return this; } return Rewrite(in decorators, key, value); } } [VisitableNode(ChildProperties = new string[] { "Elements" })] public sealed class ArrayExpression : Expression { private readonly NodeList _elements; public ref readonly NodeList Elements { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _elements; } } public ArrayExpression(in NodeList elements) : base(Nodes.ArrayExpression) { _elements = elements; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ArrayExpression Rewrite(in NodeList elements) { return new ArrayExpression(in elements); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNextNullable(in Elements); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitArrayExpression(this); } public ArrayExpression UpdateWith(in NodeList elements) { if (elements.IsSameAs(in Elements)) { return this; } return Rewrite(in elements); } } [VisitableNode(ChildProperties = new string[] { "Elements" })] public sealed class ArrayPattern : BindingPattern { private readonly NodeList _elements; public ref readonly NodeList Elements { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _elements; } } public ArrayPattern(in NodeList elements) : base(Nodes.ArrayPattern) { _elements = elements; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ArrayPattern Rewrite(in NodeList elements) { return new ArrayPattern(in elements); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNextNullable(in Elements); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitArrayPattern(this); } public ArrayPattern UpdateWith(in NodeList elements) { if (elements.IsSameAs(in Elements)) { return this; } return Rewrite(in elements); } } [VisitableNode(ChildProperties = new string[] { "Params", "Body" })] public sealed class ArrowFunctionExpression : Expression, IFunction { private readonly NodeList _params; Identifier? IFunction.Id => null; public ref readonly NodeList Params { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _params; } } public StatementListItem Body { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } bool IFunction.Generator => false; public bool Expression { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public bool Strict { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public bool Async { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ArrowFunctionExpression(in NodeList parameters, StatementListItem body, bool expression, bool strict, bool async) : base(Nodes.ArrowFunctionExpression) { _params = parameters; Body = body; Expression = expression; Strict = strict; Async = async; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private ArrowFunctionExpression Rewrite(in NodeList @params, StatementListItem body) { return new ArrowFunctionExpression(in @params, body, Expression, Strict, Async); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(in Params, Body); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitArrowFunctionExpression(this); } public ArrowFunctionExpression UpdateWith(in NodeList @params, StatementListItem body) { if (@params.IsSameAs(in Params) && body == Body) { return this; } return Rewrite(in @params, body); } } internal sealed class ArrowParameterPlaceHolder : Expression { public const Nodes NodeType = (Nodes)(-2147483648); public static readonly ArrowParameterPlaceHolder Empty = new ArrowParameterPlaceHolder(default(NodeList), async: false); private readonly NodeList _params; public bool Async { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ref readonly NodeList Params { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _params; } } public ArrowParameterPlaceHolder(in NodeList parameters, bool async) : base((Nodes)(-2147483648)) { Async = async; _params = parameters; } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(in Params); } protected internal override object? Accept(AstVisitor visitor) { throw new NotSupportedException(); } } public enum AssignmentOperator { Assign, PlusAssign, MinusAssign, TimesAssign, DivideAssign, ModuloAssign, BitwiseAndAssign, BitwiseOrAssign, BitwiseXorAssign, LeftShiftAssign, RightShiftAssign, UnsignedRightShiftAssign, ExponentiationAssign, NullishAssign, AndAssign, OrAssign } [VisitableNode(ChildProperties = new string[] { "Left", "Right" })] public sealed class AssignmentExpression : Expression { public AssignmentOperator Operator { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Node Left { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Expression Right { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public AssignmentExpression(string op, Node left, Expression right) : this(ParseAssignmentOperator(op), left, right) { } public AssignmentExpression(AssignmentOperator op, Node left, Expression right) : base(Nodes.AssignmentExpression) { Operator = op; Left = left; Right = right; } public static AssignmentOperator ParseAssignmentOperator(string op) { return op switch { "=" => AssignmentOperator.Assign, "+=" => AssignmentOperator.PlusAssign, "-=" => AssignmentOperator.MinusAssign, "*=" => AssignmentOperator.TimesAssign, "/=" => AssignmentOperator.DivideAssign, "%=" => AssignmentOperator.ModuloAssign, "&=" => AssignmentOperator.BitwiseAndAssign, "|=" => AssignmentOperator.BitwiseOrAssign, "^=" => AssignmentOperator.BitwiseXorAssign, "<<=" => AssignmentOperator.LeftShiftAssign, ">>=" => AssignmentOperator.RightShiftAssign, ">>>=" => AssignmentOperator.UnsignedRightShiftAssign, "**=" => AssignmentOperator.ExponentiationAssign, "??=" => AssignmentOperator.NullishAssign, "&&=" => AssignmentOperator.AndAssign, "||=" => AssignmentOperator.OrAssign, _ => throw new ArgumentOutOfRangeException("op", op, "Invalid assignment operator."), }; } public static string GetAssignmentOperatorToken(AssignmentOperator op) { return op switch { AssignmentOperator.Assign => "=", AssignmentOperator.PlusAssign => "+=", AssignmentOperator.MinusAssign => "-=", AssignmentOperator.TimesAssign => "*=", AssignmentOperator.DivideAssign => "/=", AssignmentOperator.ModuloAssign => "%=", AssignmentOperator.BitwiseAndAssign => "&=", AssignmentOperator.BitwiseOrAssign => "|=", AssignmentOperator.BitwiseXorAssign => "^=", AssignmentOperator.LeftShiftAssign => "<<=", AssignmentOperator.RightShiftAssign => ">>=", AssignmentOperator.UnsignedRightShiftAssign => ">>>=", AssignmentOperator.ExponentiationAssign => "**=", AssignmentOperator.NullishAssign => "??=", AssignmentOperator.AndAssign => "&&=", AssignmentOperator.OrAssign => "||=", _ => throw new ArgumentOutOfRangeException("op", op, "Invalid assignment operator."), }; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private AssignmentExpression Rewrite(Node left, Expression right) { return new AssignmentExpression(Operator, left, right); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(Left, Right); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitAssignmentExpression(this); } public AssignmentExpression UpdateWith(Node left, Expression right) { if (left == Left && right == Right) { return this; } return Rewrite(left, right); } } [VisitableNode(ChildProperties = new string[] { "Left", "Right" })] public sealed class AssignmentPattern : Node { internal Expression _right; public Node Left { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Expression Right { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _right; } } public AssignmentPattern(Node left, Expression right) : base(Nodes.AssignmentPattern) { Left = left; _right = right; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static AssignmentPattern Rewrite(Node left, Expression right) { return new AssignmentPattern(left, right); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(Left, Right); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitAssignmentPattern(this); } public AssignmentPattern UpdateWith(Node left, Expression right) { if (left == Left && right == Right) { return this; } return Rewrite(left, right); } } [VisitableNode(ChildProperties = new string[] { "Argument" })] public sealed class AwaitExpression : Expression { public Expression Argument { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public AwaitExpression(Expression argument) : base(Nodes.AwaitExpression) { Argument = argument; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static AwaitExpression Rewrite(Expression argument) { return new AwaitExpression(argument); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(Argument); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitAwaitExpression(this); } public AwaitExpression UpdateWith(Expression argument) { if (argument == Argument) { return this; } return Rewrite(argument); } } public enum BinaryOperator { Plus, Minus, Times, Divide, Modulo, Equal, NotEqual, Greater, GreaterOrEqual, Less, LessOrEqual, StrictlyEqual, StrictlyNotEqual, BitwiseAnd, BitwiseOr, BitwiseXor, LeftShift, RightShift, UnsignedRightShift, InstanceOf, In, LogicalAnd, LogicalOr, Exponentiation, NullishCoalescing } [VisitableNode(ChildProperties = new string[] { "Left", "Right" }, SealOverrideMethods = true)] public class BinaryExpression : Expression { public BinaryOperator Operator { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Expression Left { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Expression Right { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public BinaryExpression(string op, Expression left, Expression right) : this(ParseBinaryOperator(op), left, right) { } public BinaryExpression(BinaryOperator op, Expression left, Expression right) : this(Nodes.BinaryExpression, op, left, right) { if (LogicalExpression.IsLogicalOperator(op)) { throw new ArgumentOutOfRangeException("op", op, "Value must be a non-logical operator."); } } private protected BinaryExpression(Nodes type, string op, Expression left, Expression right) : this(type, ParseBinaryOperator(op), left, right) { } private protected BinaryExpression(Nodes type, BinaryOperator op, Expression left, Expression right) : base(type) { Operator = op; Left = left; Right = right; } public static BinaryOperator ParseBinaryOperator(string op) { return op switch { "+" => BinaryOperator.Plus, "-" => BinaryOperator.Minus, "*" => BinaryOperator.Times, "/" => BinaryOperator.Divide, "%" => BinaryOperator.Modulo, "==" => BinaryOperator.Equal, "!=" => BinaryOperator.NotEqual, ">" => BinaryOperator.Greater, ">=" => BinaryOperator.GreaterOrEqual, "<" => BinaryOperator.Less, "<=" => BinaryOperator.LessOrEqual, "===" => BinaryOperator.StrictlyEqual, "!==" => BinaryOperator.StrictlyNotEqual, "&" => BinaryOperator.BitwiseAnd, "|" => BinaryOperator.BitwiseOr, "^" => BinaryOperator.BitwiseXor, "<<" => BinaryOperator.LeftShift, ">>" => BinaryOperator.RightShift, ">>>" => BinaryOperator.UnsignedRightShift, "instanceof" => BinaryOperator.InstanceOf, "in" => BinaryOperator.In, "&&" => BinaryOperator.LogicalAnd, "||" => BinaryOperator.LogicalOr, "**" => BinaryOperator.Exponentiation, "??" => BinaryOperator.NullishCoalescing, _ => throw new ArgumentOutOfRangeException("op", op, "Invalid binary operator."), }; } public static string GetBinaryOperatorToken(BinaryOperator op) { return op switch { BinaryOperator.Plus => "+", BinaryOperator.Minus => "-", BinaryOperator.Times => "*", BinaryOperator.Divide => "/", BinaryOperator.Modulo => "%", BinaryOperator.Equal => "==", BinaryOperator.NotEqual => "!=", BinaryOperator.Greater => ">", BinaryOperator.GreaterOrEqual => ">=", BinaryOperator.Less => "<", BinaryOperator.LessOrEqual => "<=", BinaryOperator.StrictlyEqual => "===", BinaryOperator.StrictlyNotEqual => "!==", BinaryOperator.BitwiseAnd => "&", BinaryOperator.BitwiseOr => "|", BinaryOperator.BitwiseXor => "^", BinaryOperator.LeftShift => "<<", BinaryOperator.RightShift => ">>", BinaryOperator.UnsignedRightShift => ">>>", BinaryOperator.InstanceOf => "instanceof", BinaryOperator.In => "in", BinaryOperator.LogicalAnd => "&&", BinaryOperator.LogicalOr => "||", BinaryOperator.Exponentiation => "**", BinaryOperator.NullishCoalescing => "??", _ => throw new ArgumentOutOfRangeException("op", op, "Invalid binary operator."), }; } protected virtual BinaryExpression Rewrite(Expression left, Expression right) { return new BinaryExpression(Operator, left, right); } internal sealed override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(Left, Right); } protected internal sealed override object? Accept(AstVisitor visitor) { return visitor.VisitBinaryExpression(this); } public BinaryExpression UpdateWith(Expression left, Expression right) { if (left == Left && right == Right) { return this; } return Rewrite(left, right); } } public abstract class BindingPattern : Node { protected BindingPattern(Nodes type) : base(type) { } } [VisitableNode(ChildProperties = new string[] { "Body" })] public sealed class BlockStatement : Statement { private readonly NodeList _body; public ref readonly NodeList Body { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _body; } } public BlockStatement(in NodeList body) : base(Nodes.BlockStatement) { _body = body; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static BlockStatement Rewrite(in NodeList body) { return new BlockStatement(in body); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(in Body); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitBlockStatement(this); } public BlockStatement UpdateWith(in NodeList body) { if (body.IsSameAs(in Body)) { return this; } return Rewrite(in body); } } [VisitableNode(ChildProperties = new string[] { "Label" })] public sealed class BreakStatement : Statement { public Identifier? Label { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public BreakStatement(Identifier? label) : base(Nodes.BreakStatement) { Label = label; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static BreakStatement Rewrite(Identifier? label) { return new BreakStatement(label); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNextNullable(Label); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitBreakStatement(this); } public BreakStatement UpdateWith(Identifier? label) { if (label == Label) { return this; } return Rewrite(label); } } [VisitableNode(ChildProperties = new string[] { "Callee", "Arguments" })] public sealed class CallExpression : Expression { private readonly NodeList _arguments; public Expression Callee { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ref readonly NodeList Arguments { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _arguments; } } public bool Optional { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public CallExpression(Expression callee, in NodeList args, bool optional) : base(Nodes.CallExpression) { Callee = callee; _arguments = args; Optional = optional; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private CallExpression Rewrite(Expression callee, in NodeList arguments) { return new CallExpression(callee, in arguments, Optional); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(Callee, in Arguments); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitCallExpression(this); } public CallExpression UpdateWith(Expression callee, in NodeList arguments) { if (callee == Callee && arguments.IsSameAs(in Arguments)) { return this; } return Rewrite(callee, in arguments); } } [VisitableNode(ChildProperties = new string[] { "Param", "Body" })] public sealed class CatchClause : Node { public Node? Param { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public BlockStatement Body { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public CatchClause(Node? param, BlockStatement body) : base(Nodes.CatchClause) { Param = param; Body = body; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static CatchClause Rewrite(Node? param, BlockStatement body) { return new CatchClause(param, body); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNextNullableAt0(Param, Body); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitCatchClause(this); } public CatchClause UpdateWith(Node? param, BlockStatement body) { if (param == Param && body == Body) { return this; } return Rewrite(param, body); } } [VisitableNode(ChildProperties = new string[] { "Expression" })] public sealed class ChainExpression : Expression { public Expression Expression { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ChainExpression(Expression expression) : base(Nodes.ChainExpression) { Expression = expression; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ChainExpression Rewrite(Expression expression) { return new ChainExpression(expression); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(Expression); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitChainExpression(this); } public ChainExpression UpdateWith(Expression expression) { if (expression == Expression) { return this; } return Rewrite(expression); } } public readonly struct ChildNodes : IEnumerable, IEnumerable { public struct Enumerator : IEnumerator, IEnumerator, IDisposable { private readonly object? _source; private int _propertyIndex; private int _listIndex; private Node? _current; public Node Current => _current; object? IEnumerator.Current => Current; public Enumerator(in ChildNodes childNodes) { _source = ((childNodes._parentNode != null) ? (((object)childNodes._parentNode.GetChildNodes()) ?? ((object)childNodes._parentNode)) : null); _propertyIndex = 0; _listIndex = 0; _current = null; } public void Dispose() { if (_source is IEnumerator enumerator) { enumerator.Dispose(); } } public bool MoveNext() { if (_source is Node node) { _current = node.NextChildNode(ref this); return _current != null; } if (_source is IEnumerator enumerator) { if (enumerator.MoveNext()) { _current = enumerator.Current; return true; } _current = null; } return false; } void IEnumerator.Reset() { if (_source is Node) { _propertyIndex = 0; _listIndex = 0; } else if (_source is IEnumerator enumerator) { enumerator.Reset(); } _current = null; } internal Node? MoveNextExportSpecifier(Expression local, Expression exported) { switch (_propertyIndex) { case 0: _propertyIndex++; return local; case 1: _propertyIndex++; if (exported != local) { return exported; } break; } return null; } internal Node? MoveNextImportSpecifier(Expression imported, Identifier local) { int propertyIndex = _propertyIndex; if (propertyIndex != 0) { if (propertyIndex != 1) { return null; } } else { _propertyIndex++; if (imported != local) { return imported; } } _propertyIndex++; return local; } internal Node? MoveNextProperty(Expression? key, Node value, bool shorthand) { int propertyIndex = _propertyIndex; if (propertyIndex != 0) { if (propertyIndex != 1) { return null; } } else { _propertyIndex++; if (!shorthand) { return key; } } _propertyIndex++; return value; } internal Node? MoveNextTemplateLiteral(in NodeList quasis, in NodeList expressions) { switch (_propertyIndex) { case 0: { _propertyIndex++; TemplateElement templateElement = quasis[_listIndex]; if (templateElement.Tail) { _propertyIndex++; _listIndex = 0; } return templateElement; } case 1: _propertyIndex--; return expressions[_listIndex++]; default: return null; } } internal Node? MoveNext(Node arg0) { if (_propertyIndex == 0) { _propertyIndex++; return arg0; } return null; } internal Node? MoveNext(in NodeList arg0) where T0 : Node { if (_propertyIndex == 0) { if (_listIndex < arg0.Count) { return arg0[_listIndex++]; } _listIndex = 0; _propertyIndex++; } return null; } internal Node? MoveNextNullable(Node? arg0) { if (_propertyIndex == 0) { _propertyIndex++; if (arg0 != null) { return arg0; } } return null; } internal Node? MoveNextNullable(in NodeList arg0) where T0 : Node { if (_propertyIndex == 0) { while (_listIndex < arg0.Count) { Node node = arg0[_listIndex++]; if (node != null) { return node; } } _listIndex = 0; _propertyIndex++; } return null; } internal Node? MoveNext(Node arg0, Node arg1) { switch (_propertyIndex) { case 0: _propertyIndex++; return arg0; case 1: _propertyIndex++; return arg1; default: return null; } } internal Node? MoveNext(in NodeList arg0, Node arg1) where T0 : Node { int propertyIndex = _propertyIndex; if (propertyIndex != 0) { if (propertyIndex != 1) { return null; } } else { if (_listIndex < arg0.Count) { return arg0[_listIndex++]; } _listIndex = 0; _propertyIndex++; } _propertyIndex++; return arg1; } internal Node? MoveNext(Node arg0, in NodeList arg1) where T1 : Node { switch (_propertyIndex) { case 0: _propertyIndex++; return arg0; case 1: if (_listIndex >= arg1.Count) { _listIndex = 0; _propertyIndex++; break; } return arg1[_listIndex++]; } return null; } internal Node? MoveNextNullableAt0(Node? arg0, Node arg1) { int propertyIndex = _propertyIndex; if (propertyIndex != 0) { if (propertyIndex != 1) { return null; } } else { _propertyIndex++; if (arg0 != null) { return arg0; } } _propertyIndex++; return arg1; } internal Node? MoveNextNullableAt0(Node? arg0, in NodeList arg1) where T1 : Node { int propertyIndex = _propertyIndex; if (propertyIndex != 0) { if (propertyIndex != 1) { goto IL_0065; } } else { _propertyIndex++; if (arg0 != null) { return arg0; } } if (_listIndex >= arg1.Count) { _listIndex = 0; _propertyIndex++; goto IL_0065; } return arg1[_listIndex++]; IL_0065: return null; } internal Node? MoveNextNullableAt1(Node arg0, Node? arg1) { switch (_propertyIndex) { case 0: _propertyIndex++; return arg0; case 1: _propertyIndex++; if (arg1 != null) { return arg1; } break; } return null; } internal Node? MoveNext(Node arg0, Node arg1, Node arg2) { switch (_propertyIndex) { case 0: _propertyIndex++; return arg0; case 1: _propertyIndex++; return arg1; case 2: _propertyIndex++; return arg2; default: return null; } } internal Node? MoveNext(in NodeList arg0, Node arg1, Node arg2) where T0 : Node { switch (_propertyIndex) { case 0: if (_listIndex >= arg0.Count) { _listIndex = 0; _propertyIndex++; goto case 1; } return arg0[_listIndex++]; case 1: _propertyIndex++; return arg1; case 2: _propertyIndex++; return arg2; default: return null; } } internal Node? MoveNext(in NodeList arg0, Node arg1, in NodeList arg2) where T0 : Node where T2 : Node { switch (_propertyIndex) { case 0: if (_listIndex >= arg0.Count) { _listIndex = 0; _propertyIndex++; goto case 1; } return arg0[_listIndex++]; case 1: _propertyIndex++; return arg1; case 2: if (_listIndex >= arg2.Count) { _listIndex = 0; _propertyIndex++; break; } return arg2[_listIndex++]; } return null; } internal Node? MoveNextNullableAt0(Node? arg0, in NodeList arg1, Node arg2) where T1 : Node { switch (_propertyIndex) { case 0: _propertyIndex++; if (arg0 != null) { return arg0; } goto case 1; case 1: if (_listIndex >= arg1.Count) { _listIndex = 0; _propertyIndex++; goto case 2; } return arg1[_listIndex++]; case 2: _propertyIndex++; return arg2; default: return null; } } internal Node? MoveNextNullableAt0(Node? arg0, Node arg1, in NodeList arg2) where T2 : Node { switch (_propertyIndex) { case 0: _propertyIndex++; if (arg0 != null) { return arg0; } goto case 1; case 1: _propertyIndex++; return arg1; case 2: if (_listIndex >= arg2.Count) { _listIndex = 0; _propertyIndex++; break; } return arg2[_listIndex++]; } return null; } internal Node? MoveNextNullableAt2(Node arg0, Node arg1, Node? arg2) { switch (_propertyIndex) { case 0: _propertyIndex++; return arg0; case 1: _propertyIndex++; return arg1; case 2: _propertyIndex++; if (arg2 != null) { return arg2; } break; } return null; } internal Node? MoveNextNullableAt2(in NodeList arg0, Node arg1, Node? arg2) where T0 : Node { switch (_propertyIndex) { case 0: if (_listIndex >= arg0.Count) { _listIndex = 0; _propertyIndex++; goto case 1; } return arg0[_listIndex++]; case 1: _propertyIndex++; return arg1; case 2: _propertyIndex++; if (arg2 != null) { return arg2; } break; } return null; } internal Node? MoveNextNullableAt2(Node arg0, in NodeList arg1, Node? arg2) where T1 : Node { switch (_propertyIndex) { case 0: _propertyIndex++; return arg0; case 1: if (_listIndex >= arg1.Count) { _listIndex = 0; _propertyIndex++; goto case 2; } return arg1[_listIndex++]; case 2: _propertyIndex++; if (arg2 != null) { return arg2; } break; } return null; } internal Node? MoveNextNullableAt1_2(Node arg0, Node? arg1, Node? arg2) { switch (_propertyIndex) { case 0: _propertyIndex++; return arg0; case 1: _propertyIndex++; if (arg1 != null) { return arg1; } goto case 2; case 2: _propertyIndex++; if (arg2 != null) { return arg2; } break; } return null; } internal Node? MoveNextNullableAt0_2(Node? arg0, in NodeList arg1, Node? arg2, in NodeList arg3) where T1 : Node where T3 : Node { switch (_propertyIndex) { case 0: _propertyIndex++; if (arg0 != null) { return arg0; } goto case 1; case 1: if (_listIndex >= arg1.Count) { _listIndex = 0; _propertyIndex++; goto case 2; } return arg1[_listIndex++]; case 2: _propertyIndex++; if (arg2 != null) { return arg2; } goto case 3; case 3: if (_listIndex >= arg3.Count) { _listIndex = 0; _propertyIndex++; break; } return arg3[_listIndex++]; } return null; } internal Node? MoveNextNullableAt1_2(in NodeList arg0, Node? arg1, Node? arg2, Node arg3) where T0 : Node { switch (_propertyIndex) { case 0: if (_listIndex >= arg0.Count) { _listIndex = 0; _propertyIndex++; goto case 1; } return arg0[_listIndex++]; case 1: _propertyIndex++; if (arg1 != null) { return arg1; } goto case 2; case 2: _propertyIndex++; if (arg2 != null) { return arg2; } goto case 3; case 3: _propertyIndex++; return arg3; default: return null; } } internal Node? MoveNextNullableAt0_1_2(Node? arg0, Node? arg1, Node? arg2, Node arg3) { switch (_propertyIndex) { case 0: _propertyIndex++; if (arg0 != null) { return arg0; } goto case 1; case 1: _propertyIndex++; if (arg1 != null) { return arg1; } goto case 2; case 2: _propertyIndex++; if (arg2 != null) { return arg2; } goto case 3; case 3: _propertyIndex++; return arg3; default: return null; } } } private readonly Node? _parentNode; internal ChildNodes(Node parentNode) { _parentNode = parentNode; } public bool IsEmpty() { using Enumerator enumerator = GetEnumerator(); return !enumerator.MoveNext(); } public Enumerator GetEnumerator() { return new Enumerator(in this); } IEnumerator IEnumerable.GetEnumerator() { return new Enumerator(in this); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } [VisitableNode(ChildProperties = new string[] { "Body" })] public sealed class ClassBody : Node { private readonly NodeList _body; public ref readonly NodeList Body { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _body; } } public ClassBody(in NodeList body) : base(Nodes.ClassBody) { _body = body; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ClassBody Rewrite(in NodeList body) { return new ClassBody(in body); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(in Body); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitClassBody(this); } public ClassBody UpdateWith(in NodeList body) { if (body.IsSameAs(in Body)) { return this; } return Rewrite(in body); } } [VisitableNode(ChildProperties = new string[] { "Decorators", "Id", "SuperClass", "Body" })] public sealed class ClassDeclaration : Declaration, IClass { private readonly NodeList _decorators; public Identifier? Id { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Expression? SuperClass { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ClassBody Body { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ref readonly NodeList Decorators { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _decorators; } } public ClassDeclaration(Identifier? id, Expression? superClass, ClassBody body, in NodeList decorators) : base(Nodes.ClassDeclaration) { Id = id; SuperClass = superClass; Body = body; _decorators = decorators; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ClassDeclaration Rewrite(in NodeList decorators, Identifier? id, Expression? superClass, ClassBody body) { return new ClassDeclaration(id, superClass, body, in decorators); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNextNullableAt1_2(in Decorators, Id, SuperClass, Body); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitClassDeclaration(this); } public ClassDeclaration UpdateWith(in NodeList decorators, Identifier? id, Expression? superClass, ClassBody body) { if (decorators.IsSameAs(in Decorators) && id == Id && superClass == SuperClass && body == Body) { return this; } return Rewrite(in decorators, id, superClass, body); } } public abstract class ClassElement : Node { protected ClassElement(Nodes type) : base(type) { } } [VisitableNode(ChildProperties = new string[] { "Decorators", "Id", "SuperClass", "Body" })] public sealed class ClassExpression : Expression, IClass { private readonly NodeList _decorators; public Identifier? Id { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Expression? SuperClass { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ClassBody Body { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ref readonly NodeList Decorators { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _decorators; } } public ClassExpression(Identifier? id, Expression? superClass, ClassBody body, in NodeList decorators) : base(Nodes.ClassExpression) { Id = id; SuperClass = superClass; Body = body; _decorators = decorators; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ClassExpression Rewrite(in NodeList decorators, Identifier? id, Expression? superClass, ClassBody body) { return new ClassExpression(id, superClass, body, in decorators); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNextNullableAt1_2(in Decorators, Id, SuperClass, Body); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitClassExpression(this); } public ClassExpression UpdateWith(in NodeList decorators, Identifier? id, Expression? superClass, ClassBody body) { if (decorators.IsSameAs(in Decorators) && id == Id && superClass == SuperClass && body == Body) { return this; } return Rewrite(in decorators, id, superClass, body); } } public abstract class ClassProperty : ClassElement, IProperty { public PropertyKind Kind { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Expression Key { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public bool Computed { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Expression? Value { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return GetValue(); } } Node? IProperty.Value => GetValue(); protected ClassProperty(Nodes type, PropertyKind kind, Expression key, bool computed) : base(type) { Kind = kind; Key = key; Computed = computed; } protected abstract Expression? GetValue(); } public sealed class ComputedMemberExpression : MemberExpression { public ComputedMemberExpression(Expression obj, Expression property, bool optional) : base(obj, property, computed: true, optional) { } protected override MemberExpression Rewrite(Expression @object, Expression property) { return new ComputedMemberExpression(@object, property, base.Optional); } } [VisitableNode(ChildProperties = new string[] { "Test", "Consequent", "Alternate" })] public sealed class ConditionalExpression : Expression { public Expression Test { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Expression Consequent { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Expression Alternate { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ConditionalExpression(Expression test, Expression consequent, Expression alternate) : base(Nodes.ConditionalExpression) { Test = test; Consequent = consequent; Alternate = alternate; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ConditionalExpression Rewrite(Expression test, Expression consequent, Expression alternate) { return new ConditionalExpression(test, consequent, alternate); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(Test, Consequent, Alternate); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitConditionalExpression(this); } public ConditionalExpression UpdateWith(Expression test, Expression consequent, Expression alternate) { if (test == Test && consequent == Consequent && alternate == Alternate) { return this; } return Rewrite(test, consequent, alternate); } } [VisitableNode(ChildProperties = new string[] { "Label" })] public sealed class ContinueStatement : Statement { public Identifier? Label { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ContinueStatement(Identifier? label) : base(Nodes.ContinueStatement) { Label = label; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ContinueStatement Rewrite(Identifier? label) { return new ContinueStatement(label); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNextNullable(Label); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitContinueStatement(this); } public ContinueStatement UpdateWith(Identifier? label) { if (label == Label) { return this; } return Rewrite(label); } } [VisitableNode] public sealed class DebuggerStatement : Statement { public DebuggerStatement() : base(Nodes.DebuggerStatement) { } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return null; } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitDebuggerStatement(this); } } public abstract class Declaration : Statement { protected Declaration(Nodes type) : base(type) { } } [VisitableNode(ChildProperties = new string[] { "Expression" })] public sealed class Decorator : Node { public Expression Expression { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Decorator(Expression expression) : base(Nodes.Decorator) { Expression = expression; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Decorator Rewrite(Expression expression) { return new Decorator(expression); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(Expression); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitDecorator(this); } public Decorator UpdateWith(Expression expression) { if (expression == Expression) { return this; } return Rewrite(expression); } } public sealed class Directive : ExpressionStatement { public string Value { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Directive(Expression expression, string value) : base(expression) { Value = value; } protected override ExpressionStatement Rewrite(Expression expression) { return new Directive(expression, Value); } } [VisitableNode(ChildProperties = new string[] { "Body", "Test" })] public sealed class DoWhileStatement : Statement { public Statement Body { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Expression Test { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public DoWhileStatement(Statement body, Expression test) : base(Nodes.DoWhileStatement) { Body = body; Test = test; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static DoWhileStatement Rewrite(Statement body, Expression test) { return new DoWhileStatement(body, test); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(Body, Test); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitDoWhileStatement(this); } public DoWhileStatement UpdateWith(Statement body, Expression test) { if (body == Body && test == Test) { return this; } return Rewrite(body, test); } } [VisitableNode] public sealed class EmptyStatement : Statement { public EmptyStatement() : base(Nodes.EmptyStatement) { } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return null; } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitEmptyStatement(this); } } [VisitableNode(ChildProperties = new string[] { "Exported", "Source", "Attributes" })] public sealed class ExportAllDeclaration : ExportDeclaration { private readonly NodeList _attributes; public Literal Source { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Expression? Exported { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ref readonly NodeList Attributes { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _attributes; } } public ExportAllDeclaration(Literal source) : this(source, null, default(NodeList)) { } public ExportAllDeclaration(Literal source, Expression? exported, in NodeList attributes) : base(Nodes.ExportAllDeclaration) { Source = source; Exported = exported; _attributes = attributes; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ExportAllDeclaration Rewrite(Expression? exported, Literal source, in NodeList attributes) { return new ExportAllDeclaration(source, exported, in attributes); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNextNullableAt0(Exported, Source, in Attributes); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitExportAllDeclaration(this); } public ExportAllDeclaration UpdateWith(Expression? exported, Literal source, in NodeList attributes) { if (exported == Exported && source == Source && attributes.IsSameAs(in Attributes)) { return this; } return Rewrite(exported, source, in attributes); } } public abstract class ExportDeclaration : Declaration { protected ExportDeclaration(Nodes type) : base(type) { } } [VisitableNode(ChildProperties = new string[] { "Declaration" })] public sealed class ExportDefaultDeclaration : ExportDeclaration { public StatementListItem Declaration { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ExportDefaultDeclaration(StatementListItem declaration) : base(Nodes.ExportDefaultDeclaration) { Declaration = declaration; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ExportDefaultDeclaration Rewrite(StatementListItem declaration) { return new ExportDefaultDeclaration(declaration); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(Declaration); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitExportDefaultDeclaration(this); } public ExportDefaultDeclaration UpdateWith(StatementListItem declaration) { if (declaration == Declaration) { return this; } return Rewrite(declaration); } } [VisitableNode(ChildProperties = new string[] { "Declaration", "Specifiers", "Source", "Attributes" })] public sealed class ExportNamedDeclaration : ExportDeclaration { private readonly NodeList _specifiers; private readonly NodeList _attributes; public Declaration? Declaration { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ref readonly NodeList Specifiers { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _specifiers; } } public Literal? Source { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ref readonly NodeList Attributes { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _attributes; } } public ExportNamedDeclaration(Declaration? declaration, in NodeList specifiers, Literal? source, in NodeList attributes) : base(Nodes.ExportNamedDeclaration) { Declaration = declaration; _specifiers = specifiers; Source = source; _attributes = attributes; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ExportNamedDeclaration Rewrite(Declaration? declaration, in NodeList specifiers, Literal? source, in NodeList attributes) { return new ExportNamedDeclaration(declaration, in specifiers, source, in attributes); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNextNullableAt0_2(Declaration, in Specifiers, Source, in Attributes); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitExportNamedDeclaration(this); } public ExportNamedDeclaration UpdateWith(Declaration? declaration, in NodeList specifiers, Literal? source, in NodeList attributes) { if (declaration == Declaration && specifiers.IsSameAs(in Specifiers) && source == Source && attributes.IsSameAs(in Attributes)) { return this; } return Rewrite(declaration, in specifiers, source, in attributes); } } [VisitableNode(ChildProperties = new string[] { "Local", "Exported" })] public sealed class ExportSpecifier : Node, IModuleSpecifier { public Expression Local { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Expression Exported { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ExportSpecifier(Expression local, Expression exported) : base(Nodes.ExportSpecifier) { Local = local; Exported = exported; } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNextExportSpecifier(Local, Exported); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ExportSpecifier Rewrite(Expression local, Expression exported) { return new ExportSpecifier(local, exported); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitExportSpecifier(this); } public ExportSpecifier UpdateWith(Expression local, Expression exported) { if (local == Local && exported == Exported) { return this; } return Rewrite(local, exported); } } public abstract class Expression : StatementListItem, ISyntaxTreeRoot { public IReadOnlyList? Tokens { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return (IReadOnlyList)GetDynamicPropertyValue(1); } [MethodImpl(MethodImplOptions.AggressiveInlining)] set { SetDynamicPropertyValue(1, value); } } public IReadOnlyList? Comments { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return (IReadOnlyList)GetDynamicPropertyValue(2); } [MethodImpl(MethodImplOptions.AggressiveInlining)] set { SetDynamicPropertyValue(2, value); } } protected Expression(Nodes type) : base(type) { } } [VisitableNode(ChildProperties = new string[] { "Expression" }, SealOverrideMethods = true)] public class ExpressionStatement : Statement { public Expression Expression { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ExpressionStatement(Expression expression) : base(Nodes.ExpressionStatement) { Expression = expression; } protected virtual ExpressionStatement Rewrite(Expression expression) { return new ExpressionStatement(expression); } internal sealed override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(Expression); } protected internal sealed override object? Accept(AstVisitor visitor) { return visitor.VisitExpressionStatement(this); } public ExpressionStatement UpdateWith(Expression expression) { if (expression == Expression) { return this; } return Rewrite(expression); } } [VisitableNode(ChildProperties = new string[] { "Left", "Right", "Body" })] public sealed class ForInStatement : Statement { public Node Left { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Expression Right { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Statement Body { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ForInStatement(Node left, Expression right, Statement body) : base(Nodes.ForInStatement) { Left = left; Right = right; Body = body; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ForInStatement Rewrite(Node left, Expression right, Statement body) { return new ForInStatement(left, right, body); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(Left, Right, Body); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitForInStatement(this); } public ForInStatement UpdateWith(Node left, Expression right, Statement body) { if (left == Left && right == Right && body == Body) { return this; } return Rewrite(left, right, body); } } [VisitableNode(ChildProperties = new string[] { "Left", "Right", "Body" })] public sealed class ForOfStatement : Statement { public Node Left { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Expression Right { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Statement Body { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public bool Await { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ForOfStatement(Node left, Expression right, Statement body, bool await) : base(Nodes.ForOfStatement) { Left = left; Right = right; Body = body; Await = await; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private ForOfStatement Rewrite(Node left, Expression right, Statement body) { return new ForOfStatement(left, right, body, Await); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(Left, Right, Body); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitForOfStatement(this); } public ForOfStatement UpdateWith(Node left, Expression right, Statement body) { if (left == Left && right == Right && body == Body) { return this; } return Rewrite(left, right, body); } } [VisitableNode(ChildProperties = new string[] { "Init", "Test", "Update", "Body" })] public sealed class ForStatement : Statement { public StatementListItem? Init { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Expression? Test { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Expression? Update { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Statement Body { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ForStatement(StatementListItem? init, Expression? test, Expression? update, Statement body) : base(Nodes.ForStatement) { Init = init; Test = test; Update = update; Body = body; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ForStatement Rewrite(StatementListItem? init, Expression? test, Expression? update, Statement body) { return new ForStatement(init, test, update, body); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNextNullableAt0_1_2(Init, Test, Update, Body); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitForStatement(this); } public ForStatement UpdateWith(StatementListItem? init, Expression? test, Expression? update, Statement body) { if (init == Init && test == Test && update == Update && body == Body) { return this; } return Rewrite(init, test, update, body); } } [VisitableNode(ChildProperties = new string[] { "Id", "Params", "Body" })] public sealed class FunctionDeclaration : Declaration, IFunction { private readonly NodeList _params; public Identifier? Id { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ref readonly NodeList Params { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _params; } } public BlockStatement Body { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } StatementListItem IFunction.Body => Body; public bool Generator { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } bool IFunction.Expression => false; public bool Strict { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public bool Async { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public FunctionDeclaration(Identifier? id, in NodeList parameters, BlockStatement body, bool generator, bool strict, bool async) : base(Nodes.FunctionDeclaration) { Id = id; _params = parameters; Body = body; Generator = generator; Strict = strict; Async = async; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private FunctionDeclaration Rewrite(Identifier? id, in NodeList @params, BlockStatement body) { return new FunctionDeclaration(id, in @params, body, Generator, Strict, Async); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNextNullableAt0(Id, in Params, Body); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitFunctionDeclaration(this); } public FunctionDeclaration UpdateWith(Identifier? id, in NodeList @params, BlockStatement body) { if (id == Id && @params.IsSameAs(in Params) && body == Body) { return this; } return Rewrite(id, in @params, body); } } [VisitableNode(ChildProperties = new string[] { "Id", "Params", "Body" })] public sealed class FunctionExpression : Expression, IFunction { private readonly NodeList _params; public Identifier? Id { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ref readonly NodeList Params { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _params; } } public BlockStatement Body { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } StatementListItem IFunction.Body => Body; public bool Generator { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } bool IFunction.Expression => false; public bool Strict { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public bool Async { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public FunctionExpression(Identifier? id, in NodeList parameters, BlockStatement body, bool generator, bool strict, bool async) : base(Nodes.FunctionExpression) { Id = id; _params = parameters; Body = body; Generator = generator; Strict = strict; Async = async; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private FunctionExpression Rewrite(Identifier? id, in NodeList @params, BlockStatement body) { return new FunctionExpression(id, in @params, body, Generator, Strict, Async); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNextNullableAt0(Id, in Params, Body); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitFunctionExpression(this); } public FunctionExpression UpdateWith(Identifier? id, in NodeList @params, BlockStatement body) { if (id == Id && @params.IsSameAs(in Params) && body == Body) { return this; } return Rewrite(id, in @params, body); } } public interface IClass { Nodes Type { get; } Identifier? Id { get; } Expression? SuperClass { get; } ClassBody Body { get; } ref readonly NodeList Decorators { get; } ChildNodes ChildNodes { get; } } [VisitableNode] public sealed class Identifier : Expression { public string Name { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Identifier(string name) : base(Nodes.Identifier) { Name = name; } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return null; } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitIdentifier(this); } } [VisitableNode(ChildProperties = new string[] { "Test", "Consequent", "Alternate" })] public sealed class IfStatement : Statement { public Expression Test { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Statement Consequent { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Statement? Alternate { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public IfStatement(Expression test, Statement consequent, Statement? alternate) : base(Nodes.IfStatement) { Test = test; Consequent = consequent; Alternate = alternate; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static IfStatement Rewrite(Expression test, Statement consequent, Statement? alternate) { return new IfStatement(test, consequent, alternate); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNextNullableAt2(Test, Consequent, Alternate); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitIfStatement(this); } public IfStatement UpdateWith(Expression test, Statement consequent, Statement? alternate) { if (test == Test && consequent == Consequent && alternate == Alternate) { return this; } return Rewrite(test, consequent, alternate); } } public interface IFunction { Nodes Type { get; } Identifier? Id { get; } ref readonly NodeList Params { get; } StatementListItem Body { get; } bool Generator { get; } bool Expression { get; } bool Strict { get; } bool Async { get; } ChildNodes ChildNodes { get; } } public interface IModuleSpecifier { Nodes Type { get; } Expression Local { get; } ChildNodes ChildNodes { get; } } [VisitableNode(ChildProperties = new string[] { "Key", "Value" })] public sealed class ImportAttribute : Node { public Expression Key { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Literal Value { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ImportAttribute(Expression key, Literal value) : base(Nodes.ImportAttribute) { Key = key; Value = value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ImportAttribute Rewrite(Expression key, Literal value) { return new ImportAttribute(key, value); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(Key, Value); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitImportAttribute(this); } public ImportAttribute UpdateWith(Expression key, Literal value) { if (key == Key && value == Value) { return this; } return Rewrite(key, value); } } [VisitableNode(ChildProperties = new string[] { "Specifiers", "Source", "Attributes" })] public sealed class ImportDeclaration : Declaration { private readonly NodeList _specifiers; private readonly NodeList _attributes; public ref readonly NodeList Specifiers { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _specifiers; } } public Literal Source { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ref readonly NodeList Attributes { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _attributes; } } public ImportDeclaration(in NodeList specifiers, Literal source, in NodeList attributes) : base(Nodes.ImportDeclaration) { _specifiers = specifiers; Source = source; _attributes = attributes; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ImportDeclaration Rewrite(in NodeList specifiers, Literal source, in NodeList attributes) { return new ImportDeclaration(in specifiers, source, in attributes); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(in Specifiers, Source, in Attributes); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitImportDeclaration(this); } public ImportDeclaration UpdateWith(in NodeList specifiers, Literal source, in NodeList attributes) { if (specifiers.IsSameAs(in Specifiers) && source == Source && attributes.IsSameAs(in Attributes)) { return this; } return Rewrite(in specifiers, source, in attributes); } } public abstract class ImportDeclarationSpecifier : Node, IModuleSpecifier { public Identifier Local { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } Expression IModuleSpecifier.Local => Local; protected ImportDeclarationSpecifier(Identifier local, Nodes type) : base(type) { Local = local; } } [VisitableNode(ChildProperties = new string[] { "Local" })] public sealed class ImportDefaultSpecifier : ImportDeclarationSpecifier { public ImportDefaultSpecifier(Identifier local) : base(local, Nodes.ImportDefaultSpecifier) { } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ImportDefaultSpecifier Rewrite(Identifier local) { return new ImportDefaultSpecifier(local); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(base.Local); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitImportDefaultSpecifier(this); } public ImportDefaultSpecifier UpdateWith(Identifier local) { if (local == base.Local) { return this; } return Rewrite(local); } } [VisitableNode(ChildProperties = new string[] { "Source", "Options" })] public sealed class ImportExpression : Expression { public Expression Source { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Expression? Options { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ImportExpression(Expression source) : this(source, null) { } public ImportExpression(Expression source, Expression? options) : base(Nodes.ImportExpression) { Source = source; Options = options; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ImportExpression Rewrite(Expression source, Expression? options) { return new ImportExpression(source, options); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNextNullableAt1(Source, Options); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitImportExpression(this); } public ImportExpression UpdateWith(Expression source, Expression? options) { if (source == Source && options == Options) { return this; } return Rewrite(source, options); } } [VisitableNode(ChildProperties = new string[] { "Local" })] public sealed class ImportNamespaceSpecifier : ImportDeclarationSpecifier { public ImportNamespaceSpecifier(Identifier local) : base(local, Nodes.ImportNamespaceSpecifier) { } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ImportNamespaceSpecifier Rewrite(Identifier local) { return new ImportNamespaceSpecifier(local); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(base.Local); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitImportNamespaceSpecifier(this); } public ImportNamespaceSpecifier UpdateWith(Identifier local) { if (local == base.Local) { return this; } return Rewrite(local); } } [VisitableNode(ChildProperties = new string[] { "Imported", "Local" })] public sealed class ImportSpecifier : ImportDeclarationSpecifier { public Expression Imported { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ImportSpecifier(Identifier local, Expression imported) : base(local, Nodes.ImportSpecifier) { Imported = imported; } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNextImportSpecifier(Imported, base.Local); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ImportSpecifier Rewrite(Expression imported, Identifier local) { return new ImportSpecifier(local, imported); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitImportSpecifier(this); } public ImportSpecifier UpdateWith(Expression imported, Identifier local) { if (imported == Imported && local == base.Local) { return this; } return Rewrite(imported, local); } } public interface IProperty { Nodes Type { get; } PropertyKind Kind { get; } Expression Key { get; } bool Computed { get; } Node? Value { get; } ChildNodes ChildNodes { get; } } internal interface ISyntaxTreeRoot { IReadOnlyList? Tokens { get; set; } IReadOnlyList? Comments { get; set; } } [VisitableNode(ChildProperties = new string[] { "Label", "Body" })] public sealed class LabeledStatement : Statement { public Identifier Label { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Statement Body { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public LabeledStatement(Identifier label, Statement body) : base(Nodes.LabeledStatement) { Label = label; Body = body; body._labelSet = label; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static LabeledStatement Rewrite(Identifier label, Statement body) { return new LabeledStatement(label, body); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(Label, Body); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitLabeledStatement(this); } public LabeledStatement UpdateWith(Identifier label, Statement body) { if (label == Label && body == Body) { return this; } return Rewrite(label, body); } } [VisitableNode(SealOverrideMethods = true)] public class Literal : Expression { public TokenType TokenType { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public object? Value { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public string Raw { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public string? StringValue { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { if (TokenType != TokenType.StringLiteral) { return null; } return (string)Value; } } public bool? BooleanValue { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { if (TokenType != TokenType.BooleanLiteral) { return null; } return Value == ParserExtensions.s_boxedTrue; } } public double? NumericValue { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { if (TokenType != TokenType.NumericLiteral) { return null; } return (double)Value; } } public Regex? RegexValue { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { if (TokenType != TokenType.RegularExpression) { return null; } return (Regex)Value; } } public BigInteger? BigIntValue { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { if (TokenType != TokenType.BigIntLiteral) { return null; } return (BigInteger)Value; } } internal Literal(TokenType tokenType, object? value, string raw) : base(Nodes.Literal) { TokenType = tokenType; Value = value; Raw = raw; } public Literal(string value, string raw) : this(TokenType.StringLiteral, value, raw) { } public Literal(bool value, string raw) : this(TokenType.BooleanLiteral, value.AsCachedObject(), raw) { } public Literal(double value, string raw) : this(TokenType.NumericLiteral, value, raw) { } public Literal(BigInteger value, string raw) : this(TokenType.BigIntLiteral, value, raw) { } public Literal(string raw) : this(TokenType.NullLiteral, null, raw) { } internal sealed override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return null; } protected internal sealed override object? Accept(AstVisitor visitor) { return visitor.VisitLiteral(this); } } public sealed class LogicalExpression : BinaryExpression { public LogicalExpression(string op, Expression left, Expression right) : this(BinaryExpression.ParseBinaryOperator(op), left, right) { } public LogicalExpression(BinaryOperator op, Expression left, Expression right) : base(Nodes.LogicalExpression, op, left, right) { if (!IsLogicalOperator(op)) { throw new ArgumentOutOfRangeException("op", op, "Value must be a logical operator."); } } internal static bool IsLogicalOperator(BinaryOperator op) { if ((uint)(op - 21) <= 1u || op == BinaryOperator.NullishCoalescing) { return true; } return false; } protected override BinaryExpression Rewrite(Expression left, Expression right) { return new LogicalExpression(base.Operator, left, right); } } [VisitableNode(ChildProperties = new string[] { "Object", "Property" }, SealOverrideMethods = true)] public abstract class MemberExpression : Expression { public Expression Object { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Expression Property { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public bool Computed { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public bool Optional { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } protected MemberExpression(Expression obj, Expression property, bool computed, bool optional) : base(Nodes.MemberExpression) { Object = obj; Property = property; Computed = computed; Optional = optional; } protected abstract MemberExpression Rewrite(Expression @object, Expression property); internal sealed override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(Object, Property); } protected internal sealed override object? Accept(AstVisitor visitor) { return visitor.VisitMemberExpression(this); } public MemberExpression UpdateWith(Expression @object, Expression property) { if (@object == Object && property == Property) { return this; } return Rewrite(@object, property); } } [VisitableNode(ChildProperties = new string[] { "Meta", "Property" })] public sealed class MetaProperty : Expression { public Identifier Meta { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Identifier Property { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public MetaProperty(Identifier meta, Identifier property) : base(Nodes.MetaProperty) { Meta = meta; Property = property; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static MetaProperty Rewrite(Identifier meta, Identifier property) { return new MetaProperty(meta, property); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(Meta, Property); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitMetaProperty(this); } public MetaProperty UpdateWith(Identifier meta, Identifier property) { if (meta == Meta && property == Property) { return this; } return Rewrite(meta, property); } } [VisitableNode(ChildProperties = new string[] { "Decorators", "Key", "Value" })] public sealed class MethodDefinition : ClassProperty { private readonly NodeList _decorators; public new FunctionExpression Value { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public bool Static { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ref readonly NodeList Decorators { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _decorators; } } public MethodDefinition(Expression key, bool computed, FunctionExpression value, PropertyKind kind, bool isStatic, in NodeList decorators) : base(Nodes.MethodDefinition, kind, key, computed) { Value = value; Static = isStatic; _decorators = decorators; } protected override Expression? GetValue() { return Value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private MethodDefinition Rewrite(in NodeList decorators, Expression key, FunctionExpression value) { return new MethodDefinition(key, base.Computed, value, base.Kind, Static, in decorators); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(in Decorators, base.Key, Value); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitMethodDefinition(this); } public MethodDefinition UpdateWith(in NodeList decorators, Expression key, FunctionExpression value) { if (decorators.IsSameAs(in Decorators) && key == base.Key && value == Value) { return this; } return Rewrite(in decorators, key, value); } } public sealed class Module : Program { public override SourceType SourceType => SourceType.Module; public override bool Strict => true; public Module(in NodeList body) : base(in body) { } protected override Program Rewrite(in NodeList body) { return new Module(in body); } } [VisitableNode(ChildProperties = new string[] { "Callee", "Arguments" })] public sealed class NewExpression : Expression { private readonly NodeList _arguments; public Expression Callee { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ref readonly NodeList Arguments { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _arguments; } } public NewExpression(Expression callee, in NodeList args) : base(Nodes.NewExpression) { Callee = callee; _arguments = args; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static NewExpression Rewrite(Expression callee, in NodeList arguments) { return new NewExpression(callee, in arguments); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(Callee, in Arguments); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitNewExpression(this); } public NewExpression UpdateWith(Expression callee, in NodeList arguments) { if (callee == Callee && arguments.IsSameAs(in Arguments)) { return this; } return Rewrite(callee, in arguments); } } public abstract class Node : SyntaxElement { private protected const int TokensPropertyIndex = 1; private protected const int CommentsPropertyIndex = 2; private static readonly AstToJavaScriptOptions s_toStringOptions = AstToJavaScriptOptions.Default with { IgnoreExtensions = true }; public Nodes Type { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ChildNodes ChildNodes => new ChildNodes(this); protected Node(Nodes type) { Type = type; } protected internal virtual IEnumerator? GetChildNodes() { return null; } internal virtual Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { throw new NotImplementedException("User-defined node types should override the GetChildNodes method and provide an actual implementation."); } protected internal abstract object? Accept(AstVisitor visitor); [MethodImpl(MethodImplOptions.AggressiveInlining)] protected object? AcceptAsExtension(AstVisitor visitor) { return visitor.VisitExtension(this); } public override string ToString() { return this.ToJavaScriptString(KnRJavaScriptTextFormatterOptions.Default, s_toStringOptions); } private protected override string GetDebuggerDisplay() { return $"/*{Type}*/ {this}"; } } public static class NodeExtensions { [MethodImpl(MethodImplOptions.AggressiveInlining)] [DebuggerStepThrough] public static T As(this Node node) where T : Node { return (T)node; } public static IEnumerable DescendantNodesAndSelf(this Node node) { if (node == null) { throw new ArgumentNullException("node"); } return Impl(node); static IEnumerable Impl(Node node2) { List nodes = new List(1) { node2 }; do { int lastIndex = nodes.Count - 1; node2 = nodes[lastIndex]; nodes.RemoveAt(lastIndex); yield return node2; foreach (Node childNode in node2.ChildNodes) { nodes.Add(childNode); } nodes.Reverse(lastIndex, nodes.Count - lastIndex); } while (nodes.Count > 0); } } public static IEnumerable DescendantNodes(this Node node) { return node.DescendantNodesAndSelf().Skip(1); } public static IEnumerable AncestorNodesAndSelf(this Node node, Node rootNode) { if (node == null) { throw new ArgumentNullException("node"); } if (rootNode == null) { throw new ArgumentNullException("rootNode"); } if (node == rootNode) { return new Node[1] { node }; } return Impl(node, rootNode); static IEnumerable Impl(Node node2, Node rootNode2) { using IEnumerator ancestor = node2.AncestorNodes(rootNode2).GetEnumerator(); if (ancestor.MoveNext()) { yield return node2; do { yield return ancestor.Current; } while (ancestor.MoveNext()); } } } public static IEnumerable AncestorNodes(this Node node, Node rootNode) { if (node == null) { throw new ArgumentNullException("node"); } if (rootNode == null) { throw new ArgumentNullException("rootNode"); } if (node == rootNode) { return Enumerable.Empty(); } Stack stack = new Stack(); Search(rootNode, node, stack); return stack; static bool Search(Node aNode, Node targetNode, Stack parents) { parents.Push(aNode); foreach (Node childNode in aNode.ChildNodes) { if (childNode == targetNode) { return true; } if (Search(childNode, targetNode, parents)) { return true; } } parents.Pop(); return false; } } } public readonly struct NodeList : IReadOnlyList, IEnumerable, IEnumerable, IReadOnlyCollection where T : Node? { public struct Enumerator : IEnumerator, IEnumerator, IDisposable { private readonly T[]? _items; private readonly int _count; private int _index; private T? _current; public T Current => _current; object? IEnumerator.Current { get { if (_index == 0 || _index == _count + 1) { throw new InvalidOperationException(); } return Current; } } internal Enumerator(T[]? items, int count) { this = default(Enumerator); _index = 0; _items = items; _count = count; } public void Dispose() { } public bool MoveNext() { if (_index < _count) { _current = _items[_index]; _index++; return true; } return MoveNextRare(); } private bool MoveNextRare() { _index = _count + 1; _current = null; return false; } public void Reset() { _index = 0; _current = null; } } private readonly T[]? _items; private readonly int _count; public int Count { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _count; } } public T this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { if ((uint)index < (uint)_count) { return _items[index]; } return EsprimaExceptionHelper.ThrowIndexOutOfRangeException(); } } internal NodeList(ICollection collection) { _items = null; if (collection == null) { ThrowArgumentNullException(); } _count = collection.Count; if (_count > 0) { _items = new T[_count]; collection.CopyTo(_items, 0); } static void ThrowArgumentNullException() { EsprimaExceptionHelper.ThrowArgumentNullException("collection"); } } internal NodeList(T[]? items, int count) { _items = items; _count = count; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal bool IsSameAs(in NodeList other) { return _items == other._items; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public NodeList AsNodes() { Node[] items = _items; return new NodeList(items, _count); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public NodeList As() where TTo : Node? { return new NodeList((TTo[])(object)_items, _count); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ReadOnlySpan AsSpan() { return new ReadOnlySpan(_items, 0, _count); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ReadOnlyMemory AsMemory() { return new ReadOnlyMemory(_items, 0, _count); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public T[] ToArray() { return AsSpan().ToArray(); } public Enumerator GetEnumerator() { return new Enumerator(_items, Count); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } public static class NodeList { internal static NodeList From(ref ArrayList arrayList) where T : Node? { arrayList.Yield(out T[] items, out int count); return new NodeList(items, count); } public static NodeList Create(IEnumerable source) where T : Node? { if (source != null) { if (source is NodeList) { return (NodeList)(object)source; } if (!(source is ICollection collection)) { if (source is IReadOnlyList readOnlyList) { if (readOnlyList.Count == 0) { return default(NodeList); } ArrayList arrayList = new ArrayList(readOnlyList.Count); for (int i = 0; i < readOnlyList.Count; i++) { arrayList.Add(readOnlyList[i]); } return From(ref arrayList); } int? num = ((source is IReadOnlyCollection readOnlyCollection) ? new int?(readOnlyCollection.Count) : ((int?)null)); ArrayList obj; if (num.HasValue) { int valueOrDefault = num.GetValueOrDefault(); obj = new ArrayList(valueOrDefault); } else { obj = default(ArrayList); } ArrayList arrayList2 = obj; if (!num.HasValue || num > 0) { foreach (T item in source) { arrayList2.Add(item); } } return From(ref arrayList2); } if (collection.Count <= 0) { return default(NodeList); } return new NodeList(collection); } throw new ArgumentNullException("source"); } } public enum Nodes { AccessorProperty = 0, ArrayExpression = 1, ArrayPattern = 2, ArrowFunctionExpression = 3, AssignmentExpression = 4, AssignmentPattern = 5, AwaitExpression = 6, BinaryExpression = 7, BlockStatement = 8, BreakStatement = 9, CallExpression = 10, CatchClause = 11, ChainExpression = 12, ClassBody = 13, ClassDeclaration = 14, ClassExpression = 15, ConditionalExpression = 16, ContinueStatement = 17, DebuggerStatement = 18, Decorator = 19, DoWhileStatement = 20, EmptyStatement = 21, ExportAllDeclaration = 22, ExportDefaultDeclaration = 23, ExportNamedDeclaration = 24, ExportSpecifier = 25, ExpressionStatement = 26, ForInStatement = 27, ForOfStatement = 28, ForStatement = 29, FunctionDeclaration = 30, FunctionExpression = 31, Identifier = 32, IfStatement = 33, ImportAttribute = 34, ImportDeclaration = 35, ImportDefaultSpecifier = 36, ImportExpression = 37, ImportNamespaceSpecifier = 38, ImportSpecifier = 39, LabeledStatement = 40, Literal = 41, LogicalExpression = 42, MemberExpression = 43, MetaProperty = 44, MethodDefinition = 45, NewExpression = 46, ObjectExpression = 47, ObjectPattern = 48, PrivateIdentifier = 49, Program = 50, Property = 51, PropertyDefinition = 52, RestElement = 53, ReturnStatement = 54, SequenceExpression = 55, SpreadElement = 56, StaticBlock = 57, Super = 58, SwitchCase = 59, SwitchStatement = 60, TaggedTemplateExpression = 61, TemplateElement = 62, TemplateLiteral = 63, ThisExpression = 64, ThrowStatement = 65, TryStatement = 66, UnaryExpression = 67, UpdateExpression = 68, VariableDeclaration = 69, VariableDeclarator = 70, WhileStatement = 71, WithStatement = 72, YieldExpression = 73, Extension = int.MaxValue } [VisitableNode(ChildProperties = new string[] { "Properties" })] public sealed class ObjectExpression : Expression { private readonly NodeList _properties; public ref readonly NodeList Properties { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _properties; } } public ObjectExpression(in NodeList properties) : base(Nodes.ObjectExpression) { _properties = properties; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ObjectExpression Rewrite(in NodeList properties) { return new ObjectExpression(in properties); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(in Properties); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitObjectExpression(this); } public ObjectExpression UpdateWith(in NodeList properties) { if (properties.IsSameAs(in Properties)) { return this; } return Rewrite(in properties); } } [VisitableNode(ChildProperties = new string[] { "Properties" })] public sealed class ObjectPattern : BindingPattern { private readonly NodeList _properties; public ref readonly NodeList Properties { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _properties; } } public ObjectPattern(in NodeList properties) : base(Nodes.ObjectPattern) { _properties = properties; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ObjectPattern Rewrite(in NodeList properties) { return new ObjectPattern(in properties); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(in Properties); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitObjectPattern(this); } public ObjectPattern UpdateWith(in NodeList properties) { if (properties.IsSameAs(in Properties)) { return this; } return Rewrite(in properties); } } [VisitableNode] public sealed class PrivateIdentifier : Expression { public string Name { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public PrivateIdentifier(string name) : base(Nodes.PrivateIdentifier) { Name = name; } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return null; } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitPrivateIdentifier(this); } } [VisitableNode(ChildProperties = new string[] { "Body" }, SealOverrideMethods = true)] public abstract class Program : Node, ISyntaxTreeRoot { private readonly NodeList _body; public ref readonly NodeList Body { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _body; } } public abstract SourceType SourceType { get; } public abstract bool Strict { get; } public IReadOnlyList? Tokens { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return (IReadOnlyList)GetDynamicPropertyValue(1); } [MethodImpl(MethodImplOptions.AggressiveInlining)] set { SetDynamicPropertyValue(1, value); } } public IReadOnlyList? Comments { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return (IReadOnlyList)GetDynamicPropertyValue(2); } [MethodImpl(MethodImplOptions.AggressiveInlining)] set { SetDynamicPropertyValue(2, value); } } protected Program(in NodeList body) : base(Nodes.Program) { _body = body; } protected abstract Program Rewrite(in NodeList body); internal sealed override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(in Body); } protected internal sealed override object? Accept(AstVisitor visitor) { return visitor.VisitProgram(this); } public Program UpdateWith(in NodeList body) { if (body.IsSameAs(in Body)) { return this; } return Rewrite(in body); } } [VisitableNode(ChildProperties = new string[] { "Key", "Value" })] public sealed class Property : Node, IProperty { internal Node _value; public PropertyKind Kind { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Expression Key { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public bool Computed { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Node Value { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _value; } } Node? IProperty.Value => Value; public bool Method { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public bool Shorthand { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Property(PropertyKind kind, Expression key, bool computed, Node value, bool method, bool shorthand) : base(Nodes.Property) { Kind = kind; Key = key; Computed = computed; _value = value; Method = method; Shorthand = shorthand; } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNextProperty(Key, Value, Shorthand); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private Property Rewrite(Expression key, Node value) { return new Property(Kind, key, Computed, value, Method, Shorthand); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitProperty(this); } public Property UpdateWith(Expression key, Node value) { if (key == Key && value == Value) { return this; } return Rewrite(key, value); } } [VisitableNode(ChildProperties = new string[] { "Decorators", "Key", "Value" })] public sealed class PropertyDefinition : ClassProperty { private readonly NodeList _decorators; public new Expression? Value { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public bool Static { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ref readonly NodeList Decorators { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _decorators; } } public PropertyDefinition(Expression key, bool computed, Expression? value, bool isStatic, in NodeList decorators) : base(Nodes.PropertyDefinition, PropertyKind.Property, key, computed) { Value = value; Static = isStatic; _decorators = decorators; } protected override Expression? GetValue() { return Value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private PropertyDefinition Rewrite(in NodeList decorators, Expression key, Expression? value) { return new PropertyDefinition(key, base.Computed, value, Static, in decorators); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNextNullableAt2(in Decorators, base.Key, Value); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitPropertyDefinition(this); } public PropertyDefinition UpdateWith(in NodeList decorators, Expression key, Expression? value) { if (decorators.IsSameAs(in Decorators) && key == base.Key && value == Value) { return this; } return Rewrite(in decorators, key, value); } } public enum PropertyKind { None, Get, Set, Init, Constructor, Method, Property } public sealed class RegExpLiteral : Literal { public RegexValue Regex { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public RegExpParseResult ParseResult { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public RegExpLiteral(string pattern, string flags, RegExpParseResult parseResult, string raw) : this(new RegexValue(pattern, flags), parseResult, raw) { } public RegExpLiteral(RegexValue regex, RegExpParseResult parseResult, string raw) : base(TokenType.RegularExpression, parseResult.Regex, raw) { Regex = regex; ParseResult = parseResult; } } public sealed record RegexValue(string Pattern, string Flags); [VisitableNode(ChildProperties = new string[] { "Argument" })] public sealed class RestElement : Node { public Node Argument { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public RestElement(Node argument) : base(Nodes.RestElement) { Argument = argument; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static RestElement Rewrite(Node argument) { return new RestElement(argument); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(Argument); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitRestElement(this); } public RestElement UpdateWith(Node argument) { if (argument == Argument) { return this; } return Rewrite(argument); } } [VisitableNode(ChildProperties = new string[] { "Argument" })] public sealed class ReturnStatement : Statement { public Expression? Argument { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ReturnStatement(Expression? argument) : base(Nodes.ReturnStatement) { Argument = argument; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ReturnStatement Rewrite(Expression? argument) { return new ReturnStatement(argument); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNextNullable(Argument); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitReturnStatement(this); } public ReturnStatement UpdateWith(Expression? argument) { if (argument == Argument) { return this; } return Rewrite(argument); } } public sealed class Script : Program { public override SourceType SourceType => SourceType.Script; public override bool Strict { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Script(in NodeList body, bool strict) : base(in body) { Strict = strict; } protected override Program Rewrite(in NodeList body) { return new Script(in body, Strict); } } [VisitableNode(ChildProperties = new string[] { "Expressions" })] public sealed class SequenceExpression : Expression { private readonly NodeList _expressions; public ref readonly NodeList Expressions { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _expressions; } } public SequenceExpression(in NodeList expressions) : base(Nodes.SequenceExpression) { _expressions = expressions; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static SequenceExpression Rewrite(in NodeList expressions) { return new SequenceExpression(in expressions); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(in Expressions); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitSequenceExpression(this); } public SequenceExpression UpdateWith(in NodeList expressions) { if (expressions.IsSameAs(in Expressions)) { return this; } return Rewrite(in expressions); } } public enum SourceType { Module, Script } [VisitableNode(ChildProperties = new string[] { "Argument" })] public sealed class SpreadElement : Expression { public Expression Argument { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public SpreadElement(Expression argument) : base(Nodes.SpreadElement) { Argument = argument; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static SpreadElement Rewrite(Expression argument) { return new SpreadElement(argument); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(Argument); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitSpreadElement(this); } public SpreadElement UpdateWith(Expression argument) { if (argument == Argument) { return this; } return Rewrite(argument); } } public abstract class Statement : StatementListItem { internal Identifier? _labelSet; public Identifier? LabelSet { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _labelSet; } } protected Statement(Nodes type) : base(type) { } } public abstract class StatementListItem : Node { protected StatementListItem(Nodes type) : base(type) { } } [VisitableNode(ChildProperties = new string[] { "Body" })] public sealed class StaticBlock : ClassElement { private readonly NodeList _body; public ref readonly NodeList Body { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _body; } } public StaticBlock(in NodeList body) : base(Nodes.StaticBlock) { _body = body; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static StaticBlock Rewrite(in NodeList body) { return new StaticBlock(in body); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(in Body); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitStaticBlock(this); } public StaticBlock UpdateWith(in NodeList body) { if (body.IsSameAs(in Body)) { return this; } return Rewrite(in body); } } public sealed class StaticMemberExpression : MemberExpression { public StaticMemberExpression(Expression obj, Expression property, bool optional) : base(obj, property, computed: false, optional) { } protected override MemberExpression Rewrite(Expression @object, Expression property) { return new StaticMemberExpression(@object, property, base.Optional); } } [VisitableNode] public sealed class Super : Expression { public Super() : base(Nodes.Super) { } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return null; } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitSuper(this); } } [VisitableNode(ChildProperties = new string[] { "Test", "Consequent" })] public sealed class SwitchCase : Node { private readonly NodeList _consequent; public Expression? Test { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ref readonly NodeList Consequent { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _consequent; } } public SwitchCase(Expression? test, in NodeList consequent) : base(Nodes.SwitchCase) { Test = test; _consequent = consequent; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static SwitchCase Rewrite(Expression? test, in NodeList consequent) { return new SwitchCase(test, in consequent); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNextNullableAt0(Test, in Consequent); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitSwitchCase(this); } public SwitchCase UpdateWith(Expression? test, in NodeList consequent) { if (test == Test && consequent.IsSameAs(in Consequent)) { return this; } return Rewrite(test, in consequent); } } [VisitableNode(ChildProperties = new string[] { "Discriminant", "Cases" })] public sealed class SwitchStatement : Statement { private readonly NodeList _cases; public Expression Discriminant { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ref readonly NodeList Cases { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _cases; } } public SwitchStatement(Expression discriminant, in NodeList cases) : base(Nodes.SwitchStatement) { Discriminant = discriminant; _cases = cases; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static SwitchStatement Rewrite(Expression discriminant, in NodeList cases) { return new SwitchStatement(discriminant, in cases); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(Discriminant, in Cases); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitSwitchStatement(this); } public SwitchStatement UpdateWith(Expression discriminant, in NodeList cases) { if (discriminant == Discriminant && cases.IsSameAs(in Cases)) { return this; } return Rewrite(discriminant, in cases); } } public class SyntaxComment : SyntaxElement { private static readonly string[] s_blockSeparators = new string[3] { "\r\n", "\r", "\n" }; public CommentType Type { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public string Value { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public SyntaxComment(CommentType type, string value) { Type = type; Value = value; } public override string ToString() { using StringWriter stringWriter = new StringWriter(); JavaScriptTextWriter javaScriptTextWriter = new JavaScriptTextWriter(stringWriter, JavaScriptTextWriterOptions.Default); switch (Type) { case CommentType.Line: javaScriptTextWriter.WriteLineComment(Value, JavaScriptTextWriter.TriviaFlags.None); break; case CommentType.Block: javaScriptTextWriter.WriteBlockComment(Value.Split(s_blockSeparators, StringSplitOptions.None), JavaScriptTextWriter.TriviaFlags.None); break; default: throw new InvalidOperationException(); } javaScriptTextWriter.Finish(); return stringWriter.ToString(); } } [DebuggerDisplay("{GetDebuggerDisplay(), nq}")] public abstract class SyntaxElement { private protected AdditionalDataSlot _additionalDataSlot; public Range Range; public Location Location; public object? AssociatedData { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _additionalDataSlot.PrimaryData; } [MethodImpl(MethodImplOptions.AggressiveInlining)] set { _additionalDataSlot.PrimaryData = value; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] private protected object? GetDynamicPropertyValue(int propertyIndex) { return _additionalDataSlot[propertyIndex]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private protected void SetDynamicPropertyValue(int propertyIndex, object? value) { _additionalDataSlot[propertyIndex] = value; } private protected virtual string GetDebuggerDisplay() { return ToString(); } } public class SyntaxToken : SyntaxElement { private const int RegexValuePropertyIndex = 1; public TokenType Type { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public string Value { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public RegexValue? RegexValue { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return (RegexValue)GetDynamicPropertyValue(1); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private set { SetDynamicPropertyValue(1, value); } } public SyntaxToken(TokenType type, string value, RegexValue? regexValue = null) { Type = type; Value = value; RegexValue = regexValue; } public override string ToString() { return Value; } } [VisitableNode(ChildProperties = new string[] { "Tag", "Quasi" })] public sealed class TaggedTemplateExpression : Expression { public Expression Tag { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public TemplateLiteral Quasi { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public TaggedTemplateExpression(Expression tag, TemplateLiteral quasi) : base(Nodes.TaggedTemplateExpression) { Tag = tag; Quasi = quasi; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static TaggedTemplateExpression Rewrite(Expression tag, TemplateLiteral quasi) { return new TaggedTemplateExpression(tag, quasi); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(Tag, Quasi); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitTaggedTemplateExpression(this); } public TaggedTemplateExpression UpdateWith(Expression tag, TemplateLiteral quasi) { if (tag == Tag && quasi == Quasi) { return this; } return Rewrite(tag, quasi); } } [VisitableNode] public sealed class TemplateElement : Node { public sealed record TemplateElementValue(string? Cooked, string Raw); public TemplateElementValue Value { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public bool Tail { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public TemplateElement(TemplateElementValue value, bool tail) : base(Nodes.TemplateElement) { Value = value; Tail = tail; } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return null; } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitTemplateElement(this); } } [VisitableNode(ChildProperties = new string[] { "Quasis", "Expressions" })] public sealed class TemplateLiteral : Expression { private readonly NodeList _quasis; private readonly NodeList _expressions; public ref readonly NodeList Quasis { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _quasis; } } public ref readonly NodeList Expressions { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _expressions; } } public TemplateLiteral(in NodeList quasis, in NodeList expressions) : base(Nodes.TemplateLiteral) { _quasis = quasis; _expressions = expressions; } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNextTemplateLiteral(in Quasis, in Expressions); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static TemplateLiteral Rewrite(in NodeList quasis, in NodeList expressions) { return new TemplateLiteral(in quasis, in expressions); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitTemplateLiteral(this); } public TemplateLiteral UpdateWith(in NodeList quasis, in NodeList expressions) { if (quasis.IsSameAs(in Quasis) && expressions.IsSameAs(in Expressions)) { return this; } return Rewrite(in quasis, in expressions); } } [VisitableNode] public sealed class ThisExpression : Expression { public ThisExpression() : base(Nodes.ThisExpression) { } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return null; } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitThisExpression(this); } } [VisitableNode(ChildProperties = new string[] { "Argument" })] public sealed class ThrowStatement : Statement { public Expression Argument { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ThrowStatement(Expression argument) : base(Nodes.ThrowStatement) { Argument = argument; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static ThrowStatement Rewrite(Expression argument) { return new ThrowStatement(argument); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(Argument); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitThrowStatement(this); } public ThrowStatement UpdateWith(Expression argument) { if (argument == Argument) { return this; } return Rewrite(argument); } } [VisitableNode(ChildProperties = new string[] { "Block", "Handler", "Finalizer" })] public sealed class TryStatement : Statement { public BlockStatement Block { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public CatchClause? Handler { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public BlockStatement? Finalizer { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public TryStatement(BlockStatement block, CatchClause? handler, BlockStatement? finalizer) : base(Nodes.TryStatement) { Block = block; Handler = handler; Finalizer = finalizer; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static TryStatement Rewrite(BlockStatement block, CatchClause? handler, BlockStatement? finalizer) { return new TryStatement(block, handler, finalizer); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNextNullableAt1_2(Block, Handler, Finalizer); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitTryStatement(this); } public TryStatement UpdateWith(BlockStatement block, CatchClause? handler, BlockStatement? finalizer) { if (block == Block && handler == Handler && finalizer == Finalizer) { return this; } return Rewrite(block, handler, finalizer); } } public enum UnaryOperator { Plus, Minus, BitwiseNot, LogicalNot, Delete, Void, TypeOf, Increment, Decrement } [VisitableNode(ChildProperties = new string[] { "Argument" }, SealOverrideMethods = true)] public class UnaryExpression : Expression { public UnaryOperator Operator { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Expression Argument { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public bool Prefix { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public UnaryExpression(string op, Expression arg) : this(ParseUnaryOperator(op), arg) { } public UnaryExpression(UnaryOperator op, Expression arg) : this(Nodes.UnaryExpression, op, arg, prefix: true) { if (UpdateExpression.IsUpdateOperator(op)) { throw new ArgumentOutOfRangeException("op", op, "Value must be a non-update operator."); } } private protected UnaryExpression(Nodes type, string op, Expression arg, bool prefix) : this(type, ParseUnaryOperator(op), arg, prefix) { } private protected UnaryExpression(Nodes type, UnaryOperator op, Expression arg, bool prefix) : base(type) { Operator = op; Argument = arg; Prefix = prefix; } public static UnaryOperator ParseUnaryOperator(string op) { return op switch { "+" => UnaryOperator.Plus, "-" => UnaryOperator.Minus, "~" => UnaryOperator.BitwiseNot, "!" => UnaryOperator.LogicalNot, "delete" => UnaryOperator.Delete, "void" => UnaryOperator.Void, "typeof" => UnaryOperator.TypeOf, "++" => UnaryOperator.Increment, "--" => UnaryOperator.Decrement, _ => throw new ArgumentOutOfRangeException("op", op, "Invalid unary operator."), }; } public static string GetUnaryOperatorToken(UnaryOperator op) { return op switch { UnaryOperator.Plus => "+", UnaryOperator.Minus => "-", UnaryOperator.BitwiseNot => "~", UnaryOperator.LogicalNot => "!", UnaryOperator.Delete => "delete", UnaryOperator.Void => "void", UnaryOperator.TypeOf => "typeof", UnaryOperator.Increment => "++", UnaryOperator.Decrement => "--", _ => throw new ArgumentOutOfRangeException("op", op, "Invalid unary operator."), }; } protected virtual UnaryExpression Rewrite(Expression argument) { return new UnaryExpression(Operator, argument); } internal sealed override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(Argument); } protected internal sealed override object? Accept(AstVisitor visitor) { return visitor.VisitUnaryExpression(this); } public UnaryExpression UpdateWith(Expression argument) { if (argument == Argument) { return this; } return Rewrite(argument); } } public sealed class UpdateExpression : UnaryExpression { public UpdateExpression(string op, Expression arg, bool prefix) : this(UnaryExpression.ParseUnaryOperator(op), arg, prefix) { } public UpdateExpression(UnaryOperator op, Expression arg, bool prefix) : base(Nodes.UpdateExpression, op, arg, prefix) { if (!IsUpdateOperator(op)) { throw new ArgumentOutOfRangeException("op", op, "Value must be an update operator."); } } internal static bool IsUpdateOperator(UnaryOperator op) { if ((uint)(op - 7) <= 1u) { return true; } return false; } protected override UnaryExpression Rewrite(Expression argument) { return new UpdateExpression(base.Operator, argument, base.Prefix); } } [VisitableNode(ChildProperties = new string[] { "Declarations" })] public sealed class VariableDeclaration : Declaration { private readonly NodeList _declarations; public ref readonly NodeList Declarations { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _declarations; } } public VariableDeclarationKind Kind { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public static string GetVariableDeclarationKindToken(VariableDeclarationKind kind) { return kind switch { VariableDeclarationKind.Var => "var", VariableDeclarationKind.Let => "let", VariableDeclarationKind.Const => "const", _ => throw new ArgumentOutOfRangeException("kind", kind, "Invalid variable declaration kind."), }; } public VariableDeclaration(in NodeList declarations, VariableDeclarationKind kind) : base(Nodes.VariableDeclaration) { _declarations = declarations; Kind = kind; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private VariableDeclaration Rewrite(in NodeList declarations) { return new VariableDeclaration(in declarations, Kind); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(in Declarations); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitVariableDeclaration(this); } public VariableDeclaration UpdateWith(in NodeList declarations) { if (declarations.IsSameAs(in Declarations)) { return this; } return Rewrite(in declarations); } } public enum VariableDeclarationKind { Var, Let, Const } [VisitableNode(ChildProperties = new string[] { "Id", "Init" })] public sealed class VariableDeclarator : Node { public Node Id { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Expression? Init { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public VariableDeclarator(Node id, Expression? init) : base(Nodes.VariableDeclarator) { Id = id; Init = init; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static VariableDeclarator Rewrite(Node id, Expression? init) { return new VariableDeclarator(id, init); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNextNullableAt1(Id, Init); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitVariableDeclarator(this); } public VariableDeclarator UpdateWith(Node id, Expression? init) { if (id == Id && init == Init) { return this; } return Rewrite(id, init); } } [VisitableNode(ChildProperties = new string[] { "Test", "Body" })] public sealed class WhileStatement : Statement { public Expression Test { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Statement Body { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public WhileStatement(Expression test, Statement body) : base(Nodes.WhileStatement) { Test = test; Body = body; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static WhileStatement Rewrite(Expression test, Statement body) { return new WhileStatement(test, body); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(Test, Body); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitWhileStatement(this); } public WhileStatement UpdateWith(Expression test, Statement body) { if (test == Test && body == Body) { return this; } return Rewrite(test, body); } } [VisitableNode(ChildProperties = new string[] { "Object", "Body" })] public sealed class WithStatement : Statement { public Expression Object { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Statement Body { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public WithStatement(Expression obj, Statement body) : base(Nodes.WithStatement) { Object = obj; Body = body; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static WithStatement Rewrite(Expression @object, Statement body) { return new WithStatement(@object, body); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(Object, Body); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitWithStatement(this); } public WithStatement UpdateWith(Expression @object, Statement body) { if (@object == Object && body == Body) { return this; } return Rewrite(@object, body); } } [VisitableNode(ChildProperties = new string[] { "Argument" })] public sealed class YieldExpression : Expression { public Expression? Argument { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public bool Delegate { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public YieldExpression(Expression? argument, bool @delegate) : base(Nodes.YieldExpression) { Argument = argument; Delegate = @delegate; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private YieldExpression Rewrite(Expression? argument) { return new YieldExpression(argument, Delegate); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNextNullable(Argument); } protected internal override object? Accept(AstVisitor visitor) { return visitor.VisitYieldExpression(this); } public YieldExpression UpdateWith(Expression? argument) { if (argument == Argument) { return this; } return Rewrite(argument); } } [AttributeUsage(AttributeTargets.Class, Inherited = false)] internal sealed class VisitableNodeAttribute : Attribute { public Type? VisitorType { get; set; } public string[]? ChildProperties { get; set; } public bool SealOverrideMethods { get; set; } } } namespace Esprima.Ast.Jsx { [VisitableNode(VisitorType = typeof(IJsxAstVisitor), ChildProperties = new string[] { "Name", "Value" })] public sealed class JsxAttribute : JsxExpression { public JsxExpression Name { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Expression? Value { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public JsxAttribute(JsxExpression name, Expression? value) : base(JsxNodeType.Attribute) { Name = name; Value = value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static JsxAttribute Rewrite(JsxExpression name, Expression? value) { return new JsxAttribute(name, value); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNextNullableAt1(Name, Value); } protected internal override object? Accept(IJsxAstVisitor visitor) { return visitor.VisitJsxAttribute(this); } public JsxAttribute UpdateWith(JsxExpression name, Expression? value) { if (name == Name && value == Value) { return this; } return Rewrite(name, value); } } [VisitableNode(VisitorType = typeof(IJsxAstVisitor), ChildProperties = new string[] { "Name" })] public sealed class JsxClosingElement : JsxExpression { public JsxExpression Name { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public JsxClosingElement(JsxExpression name) : base(JsxNodeType.ClosingElement) { Name = name; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static JsxClosingElement Rewrite(JsxExpression name) { return new JsxClosingElement(name); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(Name); } protected internal override object? Accept(IJsxAstVisitor visitor) { return visitor.VisitJsxClosingElement(this); } public JsxClosingElement UpdateWith(JsxExpression name) { if (name == Name) { return this; } return Rewrite(name); } } [VisitableNode(VisitorType = typeof(IJsxAstVisitor))] public sealed class JsxClosingFragment : JsxExpression { public JsxClosingFragment() : base(JsxNodeType.ClosingFragment) { } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return null; } protected internal override object? Accept(IJsxAstVisitor visitor) { return visitor.VisitJsxClosingFragment(this); } } [VisitableNode(VisitorType = typeof(IJsxAstVisitor), ChildProperties = new string[] { "OpeningElement", "Children", "ClosingElement" })] public sealed class JsxElement : JsxExpression { private readonly NodeList _children; public Node OpeningElement { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public Node? ClosingElement { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ref readonly NodeList Children { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _children; } } public JsxElement(Node openingElement, in NodeList children, Node? closingElement) : base(JsxNodeType.Element) { OpeningElement = openingElement; ClosingElement = closingElement; _children = children; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static JsxElement Rewrite(Node openingElement, in NodeList children, Node? closingElement) { return new JsxElement(openingElement, in children, closingElement); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNextNullableAt2(OpeningElement, in Children, ClosingElement); } protected internal override object? Accept(IJsxAstVisitor visitor) { return visitor.VisitJsxElement(this); } public JsxElement UpdateWith(Node openingElement, in NodeList children, Node? closingElement) { if (openingElement == OpeningElement && children.IsSameAs(in Children) && closingElement == ClosingElement) { return this; } return Rewrite(openingElement, in children, closingElement); } } [VisitableNode(VisitorType = typeof(IJsxAstVisitor))] public sealed class JsxEmptyExpression : JsxExpression { public JsxEmptyExpression() : base(JsxNodeType.EmptyExpression) { } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return null; } protected internal override object? Accept(IJsxAstVisitor visitor) { return visitor.VisitJsxEmptyExpression(this); } } public abstract class JsxExpression : Expression { private static readonly AstToJavaScriptOptions s_toStringOptions; public new JsxNodeType Type { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } protected JsxExpression(JsxNodeType type) : base(Nodes.Extension) { Type = type; } protected internal abstract object? Accept(IJsxAstVisitor visitor); protected internal sealed override object? Accept(AstVisitor visitor) { if (!(visitor is IJsxAstVisitor visitor2)) { return AcceptAsExtension(visitor); } return Accept(visitor2); } public override string ToString() { return this.ToJavaScriptString(KnRJavaScriptTextFormatterOptions.Default, s_toStringOptions); } private protected override string GetDebuggerDisplay() { return $"/*Jsx{Type}*/ {this}"; } static JsxExpression() { JsxAstToJavaScriptOptions obj = (JsxAstToJavaScriptOptions)JsxAstToJavaScriptOptions.Default.$(); obj.IgnoreExtensions = true; s_toStringOptions = obj; } } [VisitableNode(VisitorType = typeof(IJsxAstVisitor), ChildProperties = new string[] { "Expression" })] public sealed class JsxExpressionContainer : JsxExpression { public Expression Expression { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public JsxExpressionContainer(Expression expression) : base(JsxNodeType.ExpressionContainer) { Expression = expression; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static JsxExpressionContainer Rewrite(Expression expression) { return new JsxExpressionContainer(expression); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(Expression); } protected internal override object? Accept(IJsxAstVisitor visitor) { return visitor.VisitJsxExpressionContainer(this); } public JsxExpressionContainer UpdateWith(Expression expression) { if (expression == Expression) { return this; } return Rewrite(expression); } } [VisitableNode(VisitorType = typeof(IJsxAstVisitor))] public sealed class JsxIdentifier : JsxExpression { public string Name { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public JsxIdentifier(string name) : base(JsxNodeType.Identifier) { Name = name; } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return null; } protected internal override object? Accept(IJsxAstVisitor visitor) { return visitor.VisitJsxIdentifier(this); } } [VisitableNode(VisitorType = typeof(IJsxAstVisitor), ChildProperties = new string[] { "Object", "Property" })] public sealed class JsxMemberExpression : JsxExpression { public JsxExpression Object { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public JsxIdentifier Property { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public JsxMemberExpression(JsxExpression obj, JsxIdentifier property) : base(JsxNodeType.MemberExpression) { Object = obj; Property = property; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static JsxMemberExpression Rewrite(JsxExpression @object, JsxIdentifier property) { return new JsxMemberExpression(@object, property); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(Object, Property); } protected internal override object? Accept(IJsxAstVisitor visitor) { return visitor.VisitJsxMemberExpression(this); } public JsxMemberExpression UpdateWith(JsxExpression @object, JsxIdentifier property) { if (@object == Object && property == Property) { return this; } return Rewrite(@object, property); } } [VisitableNode(VisitorType = typeof(IJsxAstVisitor), ChildProperties = new string[] { "Name", "Namespace" })] public sealed class JsxNamespacedName : JsxExpression { public JsxIdentifier Namespace { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public JsxIdentifier Name { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public JsxNamespacedName(JsxIdentifier @namespace, JsxIdentifier name) : base(JsxNodeType.NamespacedName) { Namespace = @namespace; Name = name; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static JsxNamespacedName Rewrite(JsxIdentifier name, JsxIdentifier @namespace) { return new JsxNamespacedName(@namespace, name); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(Name, Namespace); } protected internal override object? Accept(IJsxAstVisitor visitor) { return visitor.VisitJsxNamespacedName(this); } public JsxNamespacedName UpdateWith(JsxIdentifier name, JsxIdentifier @namespace) { if (name == Name && @namespace == Namespace) { return this; } return Rewrite(name, @namespace); } } public enum JsxNodeType { Attribute, ClosingElement, ClosingFragment, Element, EmptyExpression, ExpressionContainer, Identifier, MemberExpression, NamespacedName, OpeningElement, OpeningFragment, SpreadAttribute, Text } [VisitableNode(VisitorType = typeof(IJsxAstVisitor), ChildProperties = new string[] { "Name", "Attributes" })] public sealed class JsxOpeningElement : JsxExpression { private readonly NodeList _attributes; public JsxExpression Name { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public bool SelfClosing { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public ref readonly NodeList Attributes { [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return ref _attributes; } } public JsxOpeningElement(JsxExpression name, bool selfClosing, in NodeList attributes) : base(JsxNodeType.OpeningElement) { Name = name; SelfClosing = selfClosing; _attributes = attributes; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private JsxOpeningElement Rewrite(JsxExpression name, in NodeList attributes) { return new JsxOpeningElement(name, SelfClosing, in attributes); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(Name, in Attributes); } protected internal override object? Accept(IJsxAstVisitor visitor) { return visitor.VisitJsxOpeningElement(this); } public JsxOpeningElement UpdateWith(JsxExpression name, in NodeList attributes) { if (name == Name && attributes.IsSameAs(in Attributes)) { return this; } return Rewrite(name, in attributes); } } [VisitableNode(VisitorType = typeof(IJsxAstVisitor))] public sealed class JsxOpeningFragment : JsxExpression { public bool SelfClosing { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public JsxOpeningFragment(bool selfClosing) : base(JsxNodeType.OpeningFragment) { SelfClosing = selfClosing; } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return null; } protected internal override object? Accept(IJsxAstVisitor visitor) { return visitor.VisitJsxOpeningFragment(this); } } [VisitableNode(VisitorType = typeof(IJsxAstVisitor), ChildProperties = new string[] { "Argument" })] public sealed class JsxSpreadAttribute : JsxExpression { public Expression Argument { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public JsxSpreadAttribute(Expression argument) : base(JsxNodeType.SpreadAttribute) { Argument = argument; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static JsxSpreadAttribute Rewrite(Expression argument) { return new JsxSpreadAttribute(argument); } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return enumerator.MoveNext(Argument); } protected internal override object? Accept(IJsxAstVisitor visitor) { return visitor.VisitJsxSpreadAttribute(this); } public JsxSpreadAttribute UpdateWith(Expression argument) { if (argument == Argument) { return this; } return Rewrite(argument); } } public sealed class JsxSyntaxToken : SyntaxToken { public new JsxTokenType Type { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public JsxSyntaxToken(JsxTokenType type, string value) : base(TokenType.Extension, value) { Type = type; } } [VisitableNode(VisitorType = typeof(IJsxAstVisitor))] public sealed class JsxText : JsxExpression { public string? Value { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public string Raw { [MethodImpl(MethodImplOptions.AggressiveInlining)] get; } public JsxText(string? value, string raw) : base(JsxNodeType.Text) { Value = value; Raw = raw; } internal override Node? NextChildNode(ref ChildNodes.Enumerator enumerator) { return null; } protected internal override object? Accept(IJsxAstVisitor visitor) { return visitor.VisitJsxText(this); } } }