@tracecode/harness 0.6.6 → 0.7.0-beta7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +48 -0
- package/README.md +134 -15
- package/THIRD_PARTY_NOTICES.md +170 -0
- package/dist/browser.cjs +2361 -1033
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +33 -3
- package/dist/browser.d.ts +33 -3
- package/dist/browser.js +2357 -1033
- package/dist/browser.js.map +1 -1
- package/dist/cli.cjs +160 -23
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +161 -24
- package/dist/cli.js.map +1 -1
- package/dist/core.cjs +748 -867
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +21 -85
- package/dist/core.d.ts +21 -85
- package/dist/core.js +734 -855
- package/dist/core.js.map +1 -1
- package/dist/cpp-worker-client-Bn7kC0_L.d.ts +84 -0
- package/dist/cpp-worker-client-BzdJLuZa.d.cts +84 -0
- package/dist/cpp.cjs +1063 -0
- package/dist/cpp.cjs.map +1 -0
- package/dist/cpp.d.cts +7 -0
- package/dist/cpp.d.ts +7 -0
- package/dist/cpp.js +1035 -0
- package/dist/cpp.js.map +1 -0
- package/dist/csharp-worker-client-DMHIa2YG.d.cts +69 -0
- package/dist/csharp-worker-client-JwqS6LiX.d.ts +69 -0
- package/dist/csharp.cjs +1012 -0
- package/dist/csharp.cjs.map +1 -0
- package/dist/csharp.d.cts +7 -0
- package/dist/csharp.d.ts +7 -0
- package/dist/csharp.js +984 -0
- package/dist/csharp.js.map +1 -0
- package/dist/index.cjs +3142 -1160
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -5
- package/dist/index.d.ts +13 -5
- package/dist/index.js +3117 -1148
- package/dist/index.js.map +1 -1
- package/dist/internal/browser.cjs +1639 -30
- package/dist/internal/browser.cjs.map +1 -1
- package/dist/internal/browser.d.cts +6 -199
- package/dist/internal/browser.d.ts +6 -199
- package/dist/internal/browser.js +1636 -30
- package/dist/internal/browser.js.map +1 -1
- package/dist/java-worker-client-BOwKW-11.d.cts +72 -0
- package/dist/java-worker-client-C97DDnCp.d.ts +72 -0
- package/dist/java.cjs +1225 -0
- package/dist/java.cjs.map +1 -0
- package/dist/java.d.cts +7 -0
- package/dist/java.d.ts +7 -0
- package/dist/java.js +1197 -0
- package/dist/java.js.map +1 -0
- package/dist/javascript-worker-client-CYBGEEvc.d.cts +51 -0
- package/dist/javascript-worker-client-DIX1Mp21.d.ts +51 -0
- package/dist/javascript.cjs +1063 -19
- package/dist/javascript.cjs.map +1 -1
- package/dist/javascript.d.cts +7 -4
- package/dist/javascript.d.ts +7 -4
- package/dist/javascript.js +1061 -19
- package/dist/javascript.js.map +1 -1
- package/dist/pyodide-worker-client-C-2rfHj9.d.ts +111 -0
- package/dist/pyodide-worker-client-Cn0a8Uv3.d.cts +111 -0
- package/dist/python.cjs +1282 -74
- package/dist/python.cjs.map +1 -1
- package/dist/python.d.cts +20 -14
- package/dist/python.d.ts +20 -14
- package/dist/python.js +1279 -74
- package/dist/python.js.map +1 -1
- package/dist/runtime-language-info-BFUSti3-.d.ts +43 -0
- package/dist/runtime-language-info-Bxza1cI2.d.cts +43 -0
- package/dist/runtime-types-2qM0MukN.d.cts +244 -0
- package/dist/runtime-types-2qM0MukN.d.ts +244 -0
- package/package.json +73 -8
- package/workers/cpp/cpp-compiler-frame.html +82 -0
- package/workers/cpp/cpp-compiler-worker.js +131 -0
- package/workers/cpp/cpp-worker.js +5790 -0
- package/workers/cpp/tracecode_runtime.hpp +6147 -0
- package/workers/csharp/csharp-worker.js +301 -0
- package/workers/java/.build/classes/harness/browser/JavaRewriteLibrary.class +0 -0
- package/workers/java/java-source-augmentations.js +880 -0
- package/workers/java/java-worker.js +2149 -178
- package/workers/java/src/harness/browser/JavaRewriteLibrary.java +1645 -32
- package/workers/java/src/javafx/util/Pair.java +42 -0
- package/workers/java/src/tracecode/browser/BrowserCompileAndTraceLibrary.java +714 -0
- package/workers/java/src/tracecode/browser/BrowserCompileAndTraceMain.java +76 -0
- package/workers/java/src/tracecode/browser/RuntimeProbeMain.java +14 -0
- package/workers/java/src/tracecode/user/TraceHooks.java +1406 -0
- package/workers/javascript/javascript-libraries-entry.js +71 -0
- package/workers/javascript/javascript-worker.js +2054 -424
- package/workers/python/generated-python-harness-snippets.js +4 -4
- package/workers/python/pyodide-worker.js +222 -61
- package/workers/python/runtime-core.js +1387 -301
- package/workers/vendor/csharp/.stamp +0 -0
- package/workers/vendor/csharp/TraceCode.CSharpHost.runtimeconfig.json +32 -0
- package/workers/vendor/csharp/_framework/Microsoft.CSharp.wasm +0 -0
- package/workers/vendor/csharp/_framework/Microsoft.CodeAnalysis.CSharp.wasm +0 -0
- package/workers/vendor/csharp/_framework/Microsoft.CodeAnalysis.wasm +0 -0
- package/workers/vendor/csharp/_framework/Microsoft.VisualBasic.Core.wasm +0 -0
- package/workers/vendor/csharp/_framework/Microsoft.VisualBasic.wasm +0 -0
- package/workers/vendor/csharp/_framework/Microsoft.Win32.Primitives.wasm +0 -0
- package/workers/vendor/csharp/_framework/Microsoft.Win32.Registry.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.AppContext.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Buffers.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Collections.Concurrent.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Collections.Immutable.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Collections.NonGeneric.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Collections.Specialized.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Collections.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.ComponentModel.Annotations.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.ComponentModel.DataAnnotations.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.ComponentModel.EventBasedAsync.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.ComponentModel.Primitives.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.ComponentModel.TypeConverter.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.ComponentModel.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Configuration.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Console.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Core.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Data.Common.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Data.DataSetExtensions.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Data.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Diagnostics.Contracts.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Diagnostics.Debug.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Diagnostics.DiagnosticSource.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Diagnostics.FileVersionInfo.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Diagnostics.Process.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Diagnostics.StackTrace.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Diagnostics.TextWriterTraceListener.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Diagnostics.Tools.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Diagnostics.TraceSource.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Diagnostics.Tracing.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Drawing.Primitives.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Drawing.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Dynamic.Runtime.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Formats.Asn1.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Formats.Tar.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Globalization.Calendars.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Globalization.Extensions.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Globalization.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.IO.Compression.Brotli.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.IO.Compression.FileSystem.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.IO.Compression.ZipFile.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.IO.Compression.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.IO.FileSystem.AccessControl.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.IO.FileSystem.DriveInfo.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.IO.FileSystem.Primitives.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.IO.FileSystem.Watcher.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.IO.FileSystem.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.IO.IsolatedStorage.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.IO.MemoryMappedFiles.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.IO.Pipelines.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.IO.Pipes.AccessControl.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.IO.Pipes.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.IO.UnmanagedMemoryStream.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.IO.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Linq.AsyncEnumerable.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Linq.Expressions.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Linq.Parallel.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Linq.Queryable.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Linq.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Memory.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.Http.Json.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.Http.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.HttpListener.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.Mail.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.NameResolution.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.NetworkInformation.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.Ping.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.Primitives.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.Quic.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.Requests.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.Security.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.ServerSentEvents.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.ServicePoint.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.Sockets.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.WebClient.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.WebHeaderCollection.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.WebProxy.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.WebSockets.Client.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.WebSockets.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Numerics.Vectors.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Numerics.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.ObjectModel.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Private.CoreLib.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Private.DataContractSerialization.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Private.Uri.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Private.Xml.Linq.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Private.Xml.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Reflection.DispatchProxy.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Reflection.Emit.ILGeneration.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Reflection.Emit.Lightweight.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Reflection.Emit.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Reflection.Extensions.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Reflection.Metadata.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Reflection.Primitives.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Reflection.TypeExtensions.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Reflection.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Resources.Reader.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Resources.ResourceManager.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Resources.Writer.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Runtime.CompilerServices.Unsafe.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Runtime.CompilerServices.VisualC.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Runtime.Extensions.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Runtime.Handles.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Runtime.InteropServices.JavaScript.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Runtime.InteropServices.RuntimeInformation.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Runtime.InteropServices.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Runtime.Intrinsics.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Runtime.Loader.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Runtime.Numerics.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Runtime.Serialization.Formatters.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Runtime.Serialization.Json.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Runtime.Serialization.Primitives.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Runtime.Serialization.Xml.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Runtime.Serialization.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Runtime.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Security.AccessControl.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Security.Claims.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Security.Cryptography.Algorithms.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Security.Cryptography.Cng.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Security.Cryptography.Csp.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Security.Cryptography.Encoding.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Security.Cryptography.OpenSsl.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Security.Cryptography.Primitives.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Security.Cryptography.X509Certificates.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Security.Cryptography.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Security.Principal.Windows.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Security.Principal.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Security.SecureString.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Security.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.ServiceModel.Web.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.ServiceProcess.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Text.Encoding.CodePages.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Text.Encoding.Extensions.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Text.Encoding.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Text.Encodings.Web.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Text.Json.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Text.RegularExpressions.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Threading.AccessControl.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Threading.Channels.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Threading.Overlapped.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Threading.Tasks.Dataflow.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Threading.Tasks.Extensions.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Threading.Tasks.Parallel.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Threading.Tasks.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Threading.Thread.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Threading.ThreadPool.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Threading.Timer.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Threading.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Transactions.Local.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Transactions.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.ValueTuple.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Web.HttpUtility.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Web.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Windows.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Xml.Linq.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Xml.ReaderWriter.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Xml.Serialization.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Xml.XDocument.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Xml.XPath.XDocument.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Xml.XPath.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Xml.XmlDocument.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Xml.XmlSerializer.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Xml.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.wasm +0 -0
- package/workers/vendor/csharp/_framework/TraceCode.CSharpHost.wasm +0 -0
- package/workers/vendor/csharp/_framework/WindowsBase.wasm +0 -0
- package/workers/vendor/csharp/_framework/cs/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/cs/Microsoft.CodeAnalysis.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/de/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/de/Microsoft.CodeAnalysis.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/dotnet.boot.js +1958 -0
- package/workers/vendor/csharp/_framework/dotnet.js +4 -0
- package/workers/vendor/csharp/_framework/dotnet.js.map +1 -0
- package/workers/vendor/csharp/_framework/dotnet.native.js +6687 -0
- package/workers/vendor/csharp/_framework/dotnet.native.wasm +0 -0
- package/workers/vendor/csharp/_framework/dotnet.runtime.js +4 -0
- package/workers/vendor/csharp/_framework/dotnet.runtime.js.map +1 -0
- package/workers/vendor/csharp/_framework/es/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/es/Microsoft.CodeAnalysis.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/fr/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/fr/Microsoft.CodeAnalysis.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/it/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/it/Microsoft.CodeAnalysis.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/ja/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/ja/Microsoft.CodeAnalysis.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/ko/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/ko/Microsoft.CodeAnalysis.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/mscorlib.wasm +0 -0
- package/workers/vendor/csharp/_framework/netstandard.wasm +0 -0
- package/workers/vendor/csharp/_framework/pl/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/pl/Microsoft.CodeAnalysis.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/pt-BR/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/pt-BR/Microsoft.CodeAnalysis.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/ru/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/ru/Microsoft.CodeAnalysis.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/0_Microsoft.CodeAnalysis.CSharp.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/100_System.Reflection.Emit.ILGeneration.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/101_System.Reflection.Emit.Lightweight.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/102_System.Reflection.Extensions.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/103_System.Reflection.Metadata.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/104_System.Reflection.Primitives.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/105_System.Reflection.TypeExtensions.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/106_System.Resources.Reader.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/107_System.Resources.ResourceManager.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/108_System.Resources.Writer.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/109_System.Runtime.CompilerServices.Unsafe.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/10_System.Buffers.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/110_System.Runtime.CompilerServices.VisualC.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/111_System.Runtime.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/112_System.Runtime.Extensions.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/113_System.Runtime.Handles.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/114_System.Runtime.InteropServices.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/115_System.Runtime.InteropServices.JavaScript.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/116_System.Runtime.InteropServices.RuntimeInformation.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/117_System.Runtime.Intrinsics.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/118_System.Runtime.Loader.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/119_System.Runtime.Numerics.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/11_System.Collections.Concurrent.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/120_System.Runtime.Serialization.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/121_System.Runtime.Serialization.Formatters.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/122_System.Runtime.Serialization.Json.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/123_System.Runtime.Serialization.Primitives.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/124_System.Runtime.Serialization.Xml.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/125_System.Security.AccessControl.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/126_System.Security.Claims.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/127_System.Security.Cryptography.Algorithms.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/128_System.Security.Cryptography.Cng.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/129_System.Security.Cryptography.Csp.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/12_System.Collections.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/130_System.Security.Cryptography.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/131_System.Security.Cryptography.Encoding.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/132_System.Security.Cryptography.OpenSsl.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/133_System.Security.Cryptography.Primitives.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/134_System.Security.Cryptography.X509Certificates.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/135_System.Security.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/136_System.Security.Principal.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/137_System.Security.Principal.Windows.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/138_System.Security.SecureString.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/139_System.ServiceModel.Web.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/13_System.Collections.Immutable.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/140_System.ServiceProcess.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/141_System.Text.Encoding.CodePages.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/142_System.Text.Encoding.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/143_System.Text.Encoding.Extensions.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/144_System.Text.Encodings.Web.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/145_System.Text.Json.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/146_System.Text.RegularExpressions.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/147_System.Threading.AccessControl.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/148_System.Threading.Channels.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/149_System.Threading.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/14_System.Collections.NonGeneric.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/150_System.Threading.Overlapped.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/151_System.Threading.Tasks.Dataflow.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/152_System.Threading.Tasks.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/153_System.Threading.Tasks.Extensions.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/154_System.Threading.Tasks.Parallel.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/155_System.Threading.Thread.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/156_System.Threading.ThreadPool.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/157_System.Threading.Timer.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/158_System.Transactions.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/159_System.Transactions.Local.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/15_System.Collections.Specialized.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/160_System.ValueTuple.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/161_System.Web.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/162_System.Web.HttpUtility.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/163_System.Windows.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/164_System.Xml.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/165_System.Xml.Linq.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/166_System.Xml.ReaderWriter.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/167_System.Xml.Serialization.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/168_System.Xml.XDocument.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/169_System.Xml.XmlDocument.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/16_System.ComponentModel.Annotations.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/170_System.Xml.XmlSerializer.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/171_System.Xml.XPath.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/172_System.Xml.XPath.XDocument.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/173_TraceCode.CSharpHost.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/174_WindowsBase.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/17_System.ComponentModel.DataAnnotations.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/18_System.ComponentModel.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/19_System.ComponentModel.EventBasedAsync.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/1_Microsoft.CodeAnalysis.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/20_System.ComponentModel.Primitives.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/21_System.ComponentModel.TypeConverter.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/22_System.Configuration.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/23_System.Console.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/24_System.Core.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/25_System.Data.Common.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/26_System.Data.DataSetExtensions.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/27_System.Data.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/28_System.Diagnostics.Contracts.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/29_System.Diagnostics.Debug.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/2_Microsoft.CSharp.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/30_System.Diagnostics.DiagnosticSource.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/31_System.Diagnostics.FileVersionInfo.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/32_System.Diagnostics.Process.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/33_System.Diagnostics.StackTrace.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/34_System.Diagnostics.TextWriterTraceListener.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/35_System.Diagnostics.Tools.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/36_System.Diagnostics.TraceSource.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/37_System.Diagnostics.Tracing.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/38_System.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/39_System.Drawing.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/3_Microsoft.VisualBasic.Core.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/40_System.Drawing.Primitives.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/41_System.Dynamic.Runtime.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/42_System.Formats.Asn1.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/43_System.Formats.Tar.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/44_System.Globalization.Calendars.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/45_System.Globalization.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/46_System.Globalization.Extensions.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/47_System.IO.Compression.Brotli.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/48_System.IO.Compression.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/49_System.IO.Compression.FileSystem.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/4_Microsoft.VisualBasic.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/50_System.IO.Compression.ZipFile.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/51_System.IO.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/52_System.IO.FileSystem.AccessControl.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/53_System.IO.FileSystem.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/54_System.IO.FileSystem.DriveInfo.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/55_System.IO.FileSystem.Primitives.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/56_System.IO.FileSystem.Watcher.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/57_System.IO.IsolatedStorage.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/58_System.IO.MemoryMappedFiles.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/59_System.IO.Pipelines.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/5_Microsoft.Win32.Primitives.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/60_System.IO.Pipes.AccessControl.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/61_System.IO.Pipes.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/62_System.IO.UnmanagedMemoryStream.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/63_System.Linq.AsyncEnumerable.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/64_System.Linq.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/65_System.Linq.Expressions.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/66_System.Linq.Parallel.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/67_System.Linq.Queryable.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/68_System.Memory.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/69_System.Net.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/6_Microsoft.Win32.Registry.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/70_System.Net.Http.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/71_System.Net.Http.Json.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/72_System.Net.HttpListener.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/73_System.Net.Mail.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/74_System.Net.NameResolution.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/75_System.Net.NetworkInformation.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/76_System.Net.Ping.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/77_System.Net.Primitives.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/78_System.Net.Quic.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/79_System.Net.Requests.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/7_mscorlib.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/80_System.Net.Security.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/81_System.Net.ServerSentEvents.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/82_System.Net.ServicePoint.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/83_System.Net.Sockets.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/84_System.Net.WebClient.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/85_System.Net.WebHeaderCollection.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/86_System.Net.WebProxy.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/87_System.Net.WebSockets.Client.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/88_System.Net.WebSockets.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/89_System.Numerics.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/8_netstandard.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/90_System.Numerics.Vectors.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/91_System.ObjectModel.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/92_System.Private.CoreLib.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/93_System.Private.DataContractSerialization.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/94_System.Private.Uri.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/95_System.Private.Xml.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/96_System.Private.Xml.Linq.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/97_System.Reflection.DispatchProxy.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/98_System.Reflection.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/99_System.Reflection.Emit.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/9_System.AppContext.dll +0 -0
- package/workers/vendor/csharp/_framework/tr/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/tr/Microsoft.CodeAnalysis.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/zh-Hans/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/zh-Hans/Microsoft.CodeAnalysis.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/zh-Hant/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/zh-Hant/Microsoft.CodeAnalysis.resources.wasm +0 -0
- package/workers/vendor/csharp/main.mjs +5 -0
- package/workers/vendor/csharp/package.json +1 -0
- package/workers/vendor/java-browser-helper.jar +0 -0
- package/workers/vendor/java-rewriter.jar +0 -0
- package/workers/vendor/javascript-libraries.js +10106 -0
- package/dist/runtime-types-89nchXlY.d.cts +0 -89
- package/dist/runtime-types-CCQ-ZLc9.d.ts +0 -89
- package/dist/types-zyvpJKCi.d.cts +0 -100
- package/dist/types-zyvpJKCi.d.ts +0 -100
- package/workers/java/java-source-augmentations.cjs +0 -242
- package/workers/java/src/spike/user/TraceHooks.java +0 -619
- package/workers/vendor/java-browser-spike-helper.jar +0 -0
- package/workers/vendor/java-practice-rewriter.jar +0 -0
- package/workers/vendor/java-rewrite-bridge.jar +0 -0
|
@@ -14,6 +14,20 @@ const WORKER_DEBUG = (() => {
|
|
|
14
14
|
}
|
|
15
15
|
})();
|
|
16
16
|
|
|
17
|
+
function emitRuntimeDiagnostic(level, phase, message, detail) {
|
|
18
|
+
if (!WORKER_DEBUG && level !== 'error') return;
|
|
19
|
+
const method = level === 'error' ? 'error' : level === 'warn' ? 'warn' : level === 'debug' ? 'debug' : 'info';
|
|
20
|
+
console[method]('[TraceRuntime]', {
|
|
21
|
+
schema: 'tracecode.runtime-diagnostic.v1',
|
|
22
|
+
source: 'harness',
|
|
23
|
+
component: 'JavaScriptWorker',
|
|
24
|
+
runtime: 'javascript',
|
|
25
|
+
phase,
|
|
26
|
+
message,
|
|
27
|
+
...(detail === undefined ? {} : { detail }),
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
17
31
|
let isInitialized = false;
|
|
18
32
|
let isLoading = false;
|
|
19
33
|
let typeScriptLoadPromise = null;
|
|
@@ -28,12 +42,23 @@ const TYPESCRIPT_COMPILER_URLS = [
|
|
|
28
42
|
'https://cdn.jsdelivr.net/npm/typescript@5.9.2/lib/typescript.js',
|
|
29
43
|
'https://unpkg.com/typescript@5.9.2/lib/typescript.js',
|
|
30
44
|
];
|
|
45
|
+
const JAVASCRIPT_LIBRARY_URLS = [
|
|
46
|
+
'./vendor/javascript-libraries.js',
|
|
47
|
+
];
|
|
48
|
+
let javascriptLibrariesLoadAttempted = false;
|
|
31
49
|
|
|
32
50
|
const JAVASCRIPT_RUNTIME_PRELUDE = `
|
|
51
|
+
if (typeof globalThis.module === 'undefined') {
|
|
52
|
+
globalThis.module = { exports: {} };
|
|
53
|
+
}
|
|
54
|
+
if (typeof globalThis.exports === 'undefined') {
|
|
55
|
+
globalThis.exports = globalThis.module.exports || {};
|
|
56
|
+
}
|
|
33
57
|
if (typeof globalThis.ListNode !== 'function') {
|
|
34
58
|
globalThis.ListNode = class ListNode {
|
|
35
59
|
constructor(val = 0, next = null) {
|
|
36
60
|
this.val = val;
|
|
61
|
+
this.value = val;
|
|
37
62
|
this.next = next;
|
|
38
63
|
}
|
|
39
64
|
};
|
|
@@ -42,6 +67,7 @@ if (typeof globalThis.TreeNode !== 'function') {
|
|
|
42
67
|
globalThis.TreeNode = class TreeNode {
|
|
43
68
|
constructor(val = 0, left = null, right = null) {
|
|
44
69
|
this.val = val;
|
|
70
|
+
this.value = val;
|
|
45
71
|
this.left = left;
|
|
46
72
|
this.right = right;
|
|
47
73
|
}
|
|
@@ -49,9 +75,45 @@ if (typeof globalThis.TreeNode !== 'function') {
|
|
|
49
75
|
}
|
|
50
76
|
`;
|
|
51
77
|
|
|
78
|
+
function ensureJavaScriptLibraries() {
|
|
79
|
+
if (
|
|
80
|
+
typeof globalThis !== 'undefined' &&
|
|
81
|
+
globalThis.__TRACECODE_JAVASCRIPT_LIBRARIES__ &&
|
|
82
|
+
typeof globalThis.require === 'function'
|
|
83
|
+
) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (javascriptLibrariesLoadAttempted) return;
|
|
87
|
+
javascriptLibrariesLoadAttempted = true;
|
|
88
|
+
if (typeof importScripts !== 'function') return;
|
|
89
|
+
|
|
90
|
+
const errors = [];
|
|
91
|
+
for (const libraryUrl of JAVASCRIPT_LIBRARY_URLS) {
|
|
92
|
+
try {
|
|
93
|
+
importScripts(libraryUrl);
|
|
94
|
+
if (
|
|
95
|
+
typeof globalThis !== 'undefined' &&
|
|
96
|
+
globalThis.__TRACECODE_JAVASCRIPT_LIBRARIES__ &&
|
|
97
|
+
typeof globalThis.require === 'function'
|
|
98
|
+
) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
errors.push(`${libraryUrl} (loaded but module registry was missing)`);
|
|
102
|
+
} catch (error) {
|
|
103
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
104
|
+
errors.push(`${libraryUrl} (${message})`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (errors.length > 0) {
|
|
109
|
+
emitRuntimeDiagnostic('warn', 'library-preload-skipped', 'JavaScript library preload skipped.', { errors });
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
52
113
|
const TYPESCRIPT_RUNTIME_DECLARATIONS = `
|
|
53
114
|
declare class ListNode {
|
|
54
115
|
val: any;
|
|
116
|
+
value: any;
|
|
55
117
|
next: ListNode | SerializedListNode | SerializedRef | null;
|
|
56
118
|
prev?: ListNode | SerializedListNode | SerializedRef | null;
|
|
57
119
|
constructor(val?: any, next?: ListNode | null);
|
|
@@ -59,6 +121,7 @@ declare class ListNode {
|
|
|
59
121
|
|
|
60
122
|
declare class TreeNode {
|
|
61
123
|
val: any;
|
|
124
|
+
value: any;
|
|
62
125
|
left: TreeNode | SerializedTreeNode | SerializedRef | null;
|
|
63
126
|
right: TreeNode | SerializedTreeNode | SerializedRef | null;
|
|
64
127
|
constructor(val?: any, left?: TreeNode | null, right?: TreeNode | null);
|
|
@@ -70,6 +133,7 @@ type SerializedListNode = {
|
|
|
70
133
|
__id__?: string;
|
|
71
134
|
__type__?: 'ListNode';
|
|
72
135
|
val?: any;
|
|
136
|
+
value?: any;
|
|
73
137
|
next?: SerializedListNode | SerializedRef | ListNode | null;
|
|
74
138
|
prev?: SerializedListNode | SerializedRef | ListNode | null;
|
|
75
139
|
};
|
|
@@ -78,11 +142,48 @@ type SerializedTreeNode = {
|
|
|
78
142
|
__id__?: string;
|
|
79
143
|
__type__?: 'TreeNode';
|
|
80
144
|
val?: any;
|
|
145
|
+
value?: any;
|
|
81
146
|
left?: SerializedTreeNode | SerializedRef | TreeNode | null;
|
|
82
147
|
right?: SerializedTreeNode | SerializedRef | TreeNode | null;
|
|
83
148
|
};
|
|
84
149
|
`;
|
|
85
150
|
|
|
151
|
+
const CUSTOM_OBJECT_MATERIALIZER_SOURCE = `
|
|
152
|
+
function __tracecodeMaterializeCustomObject(value) {
|
|
153
|
+
if (value === null || value === undefined) return value;
|
|
154
|
+
if (Array.isArray(value)) return value.map((item) => __tracecodeMaterializeCustomObject(item));
|
|
155
|
+
if (typeof value !== 'object') return value;
|
|
156
|
+
if (value.__type__ === 'TreeNode' || value.__type__ === 'ListNode' || value.__ref__) return value;
|
|
157
|
+
const __typeName = typeof value.__type__ === 'string'
|
|
158
|
+
? value.__type__
|
|
159
|
+
: (typeof value.__class__ === 'string' ? value.__class__ : null);
|
|
160
|
+
if (!__typeName) return value;
|
|
161
|
+
const __fields = { __type__: __typeName };
|
|
162
|
+
if (typeof value.__class__ === 'string') __fields.__class__ = value.__class__;
|
|
163
|
+
for (const [__key, __child] of Object.entries(value)) {
|
|
164
|
+
if (__key === '__type__' || __key === '__class__' || __key === '__id__') continue;
|
|
165
|
+
__fields[__key] = __tracecodeMaterializeCustomObject(__child);
|
|
166
|
+
}
|
|
167
|
+
let __ctor;
|
|
168
|
+
try {
|
|
169
|
+
__ctor = eval(__typeName);
|
|
170
|
+
} catch (_err) {
|
|
171
|
+
__ctor = undefined;
|
|
172
|
+
}
|
|
173
|
+
if (typeof __ctor !== 'function') return __fields;
|
|
174
|
+
const __args = Object.entries(__fields)
|
|
175
|
+
.filter(([__key]) => __key !== '__type__' && __key !== '__class__')
|
|
176
|
+
.map(([, __value]) => __value);
|
|
177
|
+
try {
|
|
178
|
+
return new __ctor(...__args);
|
|
179
|
+
} catch (_err) {
|
|
180
|
+
const __instance = Object.create(__ctor.prototype);
|
|
181
|
+
Object.assign(__instance, __fields);
|
|
182
|
+
return __instance;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
`;
|
|
186
|
+
|
|
86
187
|
function performanceNow() {
|
|
87
188
|
if (typeof performance !== 'undefined' && typeof performance.now === 'function') {
|
|
88
189
|
return performance.now();
|
|
@@ -139,17 +240,41 @@ function getCustomClassName(value) {
|
|
|
139
240
|
return name;
|
|
140
241
|
}
|
|
141
242
|
|
|
243
|
+
const RUNTIME_VALUE_MAX_DEPTH = 48;
|
|
244
|
+
const RUNTIME_VALUE_MAX_ITEMS = 64;
|
|
245
|
+
const RUNTIME_VALUE_MAX_OBJECT_FIELDS = 32;
|
|
246
|
+
const TRACE_SERIALIZATION_LIMITS = { maxItems: RUNTIME_VALUE_MAX_ITEMS, maxFields: RUNTIME_VALUE_MAX_OBJECT_FIELDS };
|
|
247
|
+
const OUTPUT_SERIALIZATION_LIMITS = { maxItems: Number.POSITIVE_INFINITY, maxFields: Number.POSITIVE_INFINITY };
|
|
248
|
+
let activeSerializationLimits = TRACE_SERIALIZATION_LIMITS;
|
|
249
|
+
|
|
250
|
+
function truncationMarker(total, emitted) {
|
|
251
|
+
return { __truncated__: true, remaining: Math.max(0, total - emitted) };
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function limitedEntries(items, maxItems) {
|
|
255
|
+
return {
|
|
256
|
+
values: items.slice(0, maxItems),
|
|
257
|
+
remaining: Math.max(0, items.length - maxItems),
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
|
|
142
261
|
function serializeValue(
|
|
143
262
|
value,
|
|
144
263
|
depth = 0,
|
|
145
264
|
seen = new WeakSet(),
|
|
146
265
|
nodeRefState = { ids: new Map(), nextId: 1 }
|
|
147
266
|
) {
|
|
148
|
-
if (depth >
|
|
267
|
+
if (depth > RUNTIME_VALUE_MAX_DEPTH) return '<max depth>';
|
|
149
268
|
if (value === null || value === undefined) return value;
|
|
150
269
|
|
|
151
270
|
const valueType = typeof value;
|
|
152
|
-
if (valueType === '
|
|
271
|
+
if (valueType === 'number') {
|
|
272
|
+
if (Number.isNaN(value)) return 'NaN';
|
|
273
|
+
if (value === Infinity) return 'Infinity';
|
|
274
|
+
if (value === -Infinity) return '-Infinity';
|
|
275
|
+
return value;
|
|
276
|
+
}
|
|
277
|
+
if (valueType === 'string' || valueType === 'boolean') {
|
|
153
278
|
return value;
|
|
154
279
|
}
|
|
155
280
|
if (valueType === 'bigint') {
|
|
@@ -159,22 +284,39 @@ function serializeValue(
|
|
|
159
284
|
return '<function>';
|
|
160
285
|
}
|
|
161
286
|
if (Array.isArray(value)) {
|
|
162
|
-
|
|
287
|
+
const limited = limitedEntries(value, activeSerializationLimits.maxItems);
|
|
288
|
+
const result = limited.values.map((item) => serializeValue(item, depth + 1, seen, nodeRefState));
|
|
289
|
+
if (limited.remaining > 0) result.push(truncationMarker(value.length, limited.values.length));
|
|
290
|
+
return result;
|
|
163
291
|
}
|
|
164
292
|
if (value instanceof Set) {
|
|
165
|
-
|
|
293
|
+
const items = [...value];
|
|
294
|
+
const limited = limitedEntries(items, activeSerializationLimits.maxItems);
|
|
295
|
+
const result = {
|
|
166
296
|
__type__: 'set',
|
|
167
|
-
values:
|
|
297
|
+
values: limited.values.map((item) => serializeValue(item, depth + 1, seen, nodeRefState)),
|
|
168
298
|
};
|
|
299
|
+
if (limited.remaining > 0) {
|
|
300
|
+
result.__truncated__ = true;
|
|
301
|
+
result.remaining = limited.remaining;
|
|
302
|
+
}
|
|
303
|
+
return result;
|
|
169
304
|
}
|
|
170
305
|
if (value instanceof Map) {
|
|
171
|
-
|
|
306
|
+
const entries = [...value.entries()];
|
|
307
|
+
const limited = limitedEntries(entries, activeSerializationLimits.maxItems);
|
|
308
|
+
const result = {
|
|
172
309
|
__type__: 'map',
|
|
173
|
-
entries:
|
|
310
|
+
entries: limited.values.map(([k, v]) => [
|
|
174
311
|
serializeValue(k, depth + 1, seen, nodeRefState),
|
|
175
312
|
serializeValue(v, depth + 1, seen, nodeRefState),
|
|
176
313
|
]),
|
|
177
314
|
};
|
|
315
|
+
if (limited.remaining > 0) {
|
|
316
|
+
result.__truncated__ = true;
|
|
317
|
+
result.remaining = limited.remaining;
|
|
318
|
+
}
|
|
319
|
+
return result;
|
|
178
320
|
}
|
|
179
321
|
if (valueType === 'object') {
|
|
180
322
|
if (isLikelyTreeNodeValue(value) || isLikelyListNodeValue(value)) {
|
|
@@ -182,12 +324,12 @@ function serializeValue(
|
|
|
182
324
|
if (existingId) {
|
|
183
325
|
return { __ref__: existingId };
|
|
184
326
|
}
|
|
185
|
-
const
|
|
186
|
-
const nodeId =
|
|
327
|
+
const isTree = isLikelyTreeNodeValue(value);
|
|
328
|
+
const nodeId = `ref-${nodeRefState.nextId++}`;
|
|
187
329
|
nodeRefState.ids.set(value, nodeId);
|
|
188
330
|
|
|
189
331
|
const out =
|
|
190
|
-
|
|
332
|
+
isTree
|
|
191
333
|
? {
|
|
192
334
|
__type__: 'TreeNode',
|
|
193
335
|
__id__: nodeId,
|
|
@@ -205,13 +347,17 @@ function serializeValue(
|
|
|
205
347
|
: {}),
|
|
206
348
|
};
|
|
207
349
|
const skipped =
|
|
208
|
-
|
|
350
|
+
isTree
|
|
209
351
|
? new Set(['__id__', '__type__', '__class__', 'val', 'value', 'left', 'right'])
|
|
210
352
|
: new Set(['__id__', '__type__', '__class__', 'val', 'value', 'next', 'prev']);
|
|
211
|
-
|
|
212
|
-
|
|
353
|
+
const fields = Object.entries(value).filter(([k]) => !skipped.has(k));
|
|
354
|
+
for (const [k, v] of fields.slice(0, activeSerializationLimits.maxFields)) {
|
|
213
355
|
out[k] = serializeValue(v, depth + 1, seen, nodeRefState);
|
|
214
356
|
}
|
|
357
|
+
if (fields.length > activeSerializationLimits.maxFields) {
|
|
358
|
+
out.__truncated__ = true;
|
|
359
|
+
out.remaining = fields.length - activeSerializationLimits.maxFields;
|
|
360
|
+
}
|
|
215
361
|
return out;
|
|
216
362
|
}
|
|
217
363
|
|
|
@@ -222,19 +368,24 @@ function serializeValue(
|
|
|
222
368
|
return { __ref__: existingId };
|
|
223
369
|
}
|
|
224
370
|
|
|
225
|
-
const objectId = `
|
|
371
|
+
const objectId = `ref-${nodeRefState.nextId++}`;
|
|
226
372
|
nodeRefState.ids.set(value, objectId);
|
|
227
373
|
|
|
228
374
|
if (seen.has(value)) return { __ref__: objectId };
|
|
229
375
|
seen.add(value);
|
|
230
376
|
const out = {
|
|
231
|
-
__type__:
|
|
377
|
+
__type__: customClassName,
|
|
232
378
|
__class__: customClassName,
|
|
233
379
|
__id__: objectId,
|
|
234
380
|
};
|
|
235
|
-
|
|
381
|
+
const fields = Object.entries(value);
|
|
382
|
+
for (const [k, v] of fields.slice(0, activeSerializationLimits.maxFields)) {
|
|
236
383
|
out[k] = serializeValue(v, depth + 1, seen, nodeRefState);
|
|
237
384
|
}
|
|
385
|
+
if (fields.length > activeSerializationLimits.maxFields) {
|
|
386
|
+
out.__truncated__ = true;
|
|
387
|
+
out.remaining = fields.length - activeSerializationLimits.maxFields;
|
|
388
|
+
}
|
|
238
389
|
seen.delete(value);
|
|
239
390
|
return out;
|
|
240
391
|
}
|
|
@@ -242,9 +393,14 @@ function serializeValue(
|
|
|
242
393
|
if (seen.has(value)) return '<cycle>';
|
|
243
394
|
seen.add(value);
|
|
244
395
|
const out = {};
|
|
245
|
-
|
|
396
|
+
const fields = Object.entries(value);
|
|
397
|
+
for (const [k, v] of fields.slice(0, activeSerializationLimits.maxFields)) {
|
|
246
398
|
out[k] = serializeValue(v, depth + 1, seen, nodeRefState);
|
|
247
399
|
}
|
|
400
|
+
if (fields.length > activeSerializationLimits.maxFields) {
|
|
401
|
+
out.__truncated__ = true;
|
|
402
|
+
out.remaining = fields.length - activeSerializationLimits.maxFields;
|
|
403
|
+
}
|
|
248
404
|
seen.delete(value);
|
|
249
405
|
return out;
|
|
250
406
|
}
|
|
@@ -252,6 +408,20 @@ function serializeValue(
|
|
|
252
408
|
return String(value);
|
|
253
409
|
}
|
|
254
410
|
|
|
411
|
+
function withSerializationLimits(limits, serialize) {
|
|
412
|
+
const previous = activeSerializationLimits;
|
|
413
|
+
activeSerializationLimits = limits;
|
|
414
|
+
try {
|
|
415
|
+
return serialize();
|
|
416
|
+
} finally {
|
|
417
|
+
activeSerializationLimits = previous;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
function serializeOutputValue(value) {
|
|
422
|
+
return withSerializationLimits(OUTPUT_SERIALIZATION_LIMITS, () => serializeValue(value));
|
|
423
|
+
}
|
|
424
|
+
|
|
255
425
|
function serializeTopLevelValue(value, nodeRefState) {
|
|
256
426
|
if (value === null || value === undefined) return value;
|
|
257
427
|
if (typeof value !== 'object' || Array.isArray(value)) {
|
|
@@ -264,7 +434,7 @@ function serializeTopLevelValue(value, nodeRefState) {
|
|
|
264
434
|
const isTree = isLikelyTreeNodeValue(value);
|
|
265
435
|
let nodeId = nodeRefState.ids.get(objectValue);
|
|
266
436
|
if (!nodeId) {
|
|
267
|
-
nodeId =
|
|
437
|
+
nodeId = `ref-${nodeRefState.nextId++}`;
|
|
268
438
|
nodeRefState.ids.set(objectValue, nodeId);
|
|
269
439
|
}
|
|
270
440
|
|
|
@@ -289,10 +459,14 @@ function serializeTopLevelValue(value, nodeRefState) {
|
|
|
289
459
|
const skipped = isTree
|
|
290
460
|
? new Set(['__id__', '__type__', '__class__', 'val', 'value', 'left', 'right'])
|
|
291
461
|
: new Set(['__id__', '__type__', '__class__', 'val', 'value', 'next', 'prev']);
|
|
292
|
-
|
|
293
|
-
|
|
462
|
+
const fields = Object.entries(nodeValue).filter(([k]) => !skipped.has(k));
|
|
463
|
+
for (const [k, v] of fields.slice(0, activeSerializationLimits.maxFields)) {
|
|
294
464
|
out[k] = serializeValue(v, 1, new WeakSet(), nodeRefState);
|
|
295
465
|
}
|
|
466
|
+
if (fields.length > activeSerializationLimits.maxFields) {
|
|
467
|
+
out.__truncated__ = true;
|
|
468
|
+
out.remaining = fields.length - activeSerializationLimits.maxFields;
|
|
469
|
+
}
|
|
296
470
|
return out;
|
|
297
471
|
}
|
|
298
472
|
|
|
@@ -301,7 +475,7 @@ function serializeTopLevelValue(value, nodeRefState) {
|
|
|
301
475
|
const objectValue = value;
|
|
302
476
|
let objectId = nodeRefState.ids.get(objectValue);
|
|
303
477
|
if (!objectId) {
|
|
304
|
-
objectId = `
|
|
478
|
+
objectId = `ref-${nodeRefState.nextId++}`;
|
|
305
479
|
nodeRefState.ids.set(objectValue, objectId);
|
|
306
480
|
}
|
|
307
481
|
const seen = new WeakSet();
|
|
@@ -311,9 +485,14 @@ function serializeTopLevelValue(value, nodeRefState) {
|
|
|
311
485
|
__class__: customClassName,
|
|
312
486
|
__id__: objectId,
|
|
313
487
|
};
|
|
314
|
-
|
|
488
|
+
const fields = Object.entries(value);
|
|
489
|
+
for (const [k, v] of fields.slice(0, activeSerializationLimits.maxFields)) {
|
|
315
490
|
out[k] = serializeValue(v, 1, seen, nodeRefState);
|
|
316
491
|
}
|
|
492
|
+
if (fields.length > activeSerializationLimits.maxFields) {
|
|
493
|
+
out.__truncated__ = true;
|
|
494
|
+
out.remaining = fields.length - activeSerializationLimits.maxFields;
|
|
495
|
+
}
|
|
317
496
|
return out;
|
|
318
497
|
}
|
|
319
498
|
|
|
@@ -398,16 +577,45 @@ function resolveReferenceGraph(value, byId, resolved) {
|
|
|
398
577
|
return out;
|
|
399
578
|
}
|
|
400
579
|
|
|
580
|
+
function cloneInputGraph(value, cloned = new WeakMap()) {
|
|
581
|
+
if (value === null || value === undefined) return value;
|
|
582
|
+
if (typeof value !== 'object') return value;
|
|
583
|
+
|
|
584
|
+
if (cloned.has(value)) {
|
|
585
|
+
return cloned.get(value);
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
if (Array.isArray(value)) {
|
|
589
|
+
const out = [];
|
|
590
|
+
cloned.set(value, out);
|
|
591
|
+
for (const item of value) {
|
|
592
|
+
out.push(cloneInputGraph(item, cloned));
|
|
593
|
+
}
|
|
594
|
+
return out;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
if (!isPlainObjectRecord(value)) {
|
|
598
|
+
return value;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
const out = {};
|
|
602
|
+
cloned.set(value, out);
|
|
603
|
+
for (const [key, nested] of Object.entries(value)) {
|
|
604
|
+
out[key] = cloneInputGraph(nested, cloned);
|
|
605
|
+
}
|
|
606
|
+
return out;
|
|
607
|
+
}
|
|
608
|
+
|
|
401
609
|
function normalizeInputs(inputs) {
|
|
402
610
|
if (!inputs || typeof inputs !== 'object' || Array.isArray(inputs)) return {};
|
|
403
611
|
const byId = new Map();
|
|
404
612
|
collectReferenceTargets(inputs, byId, new WeakSet());
|
|
405
613
|
if (byId.size === 0) {
|
|
406
|
-
return inputs;
|
|
614
|
+
return cloneInputGraph(inputs);
|
|
407
615
|
}
|
|
408
616
|
const hydrated = resolveReferenceGraph(inputs, byId, new WeakMap());
|
|
409
617
|
if (!hydrated || typeof hydrated !== 'object' || Array.isArray(hydrated)) {
|
|
410
|
-
return inputs;
|
|
618
|
+
return cloneInputGraph(inputs);
|
|
411
619
|
}
|
|
412
620
|
return hydrated;
|
|
413
621
|
}
|
|
@@ -675,12 +883,168 @@ function findFunctionLikeNode(ts, sourceFile, functionName, executionStyle) {
|
|
|
675
883
|
return found;
|
|
676
884
|
}
|
|
677
885
|
|
|
886
|
+
function escapeRegExp(value) {
|
|
887
|
+
return String(value).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
function stripJavaScriptTriviaForSignatureScan(code) {
|
|
891
|
+
let output = '';
|
|
892
|
+
let i = 0;
|
|
893
|
+
|
|
894
|
+
while (i < code.length) {
|
|
895
|
+
const current = code[i];
|
|
896
|
+
const next = code[i + 1];
|
|
897
|
+
|
|
898
|
+
if (current === '/' && next === '/') {
|
|
899
|
+
output += ' ';
|
|
900
|
+
i += 2;
|
|
901
|
+
while (i < code.length && code[i] !== '\n') {
|
|
902
|
+
output += ' ';
|
|
903
|
+
i += 1;
|
|
904
|
+
}
|
|
905
|
+
continue;
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
if (current === '/' && next === '*') {
|
|
909
|
+
output += ' ';
|
|
910
|
+
i += 2;
|
|
911
|
+
while (i < code.length) {
|
|
912
|
+
if (code[i] === '*' && code[i + 1] === '/') {
|
|
913
|
+
output += ' ';
|
|
914
|
+
i += 2;
|
|
915
|
+
break;
|
|
916
|
+
}
|
|
917
|
+
output += code[i] === '\n' ? '\n' : ' ';
|
|
918
|
+
i += 1;
|
|
919
|
+
}
|
|
920
|
+
continue;
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
if (current === '"' || current === "'" || current === '`') {
|
|
924
|
+
const quote = current;
|
|
925
|
+
output += quote;
|
|
926
|
+
i += 1;
|
|
927
|
+
while (i < code.length) {
|
|
928
|
+
const char = code[i];
|
|
929
|
+
if (char === '\\') {
|
|
930
|
+
output += ' ';
|
|
931
|
+
if (i + 1 < code.length) output += code[i + 1] === '\n' ? '\n' : ' ';
|
|
932
|
+
i += 2;
|
|
933
|
+
continue;
|
|
934
|
+
}
|
|
935
|
+
output += char === '\n' ? '\n' : ' ';
|
|
936
|
+
i += 1;
|
|
937
|
+
if (char === quote) break;
|
|
938
|
+
}
|
|
939
|
+
continue;
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
output += current;
|
|
943
|
+
i += 1;
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
return output;
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
function findMatchingBraceIndex(code, openBraceIndex) {
|
|
950
|
+
let depth = 0;
|
|
951
|
+
for (let i = openBraceIndex; i < code.length; i += 1) {
|
|
952
|
+
const char = code[i];
|
|
953
|
+
if (char === '{') {
|
|
954
|
+
depth += 1;
|
|
955
|
+
} else if (char === '}') {
|
|
956
|
+
depth -= 1;
|
|
957
|
+
if (depth === 0) return i;
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
return -1;
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
function extractClassBodyForSignatureScan(code, className) {
|
|
964
|
+
const classMatch = new RegExp(`\\bclass\\s+${escapeRegExp(className)}\\b[^{}]*\\{`, 'm').exec(code);
|
|
965
|
+
if (!classMatch) return null;
|
|
966
|
+
const openBraceIndex = classMatch.index + classMatch[0].lastIndexOf('{');
|
|
967
|
+
const closeBraceIndex = findMatchingBraceIndex(code, openBraceIndex);
|
|
968
|
+
if (closeBraceIndex < 0) return null;
|
|
969
|
+
return code.slice(openBraceIndex + 1, closeBraceIndex);
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
function parseSimpleJavaScriptParameterNames(parameterText) {
|
|
973
|
+
const names = [];
|
|
974
|
+
const rawParameters = String(parameterText ?? '').split(',');
|
|
975
|
+
|
|
976
|
+
for (const rawParameter of rawParameters) {
|
|
977
|
+
const trimmed = rawParameter.trim();
|
|
978
|
+
if (!trimmed) continue;
|
|
979
|
+
const withoutDefault = trimmed.split('=')[0].trim();
|
|
980
|
+
const name = withoutDefault.startsWith('...') ? withoutDefault.slice(3).trim() : withoutDefault;
|
|
981
|
+
if (name === 'this') continue;
|
|
982
|
+
if (!/^[A-Za-z_$][\w$]*$/.test(name)) {
|
|
983
|
+
return null;
|
|
984
|
+
}
|
|
985
|
+
names.push(name);
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
return names;
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
function extractSimpleJavaScriptParameterNames(code, functionName, executionStyle) {
|
|
992
|
+
const strippedCode = stripJavaScriptTriviaForSignatureScan(code);
|
|
993
|
+
const escapedName = escapeRegExp(functionName);
|
|
994
|
+
const exportPrefix = String.raw`(?:export\s+default\s+|export\s+)?`;
|
|
995
|
+
const functionPatterns = [
|
|
996
|
+
new RegExp(String.raw`(?:^|[^\w$])${exportPrefix}(?:async\s+)?function\s+${escapedName}\s*\(([^)]*)\)`, 'm'),
|
|
997
|
+
new RegExp(String.raw`(?:^|[^\w$])${exportPrefix}(?:const|let|var)\s+${escapedName}\s*=\s*(?:async\s+)?function(?:\s+[A-Za-z_$][\w$]*)?\s*\(([^)]*)\)`, 'm'),
|
|
998
|
+
new RegExp(String.raw`(?:^|[^\w$])${exportPrefix}(?:const|let|var)\s+${escapedName}\s*=\s*(?:async\s+)?\(([^)]*)\)\s*=>`, 'm'),
|
|
999
|
+
new RegExp(String.raw`(?:^|[^\w$])${exportPrefix}(?:const|let|var)\s+${escapedName}\s*=\s*(?:async\s+)?([A-Za-z_$][\w$]*)\s*=>`, 'm'),
|
|
1000
|
+
];
|
|
1001
|
+
const methodBody =
|
|
1002
|
+
executionStyle === 'solution-method'
|
|
1003
|
+
? extractClassBodyForSignatureScan(strippedCode, 'Solution') ?? strippedCode
|
|
1004
|
+
: strippedCode;
|
|
1005
|
+
const methodPatterns = [
|
|
1006
|
+
new RegExp(String.raw`(?:^|[;{}\s])(?:async\s+)?${escapedName}\s*\(([^)]*)\)\s*\{`, 'm'),
|
|
1007
|
+
new RegExp(String.raw`(?:^|[;{}\s])${escapedName}\s*=\s*(?:async\s+)?\(([^)]*)\)\s*=>`, 'm'),
|
|
1008
|
+
new RegExp(String.raw`(?:^|[;{}\s])${escapedName}\s*=\s*(?:async\s+)?([A-Za-z_$][\w$]*)\s*=>`, 'm'),
|
|
1009
|
+
new RegExp(String.raw`(?:^|[;{}\s])${escapedName}\s*=\s*(?:async\s+)?function(?:\s+[A-Za-z_$][\w$]*)?\s*\(([^)]*)\)`, 'm'),
|
|
1010
|
+
];
|
|
1011
|
+
const patterns = executionStyle === 'solution-method' ? methodPatterns : functionPatterns;
|
|
1012
|
+
const scanCode = executionStyle === 'solution-method' ? methodBody : strippedCode;
|
|
1013
|
+
|
|
1014
|
+
for (const pattern of patterns) {
|
|
1015
|
+
const match = pattern.exec(scanCode);
|
|
1016
|
+
if (!match) continue;
|
|
1017
|
+
return parseSimpleJavaScriptParameterNames(match[1] ?? '');
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
return null;
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
function orderInputKeysByParameterNames(parameterNames, inputs, fallbackKeys) {
|
|
1024
|
+
if (!parameterNames || parameterNames.length === 0) {
|
|
1025
|
+
return fallbackKeys;
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
const matchedKeys = parameterNames.filter((name) => Object.prototype.hasOwnProperty.call(inputs, name));
|
|
1029
|
+
if (matchedKeys.length === 0) {
|
|
1030
|
+
return fallbackKeys;
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
const extras = fallbackKeys.filter((key) => !matchedKeys.includes(key));
|
|
1034
|
+
return [...matchedKeys, ...extras];
|
|
1035
|
+
}
|
|
1036
|
+
|
|
678
1037
|
async function resolveOrderedInputKeys(code, functionName, inputs, executionStyle, language = 'javascript') {
|
|
679
1038
|
const fallbackKeys = Object.keys(inputs ?? {});
|
|
680
1039
|
if (!functionName || executionStyle === 'ops-class' || fallbackKeys.length <= 1) {
|
|
681
1040
|
return fallbackKeys;
|
|
682
1041
|
}
|
|
683
1042
|
|
|
1043
|
+
if (language !== 'typescript') {
|
|
1044
|
+
const parameterNames = extractSimpleJavaScriptParameterNames(code, functionName, executionStyle);
|
|
1045
|
+
return orderInputKeysByParameterNames(parameterNames, inputs, fallbackKeys);
|
|
1046
|
+
}
|
|
1047
|
+
|
|
684
1048
|
try {
|
|
685
1049
|
await ensureTypeScriptCompiler();
|
|
686
1050
|
const ts = getTypeScriptCompiler();
|
|
@@ -701,17 +1065,7 @@ async function resolveOrderedInputKeys(code, functionName, inputs, executionStyl
|
|
|
701
1065
|
}
|
|
702
1066
|
|
|
703
1067
|
const parameterNames = collectSimpleParameterNames(ts, target);
|
|
704
|
-
|
|
705
|
-
return fallbackKeys;
|
|
706
|
-
}
|
|
707
|
-
|
|
708
|
-
const matchedKeys = parameterNames.filter((name) => Object.prototype.hasOwnProperty.call(inputs, name));
|
|
709
|
-
if (matchedKeys.length === 0) {
|
|
710
|
-
return fallbackKeys;
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
const extras = fallbackKeys.filter((key) => !matchedKeys.includes(key));
|
|
714
|
-
return [...matchedKeys, ...extras];
|
|
1068
|
+
return orderInputKeysByParameterNames(parameterNames, inputs, fallbackKeys);
|
|
715
1069
|
} catch (_error) {
|
|
716
1070
|
return fallbackKeys;
|
|
717
1071
|
}
|
|
@@ -759,22 +1113,30 @@ function getNumericOption(value, fallback) {
|
|
|
759
1113
|
return Math.floor(value);
|
|
760
1114
|
}
|
|
761
1115
|
|
|
762
|
-
function
|
|
763
|
-
return typeof value === 'number' && Number.isInteger(value)
|
|
1116
|
+
function isTraceablePathSegment(value) {
|
|
1117
|
+
return (typeof value === 'number' && Number.isInteger(value)) ||
|
|
1118
|
+
(typeof value === 'string' && value.length > 0);
|
|
764
1119
|
}
|
|
765
1120
|
|
|
766
1121
|
function normalizeTraceIndices(indices, maxDepth = 2) {
|
|
767
1122
|
if (!Array.isArray(indices) || indices.length === 0 || indices.length > maxDepth) {
|
|
768
1123
|
return null;
|
|
769
1124
|
}
|
|
770
|
-
if (!indices.every(
|
|
1125
|
+
if (!indices.every(isTraceablePathSegment)) {
|
|
1126
|
+
return null;
|
|
1127
|
+
}
|
|
1128
|
+
return indices.map((index) => typeof index === 'number' ? Math.trunc(index) : index);
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
function normalizeTraceIndexSources(indexSources, maxDepth = 2) {
|
|
1132
|
+
if (!Array.isArray(indexSources) || indexSources.length === 0 || indexSources.length > maxDepth) {
|
|
771
1133
|
return null;
|
|
772
1134
|
}
|
|
773
|
-
return
|
|
1135
|
+
return indexSources.map((source) => typeof source === 'string' && source.length > 0 ? source : null);
|
|
774
1136
|
}
|
|
775
1137
|
|
|
776
1138
|
function isTraceableMutatingMethod(methodName) {
|
|
777
|
-
return ['push', 'pop', 'shift', 'unshift', 'splice'].includes(methodName);
|
|
1139
|
+
return ['push', 'pop', 'shift', 'unshift', 'splice', 'set', 'get', 'has', 'add', 'delete', 'clear'].includes(methodName);
|
|
778
1140
|
}
|
|
779
1141
|
|
|
780
1142
|
function readValueAtIndices(container, indices) {
|
|
@@ -809,14 +1171,17 @@ function writeValueAtIndices(container, indices, value) {
|
|
|
809
1171
|
|
|
810
1172
|
function createTraceRecorder(options = {}) {
|
|
811
1173
|
const trace = [];
|
|
1174
|
+
const runtimeTraceEvents = [];
|
|
812
1175
|
const callStack = [];
|
|
813
1176
|
const pendingAccessesByFrame = new Map();
|
|
814
1177
|
const deferredAccessesByFrame = new Map();
|
|
1178
|
+
const runtimeTraceAccessStatsByVariable = new Map();
|
|
815
1179
|
const lineHitCount = new Map();
|
|
816
1180
|
const stableNodeRefState = { ids: new Map(), nextId: 1 };
|
|
817
1181
|
const maxTraceSteps = getNumericOption(options.maxTraceSteps, 4000);
|
|
818
1182
|
const maxStoredEvents = getNumericOption(options.maxStoredEvents, maxTraceSteps);
|
|
819
1183
|
const effectiveMaxTraceSteps = Math.min(maxTraceSteps, maxStoredEvents);
|
|
1184
|
+
const effectiveMaxRuntimeTraceEvents = maxStoredEvents;
|
|
820
1185
|
const maxLineEvents = getNumericOption(options.maxLineEvents, 12000);
|
|
821
1186
|
const maxSingleLineHits = getNumericOption(options.maxSingleLineHits, 1000);
|
|
822
1187
|
const maxCallDepth = getNumericOption(options.maxCallDepth, 2000);
|
|
@@ -827,6 +1192,27 @@ function createTraceRecorder(options = {}) {
|
|
|
827
1192
|
let timeoutRecorded = false;
|
|
828
1193
|
let nextFrameId = 1;
|
|
829
1194
|
|
|
1195
|
+
function markTraceCaptureLimit(lineNumber, functionName) {
|
|
1196
|
+
if (!traceLimitExceeded) {
|
|
1197
|
+
traceLimitExceeded = true;
|
|
1198
|
+
timeoutReason = 'trace-limit';
|
|
1199
|
+
}
|
|
1200
|
+
pendingAccessesByFrame.clear();
|
|
1201
|
+
deferredAccessesByFrame.clear();
|
|
1202
|
+
if (!timeoutRecorded && trace.length < effectiveMaxTraceSteps && runtimeTraceEvents.length < effectiveMaxRuntimeTraceEvents) {
|
|
1203
|
+
const timeoutStep = {
|
|
1204
|
+
line: normalizeLine(lineNumber, 1),
|
|
1205
|
+
event: 'timeout',
|
|
1206
|
+
variables: { timeoutReason: 'trace-limit' },
|
|
1207
|
+
function: functionName ?? callStack[callStack.length - 1]?.function ?? '<module>',
|
|
1208
|
+
callStack: snapshotCallStack(),
|
|
1209
|
+
};
|
|
1210
|
+
timeoutRecorded = true;
|
|
1211
|
+
trace.push(timeoutStep);
|
|
1212
|
+
appendRuntimeTraceEventsForStep(timeoutStep);
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
|
|
830
1216
|
function normalizeLine(lineNumber, fallback = 1) {
|
|
831
1217
|
const parsed = Number(lineNumber);
|
|
832
1218
|
if (!Number.isFinite(parsed) || parsed <= 0) return fallback;
|
|
@@ -835,6 +1221,7 @@ function createTraceRecorder(options = {}) {
|
|
|
835
1221
|
|
|
836
1222
|
function snapshotCallStack() {
|
|
837
1223
|
return callStack.map((frame) => ({
|
|
1224
|
+
id: frame.id,
|
|
838
1225
|
function: frame.function,
|
|
839
1226
|
args: frame.args,
|
|
840
1227
|
line: frame.line,
|
|
@@ -848,11 +1235,7 @@ function createTraceRecorder(options = {}) {
|
|
|
848
1235
|
if (variableValue === undefined) continue;
|
|
849
1236
|
if (typeof variableValue === 'function') continue;
|
|
850
1237
|
try {
|
|
851
|
-
|
|
852
|
-
key === 'this' && variableValue && typeof variableValue === 'object'
|
|
853
|
-
? { ids: new Map(), nextId: 1 }
|
|
854
|
-
: stableNodeRefState;
|
|
855
|
-
result[key] = serializeTopLevelValue(variableValue, refState);
|
|
1238
|
+
result[key] = serializeTopLevelValue(variableValue, stableNodeRefState);
|
|
856
1239
|
} catch {
|
|
857
1240
|
// Skip variables that throw during serialization (e.g. transient proxy/getter failures).
|
|
858
1241
|
}
|
|
@@ -860,6 +1243,24 @@ function createTraceRecorder(options = {}) {
|
|
|
860
1243
|
return result;
|
|
861
1244
|
}
|
|
862
1245
|
|
|
1246
|
+
function sanitizeCallArgs(value) {
|
|
1247
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) return {};
|
|
1248
|
+
const result = {};
|
|
1249
|
+
for (const [key, variableValue] of Object.entries(value)) {
|
|
1250
|
+
if (typeof variableValue === 'function') continue;
|
|
1251
|
+
if (variableValue === undefined) {
|
|
1252
|
+
result[key] = '<undefined>';
|
|
1253
|
+
continue;
|
|
1254
|
+
}
|
|
1255
|
+
try {
|
|
1256
|
+
result[key] = serializeTopLevelValue(variableValue, stableNodeRefState);
|
|
1257
|
+
} catch {
|
|
1258
|
+
result[key] = '<unserializable>';
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
return result;
|
|
1262
|
+
}
|
|
1263
|
+
|
|
863
1264
|
function isLikelyTreeObject(value) {
|
|
864
1265
|
if (!value || typeof value !== 'object' || Array.isArray(value)) return false;
|
|
865
1266
|
const hasValue = Object.prototype.hasOwnProperty.call(value, 'val') || Object.prototype.hasOwnProperty.call(value, 'value');
|
|
@@ -916,178 +1317,6 @@ function createTraceRecorder(options = {}) {
|
|
|
916
1317
|
return true;
|
|
917
1318
|
}
|
|
918
1319
|
|
|
919
|
-
function shouldVisualizeObjectAsHashMap(name, value) {
|
|
920
|
-
if (!value || typeof value !== 'object' || Array.isArray(value)) return false;
|
|
921
|
-
if (isLikelyTreeObject(value) || isLikelyLinkedListObject(value)) return false;
|
|
922
|
-
if (value.__type__ === 'object') return false;
|
|
923
|
-
if (Object.keys(value).length === 1 && typeof value.__ref__ === 'string') return false;
|
|
924
|
-
if (isLikelyAdjacencyListObject(value)) return false;
|
|
925
|
-
|
|
926
|
-
const lowerName = String(name).toLowerCase();
|
|
927
|
-
if (lowerName.includes('map') || lowerName.includes('seen') || lowerName.includes('dict')) {
|
|
928
|
-
return true;
|
|
929
|
-
}
|
|
930
|
-
return Object.keys(value).length > 0;
|
|
931
|
-
}
|
|
932
|
-
|
|
933
|
-
function collectRuntimeVisualizations(value) {
|
|
934
|
-
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
935
|
-
return { hashMaps: [], objectKinds: {} };
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
const visualizations = [];
|
|
939
|
-
const objectKinds = {};
|
|
940
|
-
for (const [name, variableValue] of Object.entries(value)) {
|
|
941
|
-
if (variableValue === undefined) continue;
|
|
942
|
-
|
|
943
|
-
if (variableValue instanceof Map) {
|
|
944
|
-
objectKinds[name] = 'map';
|
|
945
|
-
visualizations.push({
|
|
946
|
-
name,
|
|
947
|
-
kind: 'map',
|
|
948
|
-
entries: [...variableValue.entries()].map(([key, mapValue]) => ({
|
|
949
|
-
key: serializeValue(key),
|
|
950
|
-
value: serializeValue(mapValue),
|
|
951
|
-
})),
|
|
952
|
-
});
|
|
953
|
-
continue;
|
|
954
|
-
}
|
|
955
|
-
|
|
956
|
-
if (variableValue instanceof Set) {
|
|
957
|
-
objectKinds[name] = 'set';
|
|
958
|
-
visualizations.push({
|
|
959
|
-
name,
|
|
960
|
-
kind: 'set',
|
|
961
|
-
entries: [...variableValue.values()].map((item) => ({
|
|
962
|
-
key: serializeValue(item),
|
|
963
|
-
value: true,
|
|
964
|
-
})),
|
|
965
|
-
});
|
|
966
|
-
continue;
|
|
967
|
-
}
|
|
968
|
-
|
|
969
|
-
if (isLikelyIndexedAdjacencyListArray(variableValue)) {
|
|
970
|
-
objectKinds[name] = 'graph-adjacency';
|
|
971
|
-
continue;
|
|
972
|
-
}
|
|
973
|
-
|
|
974
|
-
if (variableValue && typeof variableValue === 'object' && !Array.isArray(variableValue)) {
|
|
975
|
-
const customClassName = getCustomClassName(variableValue);
|
|
976
|
-
if (customClassName) {
|
|
977
|
-
const serializedObject = serializeValue(variableValue);
|
|
978
|
-
objectKinds[name] = 'object';
|
|
979
|
-
visualizations.push({
|
|
980
|
-
name,
|
|
981
|
-
kind: 'object',
|
|
982
|
-
objectClassName: customClassName,
|
|
983
|
-
objectId:
|
|
984
|
-
serializedObject && typeof serializedObject === 'object' && typeof serializedObject.__id__ === 'string'
|
|
985
|
-
? serializedObject.__id__
|
|
986
|
-
: undefined,
|
|
987
|
-
entries: Object.entries(serializedObject)
|
|
988
|
-
.filter(([key]) => key !== '__type__' && key !== '__class__' && key !== '__id__')
|
|
989
|
-
.map(([key, entryValue]) => ({
|
|
990
|
-
key,
|
|
991
|
-
value: entryValue,
|
|
992
|
-
})),
|
|
993
|
-
});
|
|
994
|
-
continue;
|
|
995
|
-
}
|
|
996
|
-
|
|
997
|
-
const serializedValue = variableValue;
|
|
998
|
-
|
|
999
|
-
if (serializedValue.__type__ === 'object') {
|
|
1000
|
-
objectKinds[name] = 'object';
|
|
1001
|
-
visualizations.push({
|
|
1002
|
-
name,
|
|
1003
|
-
kind: 'object',
|
|
1004
|
-
objectClassName:
|
|
1005
|
-
typeof serializedValue.__class__ === 'string' && serializedValue.__class__.length > 0
|
|
1006
|
-
? serializedValue.__class__
|
|
1007
|
-
: undefined,
|
|
1008
|
-
objectId:
|
|
1009
|
-
typeof serializedValue.__id__ === 'string' && serializedValue.__id__.length > 0
|
|
1010
|
-
? serializedValue.__id__
|
|
1011
|
-
: undefined,
|
|
1012
|
-
entries: Object.entries(serializedValue)
|
|
1013
|
-
.filter(([key]) => key !== '__type__' && key !== '__class__' && key !== '__id__')
|
|
1014
|
-
.map(([key, entryValue]) => ({
|
|
1015
|
-
key,
|
|
1016
|
-
value: entryValue,
|
|
1017
|
-
})),
|
|
1018
|
-
});
|
|
1019
|
-
continue;
|
|
1020
|
-
}
|
|
1021
|
-
|
|
1022
|
-
if (serializedValue.__type__ === 'map' && Array.isArray(serializedValue.entries)) {
|
|
1023
|
-
objectKinds[name] = 'map';
|
|
1024
|
-
visualizations.push({
|
|
1025
|
-
name,
|
|
1026
|
-
kind: 'map',
|
|
1027
|
-
entries: serializedValue.entries
|
|
1028
|
-
.filter((entry) => Array.isArray(entry) && entry.length >= 2)
|
|
1029
|
-
.map((entry) => ({
|
|
1030
|
-
key: entry[0],
|
|
1031
|
-
value: entry[1],
|
|
1032
|
-
})),
|
|
1033
|
-
});
|
|
1034
|
-
continue;
|
|
1035
|
-
}
|
|
1036
|
-
|
|
1037
|
-
if (serializedValue.__type__ === 'set' && Array.isArray(serializedValue.values)) {
|
|
1038
|
-
objectKinds[name] = 'set';
|
|
1039
|
-
visualizations.push({
|
|
1040
|
-
name,
|
|
1041
|
-
kind: 'set',
|
|
1042
|
-
entries: serializedValue.values.map((item) => ({
|
|
1043
|
-
key: item,
|
|
1044
|
-
value: true,
|
|
1045
|
-
})),
|
|
1046
|
-
});
|
|
1047
|
-
continue;
|
|
1048
|
-
}
|
|
1049
|
-
|
|
1050
|
-
if (isLikelyTreeObject(serializedValue)) {
|
|
1051
|
-
objectKinds[name] = 'tree';
|
|
1052
|
-
continue;
|
|
1053
|
-
}
|
|
1054
|
-
|
|
1055
|
-
if (isLikelyLinkedListObject(serializedValue)) {
|
|
1056
|
-
objectKinds[name] = 'linked-list';
|
|
1057
|
-
continue;
|
|
1058
|
-
}
|
|
1059
|
-
|
|
1060
|
-
if (isLikelyAdjacencyListObject(serializedValue)) {
|
|
1061
|
-
objectKinds[name] = 'graph-adjacency';
|
|
1062
|
-
continue;
|
|
1063
|
-
}
|
|
1064
|
-
|
|
1065
|
-
if (shouldVisualizeObjectAsHashMap(name, serializedValue)) {
|
|
1066
|
-
objectKinds[name] = 'hashmap';
|
|
1067
|
-
visualizations.push({
|
|
1068
|
-
name,
|
|
1069
|
-
kind: 'hashmap',
|
|
1070
|
-
entries: Object.entries(serializedValue).map(([key, entryValue]) => ({
|
|
1071
|
-
key,
|
|
1072
|
-
value: serializeValue(entryValue),
|
|
1073
|
-
})),
|
|
1074
|
-
});
|
|
1075
|
-
}
|
|
1076
|
-
}
|
|
1077
|
-
}
|
|
1078
|
-
|
|
1079
|
-
return { hashMaps: visualizations, objectKinds };
|
|
1080
|
-
}
|
|
1081
|
-
|
|
1082
|
-
function buildVisualizationPayload(value) {
|
|
1083
|
-
const { hashMaps, objectKinds } = collectRuntimeVisualizations(value);
|
|
1084
|
-
if (hashMaps.length === 0 && Object.keys(objectKinds).length === 0) return undefined;
|
|
1085
|
-
return {
|
|
1086
|
-
...(hashMaps.length > 0 ? { hashMaps } : {}),
|
|
1087
|
-
...(Object.keys(objectKinds).length > 0 ? { objectKinds } : {}),
|
|
1088
|
-
};
|
|
1089
|
-
}
|
|
1090
|
-
|
|
1091
1320
|
function createLimitError(reason, lineNumber, message) {
|
|
1092
1321
|
const error = new Error(message);
|
|
1093
1322
|
error.__traceLimitExceeded = true;
|
|
@@ -1135,29 +1364,27 @@ function createTraceRecorder(options = {}) {
|
|
|
1135
1364
|
...(Array.isArray(access.indices) && access.indices.length > 0
|
|
1136
1365
|
? { indices: access.indices }
|
|
1137
1366
|
: {}),
|
|
1367
|
+
...(Array.isArray(access.indexSources) && access.indexSources.length > 0
|
|
1368
|
+
? { indexSources: access.indexSources }
|
|
1369
|
+
: {}),
|
|
1138
1370
|
...(access.method ? { method: access.method } : {}),
|
|
1371
|
+
...(Array.isArray(access.args) ? { args: access.args } : {}),
|
|
1139
1372
|
...(access.pathDepth ? { pathDepth: access.pathDepth } : {}),
|
|
1373
|
+
...(access.scope ? { scope: access.scope } : {}),
|
|
1374
|
+
...(access.binding ? { binding: access.binding } : {}),
|
|
1375
|
+
...(Number.isFinite(access.line) && access.line > 0 ? { line: access.line } : {}),
|
|
1376
|
+
...(Number.isFinite(access.column) && access.column >= 0 ? { column: access.column } : {}),
|
|
1377
|
+
...(Object.prototype.hasOwnProperty.call(access, 'value') ? { value: access.value } : {}),
|
|
1140
1378
|
}));
|
|
1141
1379
|
}
|
|
1142
1380
|
|
|
1143
1381
|
function appendTrace(step, frameId = getCurrentFrameId()) {
|
|
1382
|
+
if (traceLimitExceeded) {
|
|
1383
|
+
return;
|
|
1384
|
+
}
|
|
1144
1385
|
if (trace.length >= effectiveMaxTraceSteps) {
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
traceLimitExceeded = true;
|
|
1148
|
-
timeoutReason = 'trace-limit';
|
|
1149
|
-
}
|
|
1150
|
-
if (!timeoutRecorded && trace.length < effectiveMaxTraceSteps) {
|
|
1151
|
-
trace.push({
|
|
1152
|
-
line: lineNumber,
|
|
1153
|
-
event: 'timeout',
|
|
1154
|
-
variables: {},
|
|
1155
|
-
function: step?.function ?? callStack[callStack.length - 1]?.function ?? '<module>',
|
|
1156
|
-
callStack: snapshotCallStack(),
|
|
1157
|
-
});
|
|
1158
|
-
timeoutRecorded = true;
|
|
1159
|
-
}
|
|
1160
|
-
throw createLimitError('trace-limit', lineNumber, `Exceeded ${effectiveMaxTraceSteps} trace steps`);
|
|
1386
|
+
markTraceCaptureLimit(step?.line, step?.function);
|
|
1387
|
+
return;
|
|
1161
1388
|
}
|
|
1162
1389
|
const accesses = flushPendingAccesses(frameId);
|
|
1163
1390
|
const nextStep = {
|
|
@@ -1173,35 +1400,185 @@ function createTraceRecorder(options = {}) {
|
|
|
1173
1400
|
if (nextStep.accesses?.length) {
|
|
1174
1401
|
previous.accesses = [...(previous.accesses || []), ...nextStep.accesses];
|
|
1175
1402
|
}
|
|
1176
|
-
if (nextStep.visualization !== undefined) {
|
|
1177
|
-
previous.visualization = nextStep.visualization;
|
|
1178
|
-
}
|
|
1179
1403
|
previous.callStack = nextStep.callStack;
|
|
1180
1404
|
previous.function = nextStep.function;
|
|
1405
|
+
appendRuntimeTraceEventsForStep({
|
|
1406
|
+
...nextStep,
|
|
1407
|
+
event: '__merge_only__',
|
|
1408
|
+
});
|
|
1181
1409
|
return;
|
|
1182
1410
|
}
|
|
1183
1411
|
trace.push(nextStep);
|
|
1412
|
+
appendRuntimeTraceEventsForStep(nextStep);
|
|
1184
1413
|
}
|
|
1185
1414
|
|
|
1186
|
-
function
|
|
1187
|
-
|
|
1188
|
-
if (
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1415
|
+
function runtimeTraceFrameIdForStep(step) {
|
|
1416
|
+
const stack = Array.isArray(step?.callStack) ? step.callStack : [];
|
|
1417
|
+
if (stack.length > 0) {
|
|
1418
|
+
const frame = stack[stack.length - 1];
|
|
1419
|
+
return `${frame.function}:${frame.line}:${frame.id ?? 'unknown'}`;
|
|
1420
|
+
}
|
|
1421
|
+
return `${step.function}:${step.line}:root`;
|
|
1192
1422
|
}
|
|
1193
1423
|
|
|
1194
|
-
function
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1424
|
+
function runtimeTraceTargetForAccess(access) {
|
|
1425
|
+
const indices = Array.isArray(access?.indices) ? access.indices : [];
|
|
1426
|
+
const indexSources = Array.isArray(access?.indexSources) ? access.indexSources : [];
|
|
1427
|
+
const scope = typeof access?.scope === 'string' && access.scope.length > 0
|
|
1428
|
+
? access.scope
|
|
1429
|
+
: undefined;
|
|
1430
|
+
const base = {
|
|
1431
|
+
variable: access.variable,
|
|
1432
|
+
...(scope ? { scope } : {}),
|
|
1433
|
+
};
|
|
1434
|
+
if (indices.length > 0) {
|
|
1435
|
+
return {
|
|
1436
|
+
...base,
|
|
1437
|
+
path: indices,
|
|
1438
|
+
...(indexSources.length > 0 ? { indexSources } : {}),
|
|
1439
|
+
};
|
|
1203
1440
|
}
|
|
1204
|
-
return
|
|
1441
|
+
return base;
|
|
1442
|
+
}
|
|
1443
|
+
|
|
1444
|
+
function runtimeTraceKindForAccess(access) {
|
|
1445
|
+
if (access.kind === 'indexed-read' || access.kind === 'cell-read') return 'read';
|
|
1446
|
+
if (access.kind === 'indexed-write' || access.kind === 'cell-write') return 'write';
|
|
1447
|
+
return 'mutate';
|
|
1448
|
+
}
|
|
1449
|
+
|
|
1450
|
+
function runtimeTraceAccessValue(step, access) {
|
|
1451
|
+
if (access && Object.prototype.hasOwnProperty.call(access, 'value')) return access.value;
|
|
1452
|
+
return valueAtPath(step?.variables?.[access.variable], access.indices);
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1455
|
+
function traceStepFrameId(step) {
|
|
1456
|
+
const stack = Array.isArray(step?.callStack) ? step.callStack : [];
|
|
1457
|
+
return stack.length > 0 ? stack[stack.length - 1]?.id : undefined;
|
|
1458
|
+
}
|
|
1459
|
+
|
|
1460
|
+
function updateRuntimeTraceAccessStats(access) {
|
|
1461
|
+
const variable = access?.variable;
|
|
1462
|
+
if (typeof variable !== 'string' || variable.length === 0) return;
|
|
1463
|
+
const stats = runtimeTraceAccessStatsByVariable.get(variable) ?? {
|
|
1464
|
+
hasCellRead: false,
|
|
1465
|
+
hasCellWrite: false,
|
|
1466
|
+
hasMutatingCall: false,
|
|
1467
|
+
hasNestedMutatingCall: false,
|
|
1468
|
+
hasIndexedWrite: false,
|
|
1469
|
+
};
|
|
1470
|
+
if (access.kind === 'cell-read') stats.hasCellRead = true;
|
|
1471
|
+
if (access.kind === 'cell-write') stats.hasCellWrite = true;
|
|
1472
|
+
if (access.kind === 'mutating-call') stats.hasMutatingCall = true;
|
|
1473
|
+
if (access.kind === 'mutating-call' && (access.pathDepth ?? 0) > 0) stats.hasNestedMutatingCall = true;
|
|
1474
|
+
if (access.kind === 'indexed-write') stats.hasIndexedWrite = true;
|
|
1475
|
+
runtimeTraceAccessStatsByVariable.set(variable, stats);
|
|
1476
|
+
}
|
|
1477
|
+
|
|
1478
|
+
function appendRuntimeTraceEventsForStep(step) {
|
|
1479
|
+
if (traceLimitExceeded && timeoutReason === 'trace-limit' && step?.event !== 'timeout') {
|
|
1480
|
+
return;
|
|
1481
|
+
}
|
|
1482
|
+
const base = {
|
|
1483
|
+
runId: 'javascript:run',
|
|
1484
|
+
line: step.line,
|
|
1485
|
+
frameId: runtimeTraceFrameIdForStep(step),
|
|
1486
|
+
};
|
|
1487
|
+
const pushRuntimeTraceEvent = (event) => {
|
|
1488
|
+
if (runtimeTraceEvents.length >= effectiveMaxRuntimeTraceEvents) {
|
|
1489
|
+
markTraceCaptureLimit(step?.line, step?.function);
|
|
1490
|
+
return false;
|
|
1491
|
+
}
|
|
1492
|
+
runtimeTraceEvents.push(event);
|
|
1493
|
+
return true;
|
|
1494
|
+
};
|
|
1495
|
+
|
|
1496
|
+
if (step.event === 'line') {
|
|
1497
|
+
pushRuntimeTraceEvent({ ...base, kind: 'line', function: step.function });
|
|
1498
|
+
} else if (step.event === 'call') {
|
|
1499
|
+
const stack = Array.isArray(step.callStack) ? step.callStack : [];
|
|
1500
|
+
pushRuntimeTraceEvent({ ...base, kind: 'call', function: step.function, args: stack.at(-1)?.args });
|
|
1501
|
+
} else if (step.event === 'return') {
|
|
1502
|
+
pushRuntimeTraceEvent({
|
|
1503
|
+
...base,
|
|
1504
|
+
kind: 'return',
|
|
1505
|
+
function: step.function,
|
|
1506
|
+
...(step.returnValue !== undefined ? { value: step.returnValue } : {}),
|
|
1507
|
+
});
|
|
1508
|
+
} else if (step.event === 'exception') {
|
|
1509
|
+
pushRuntimeTraceEvent({ ...base, kind: 'exception', message: String(step.returnValue ?? 'Runtime exception') });
|
|
1510
|
+
} else if (step.event === 'timeout') {
|
|
1511
|
+
pushRuntimeTraceEvent({ ...base, kind: 'timeout', message: 'Runtime timeout' });
|
|
1512
|
+
} else if (step.event === 'stdout') {
|
|
1513
|
+
pushRuntimeTraceEvent({
|
|
1514
|
+
kind: 'stdout',
|
|
1515
|
+
runId: 'javascript:run',
|
|
1516
|
+
...(step.line ? { line: step.line } : {}),
|
|
1517
|
+
text: String(step.returnValue ?? ''),
|
|
1518
|
+
});
|
|
1519
|
+
}
|
|
1520
|
+
|
|
1521
|
+
if (step.event !== '__merge_only__') {
|
|
1522
|
+
for (const [variable, value] of Object.entries(step.variables ?? {})) {
|
|
1523
|
+
if (!pushRuntimeTraceEvent({ ...base, kind: 'snapshot', target: { variable }, value })) return;
|
|
1524
|
+
}
|
|
1525
|
+
} else {
|
|
1526
|
+
for (const [variable, value] of Object.entries(step.variables ?? {})) {
|
|
1527
|
+
if (!pushRuntimeTraceEvent({ ...base, kind: 'snapshot', target: { variable }, value })) return;
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
|
|
1531
|
+
for (const access of step.accesses ?? []) {
|
|
1532
|
+
updateRuntimeTraceAccessStats(access);
|
|
1533
|
+
const kind = runtimeTraceKindForAccess(access);
|
|
1534
|
+
const target = runtimeTraceTargetForAccess(access);
|
|
1535
|
+
const accessBase = {
|
|
1536
|
+
...base,
|
|
1537
|
+
...(Number.isFinite(access.line) && access.line > 0 ? { line: access.line } : {}),
|
|
1538
|
+
...(Number.isFinite(access.column) && access.column >= 0 ? { column: access.column } : {}),
|
|
1539
|
+
};
|
|
1540
|
+
if (kind === 'mutate') {
|
|
1541
|
+
const event = {
|
|
1542
|
+
...accessBase,
|
|
1543
|
+
kind,
|
|
1544
|
+
target,
|
|
1545
|
+
...(access.method ? { method: access.method } : {}),
|
|
1546
|
+
...(Array.isArray(access.args) ? { args: access.args } : {}),
|
|
1547
|
+
};
|
|
1548
|
+
if (!pushRuntimeTraceEvent(event)) return;
|
|
1549
|
+
} else {
|
|
1550
|
+
const event = {
|
|
1551
|
+
...accessBase,
|
|
1552
|
+
kind,
|
|
1553
|
+
target,
|
|
1554
|
+
value: runtimeTraceAccessValue(step, access),
|
|
1555
|
+
...(access.binding ? { binding: access.binding } : {}),
|
|
1556
|
+
};
|
|
1557
|
+
if (!pushRuntimeTraceEvent(event)) return;
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
|
|
1562
|
+
function canMergeConsecutiveLineSteps(previous, nextStep) {
|
|
1563
|
+
if (!previous || !nextStep) return false;
|
|
1564
|
+
if (previous.event !== 'line' || nextStep.event !== 'line') return false;
|
|
1565
|
+
if (previous.line !== nextStep.line) return false;
|
|
1566
|
+
if (previous.function !== nextStep.function) return false;
|
|
1567
|
+
if ((previous.accesses?.length ?? 0) > 0 || (nextStep.accesses?.length ?? 0) > 0) return false;
|
|
1568
|
+
return sameCallStackVisit(previous.callStack, nextStep.callStack);
|
|
1569
|
+
}
|
|
1570
|
+
|
|
1571
|
+
function sameCallStackVisit(left, right) {
|
|
1572
|
+
if (!Array.isArray(left) || !Array.isArray(right)) return false;
|
|
1573
|
+
if (left.length !== right.length) return false;
|
|
1574
|
+
for (let index = 0; index < left.length; index += 1) {
|
|
1575
|
+
const leftFrame = left[index];
|
|
1576
|
+
const rightFrame = right[index];
|
|
1577
|
+
if (!leftFrame || !rightFrame) return false;
|
|
1578
|
+
if (leftFrame.function !== rightFrame.function) return false;
|
|
1579
|
+
if (leftFrame.line !== rightFrame.line) return false;
|
|
1580
|
+
}
|
|
1581
|
+
return true;
|
|
1205
1582
|
}
|
|
1206
1583
|
|
|
1207
1584
|
function markTimeout(reason, lineNumber, message) {
|
|
@@ -1312,7 +1689,6 @@ function createTraceRecorder(options = {}) {
|
|
|
1312
1689
|
variables: inferredFrame.args,
|
|
1313
1690
|
function: normalizedFunctionName,
|
|
1314
1691
|
callStack: snapshotCallStack(),
|
|
1315
|
-
visualization: buildVisualizationPayload(inferredArgs),
|
|
1316
1692
|
});
|
|
1317
1693
|
return normalizedFunctionName;
|
|
1318
1694
|
}
|
|
@@ -1333,7 +1709,6 @@ function createTraceRecorder(options = {}) {
|
|
|
1333
1709
|
},
|
|
1334
1710
|
pushCall(functionName, args, lineNumber) {
|
|
1335
1711
|
const normalizedLine = normalizeLine(lineNumber, 1);
|
|
1336
|
-
const normalizedArgs = sanitizeVariables(args);
|
|
1337
1712
|
if (callStack.length + 1 > maxCallDepth) {
|
|
1338
1713
|
markTimeout(
|
|
1339
1714
|
'recursion-limit',
|
|
@@ -1341,6 +1716,11 @@ function createTraceRecorder(options = {}) {
|
|
|
1341
1716
|
`Exceeded max call depth (${maxCallDepth})`
|
|
1342
1717
|
);
|
|
1343
1718
|
}
|
|
1719
|
+
if (traceLimitExceeded) {
|
|
1720
|
+
return;
|
|
1721
|
+
}
|
|
1722
|
+
this.attachPendingAccessesToPreviousLine();
|
|
1723
|
+
const normalizedArgs = sanitizeCallArgs(args);
|
|
1344
1724
|
const frame = {
|
|
1345
1725
|
id: nextFrameId++,
|
|
1346
1726
|
function: functionName || '<module>',
|
|
@@ -1354,10 +1734,12 @@ function createTraceRecorder(options = {}) {
|
|
|
1354
1734
|
variables: normalizedArgs,
|
|
1355
1735
|
function: frame.function,
|
|
1356
1736
|
callStack: snapshotCallStack(),
|
|
1357
|
-
visualization: buildVisualizationPayload(args),
|
|
1358
1737
|
});
|
|
1359
1738
|
},
|
|
1360
1739
|
recordAccess(event) {
|
|
1740
|
+
if (traceLimitExceeded) {
|
|
1741
|
+
return;
|
|
1742
|
+
}
|
|
1361
1743
|
if (!event || typeof event !== 'object') {
|
|
1362
1744
|
return;
|
|
1363
1745
|
}
|
|
@@ -1377,12 +1759,41 @@ function createTraceRecorder(options = {}) {
|
|
|
1377
1759
|
variable,
|
|
1378
1760
|
kind,
|
|
1379
1761
|
...(Array.isArray(event.indices) && event.indices.length > 0
|
|
1380
|
-
? { indices: event.indices
|
|
1762
|
+
? { indices: normalizeTraceIndices(event.indices) ?? undefined }
|
|
1763
|
+
: {}),
|
|
1764
|
+
...(Array.isArray(event.indexSources) && event.indexSources.length > 0
|
|
1765
|
+
? { indexSources: normalizeTraceIndexSources(event.indexSources) ?? undefined }
|
|
1381
1766
|
: {}),
|
|
1382
1767
|
...(typeof event.method === 'string' && event.method.length > 0
|
|
1383
1768
|
? { method: event.method }
|
|
1384
1769
|
: {}),
|
|
1385
|
-
...(
|
|
1770
|
+
...(Array.isArray(event.args)
|
|
1771
|
+
? { args: event.args.map((arg) => this.serialize(arg)) }
|
|
1772
|
+
: {}),
|
|
1773
|
+
...(event.pathDepth === 1 || event.pathDepth === 2 || event.pathDepth === 3 ? { pathDepth: event.pathDepth } : {}),
|
|
1774
|
+
...(typeof event.scope === 'string' && event.scope.length > 0
|
|
1775
|
+
? { scope: event.scope }
|
|
1776
|
+
: {}),
|
|
1777
|
+
...(event.binding &&
|
|
1778
|
+
typeof event.binding === 'object' &&
|
|
1779
|
+
typeof event.binding.variable === 'string' &&
|
|
1780
|
+
event.binding.variable.length > 0
|
|
1781
|
+
? {
|
|
1782
|
+
binding: {
|
|
1783
|
+
...(event.binding.kind === 'iteration' ? { kind: 'iteration' } : {}),
|
|
1784
|
+
variable: event.binding.variable,
|
|
1785
|
+
},
|
|
1786
|
+
}
|
|
1787
|
+
: {}),
|
|
1788
|
+
...(Number.isFinite(event.line) && event.line > 0
|
|
1789
|
+
? { line: Math.trunc(event.line) }
|
|
1790
|
+
: {}),
|
|
1791
|
+
...(Number.isFinite(event.column) && event.column >= 0
|
|
1792
|
+
? { column: Math.trunc(event.column) }
|
|
1793
|
+
: {}),
|
|
1794
|
+
...(Object.prototype.hasOwnProperty.call(event, 'value')
|
|
1795
|
+
? { value: this.serialize(event.value) }
|
|
1796
|
+
: {}),
|
|
1386
1797
|
};
|
|
1387
1798
|
|
|
1388
1799
|
const existing = pendingAccessesByFrame.get(frameId) ?? [];
|
|
@@ -1390,6 +1801,9 @@ function createTraceRecorder(options = {}) {
|
|
|
1390
1801
|
pendingAccessesByFrame.set(frameId, existing);
|
|
1391
1802
|
},
|
|
1392
1803
|
deferPendingAccesses(lineFlushes = 1) {
|
|
1804
|
+
if (traceLimitExceeded) {
|
|
1805
|
+
return;
|
|
1806
|
+
}
|
|
1393
1807
|
const frameId = getCurrentFrameId();
|
|
1394
1808
|
if (frameId === undefined) {
|
|
1395
1809
|
return;
|
|
@@ -1408,9 +1822,54 @@ function createTraceRecorder(options = {}) {
|
|
|
1408
1822
|
),
|
|
1409
1823
|
});
|
|
1410
1824
|
},
|
|
1825
|
+
attachPendingAccessesToPreviousLine() {
|
|
1826
|
+
if (traceLimitExceeded) {
|
|
1827
|
+
return;
|
|
1828
|
+
}
|
|
1829
|
+
const frameId = getCurrentFrameId();
|
|
1830
|
+
if (frameId === undefined) {
|
|
1831
|
+
return;
|
|
1832
|
+
}
|
|
1833
|
+
const pending = pendingAccessesByFrame.get(frameId);
|
|
1834
|
+
if (!Array.isArray(pending) || pending.length === 0) {
|
|
1835
|
+
return;
|
|
1836
|
+
}
|
|
1837
|
+
const attachable = pending;
|
|
1838
|
+
pendingAccessesByFrame.delete(frameId);
|
|
1839
|
+
if (attachable.length === 0) {
|
|
1840
|
+
return;
|
|
1841
|
+
}
|
|
1842
|
+
for (let index = trace.length - 1; index >= 0; index -= 1) {
|
|
1843
|
+
const step = trace[index];
|
|
1844
|
+
if (!step || step.event !== 'line') continue;
|
|
1845
|
+
if (traceStepFrameId(step) !== frameId) continue;
|
|
1846
|
+
step.accesses = [...(step.accesses ?? []), ...attachable];
|
|
1847
|
+
appendRuntimeTraceEventsForStep({
|
|
1848
|
+
...step,
|
|
1849
|
+
event: '__access_only__',
|
|
1850
|
+
accesses: attachable,
|
|
1851
|
+
});
|
|
1852
|
+
return;
|
|
1853
|
+
}
|
|
1854
|
+
pendingAccessesByFrame.set(frameId, attachable);
|
|
1855
|
+
},
|
|
1856
|
+
traceCondition(value) {
|
|
1857
|
+
this.attachPendingAccessesToPreviousLine();
|
|
1858
|
+
return value;
|
|
1859
|
+
},
|
|
1860
|
+
tracePostLineCondition(evaluate) {
|
|
1861
|
+
if (typeof evaluate !== 'function') {
|
|
1862
|
+
return evaluate;
|
|
1863
|
+
}
|
|
1864
|
+
return evaluate();
|
|
1865
|
+
},
|
|
1411
1866
|
line(lineNumber, snapshotFactory, functionNameOverride, functionStartLine) {
|
|
1412
1867
|
const normalizedLine = normalizeLine(lineNumber, callStack[callStack.length - 1]?.line ?? 1);
|
|
1413
1868
|
|
|
1869
|
+
if (traceLimitExceeded) {
|
|
1870
|
+
return;
|
|
1871
|
+
}
|
|
1872
|
+
|
|
1414
1873
|
lineEventCount += 1;
|
|
1415
1874
|
if (lineEventCount > maxLineEvents) {
|
|
1416
1875
|
markTimeout('line-limit', normalizedLine, `Exceeded ${maxLineEvents} line events`);
|
|
@@ -1427,15 +1886,12 @@ function createTraceRecorder(options = {}) {
|
|
|
1427
1886
|
}
|
|
1428
1887
|
|
|
1429
1888
|
let variables = {};
|
|
1430
|
-
let visualization;
|
|
1431
1889
|
if (typeof snapshotFactory === 'function') {
|
|
1432
1890
|
try {
|
|
1433
1891
|
const snapshot = snapshotFactory();
|
|
1434
1892
|
variables = sanitizeVariables(snapshot);
|
|
1435
|
-
visualization = buildVisualizationPayload(snapshot);
|
|
1436
1893
|
} catch {
|
|
1437
1894
|
variables = {};
|
|
1438
|
-
visualization = undefined;
|
|
1439
1895
|
}
|
|
1440
1896
|
}
|
|
1441
1897
|
|
|
@@ -1452,10 +1908,12 @@ function createTraceRecorder(options = {}) {
|
|
|
1452
1908
|
variables,
|
|
1453
1909
|
function: traceFunctionName,
|
|
1454
1910
|
callStack: snapshotCallStack(),
|
|
1455
|
-
visualization,
|
|
1456
1911
|
});
|
|
1457
1912
|
},
|
|
1458
1913
|
recordReturn(lineNumber, returnValue, functionNameOverride) {
|
|
1914
|
+
if (traceLimitExceeded) {
|
|
1915
|
+
return;
|
|
1916
|
+
}
|
|
1459
1917
|
const normalizedLine = normalizeLine(lineNumber, callStack[callStack.length - 1]?.line ?? 1);
|
|
1460
1918
|
const functionName =
|
|
1461
1919
|
typeof functionNameOverride === 'string' && functionNameOverride.length > 0
|
|
@@ -1463,9 +1921,6 @@ function createTraceRecorder(options = {}) {
|
|
|
1463
1921
|
: callStack[callStack.length - 1]?.function ?? '<module>';
|
|
1464
1922
|
const serializedReturnValue = serializeValue(returnValue);
|
|
1465
1923
|
const variables = functionName === '<module>' ? { result: serializedReturnValue } : {};
|
|
1466
|
-
const visualization = functionName === '<module>'
|
|
1467
|
-
? buildVisualizationPayload({ result: returnValue })
|
|
1468
|
-
: undefined;
|
|
1469
1924
|
|
|
1470
1925
|
appendTrace({
|
|
1471
1926
|
line: normalizedLine,
|
|
@@ -1474,10 +1929,12 @@ function createTraceRecorder(options = {}) {
|
|
|
1474
1929
|
function: functionName,
|
|
1475
1930
|
callStack: snapshotCallStack(),
|
|
1476
1931
|
returnValue: serializedReturnValue,
|
|
1477
|
-
visualization,
|
|
1478
1932
|
});
|
|
1479
1933
|
},
|
|
1480
1934
|
recordException(lineNumber, error, functionNameOverride) {
|
|
1935
|
+
if (traceLimitExceeded) {
|
|
1936
|
+
return;
|
|
1937
|
+
}
|
|
1481
1938
|
const normalizedLine = normalizeLine(lineNumber, callStack[callStack.length - 1]?.line ?? 1);
|
|
1482
1939
|
appendTrace({
|
|
1483
1940
|
line: normalizedLine,
|
|
@@ -1491,6 +1948,21 @@ function createTraceRecorder(options = {}) {
|
|
|
1491
1948
|
returnValue: error instanceof Error ? error.message : String(error),
|
|
1492
1949
|
});
|
|
1493
1950
|
},
|
|
1951
|
+
recordStdout(lineNumber, text) {
|
|
1952
|
+
if (traceLimitExceeded) {
|
|
1953
|
+
return;
|
|
1954
|
+
}
|
|
1955
|
+
const normalizedLine = normalizeLine(lineNumber, callStack[callStack.length - 1]?.line ?? 1);
|
|
1956
|
+
appendTrace({
|
|
1957
|
+
line: normalizedLine,
|
|
1958
|
+
event: 'stdout',
|
|
1959
|
+
variables: {},
|
|
1960
|
+
function: callStack[callStack.length - 1]?.function ?? '<module>',
|
|
1961
|
+
callStack: snapshotCallStack(),
|
|
1962
|
+
stdoutLineCount: 1,
|
|
1963
|
+
returnValue: String(text ?? ''),
|
|
1964
|
+
});
|
|
1965
|
+
},
|
|
1494
1966
|
popCall() {
|
|
1495
1967
|
if (callStack.length > 0) {
|
|
1496
1968
|
const frame = callStack.pop();
|
|
@@ -1513,6 +1985,21 @@ function createTraceRecorder(options = {}) {
|
|
|
1513
1985
|
getTrace() {
|
|
1514
1986
|
return trace;
|
|
1515
1987
|
},
|
|
1988
|
+
getRuntimeTrace(language, runId = `${language}:run`, file) {
|
|
1989
|
+
const events = runtimeTraceEvents.map((event) => ({
|
|
1990
|
+
...event,
|
|
1991
|
+
runId,
|
|
1992
|
+
...(file ? { file } : {}),
|
|
1993
|
+
}));
|
|
1994
|
+
return {
|
|
1995
|
+
schemaVersion: RUNTIME_TRACE_SCHEMA_VERSION,
|
|
1996
|
+
language,
|
|
1997
|
+
runId,
|
|
1998
|
+
events,
|
|
1999
|
+
lineEventCount: events.filter((event) => event.kind === 'line').length,
|
|
2000
|
+
traceStepCount: events.length,
|
|
2001
|
+
};
|
|
2002
|
+
},
|
|
1516
2003
|
getLineEventCount() {
|
|
1517
2004
|
return lineEventCount;
|
|
1518
2005
|
},
|
|
@@ -1672,6 +2159,75 @@ function createSyntheticTrace(payload, codeResult) {
|
|
|
1672
2159
|
];
|
|
1673
2160
|
}
|
|
1674
2161
|
|
|
2162
|
+
function createEmptyRuntimeTrace(language, runId = `${language}:run`) {
|
|
2163
|
+
return {
|
|
2164
|
+
schemaVersion: RUNTIME_TRACE_SCHEMA_VERSION,
|
|
2165
|
+
language,
|
|
2166
|
+
runId,
|
|
2167
|
+
events: [],
|
|
2168
|
+
lineEventCount: 0,
|
|
2169
|
+
traceStepCount: 0,
|
|
2170
|
+
};
|
|
2171
|
+
}
|
|
2172
|
+
|
|
2173
|
+
function defaultRuntimeTraceFile(language) {
|
|
2174
|
+
return language === 'typescript' ? 'solution.ts' : 'solution.js';
|
|
2175
|
+
}
|
|
2176
|
+
|
|
2177
|
+
function createSyntheticRuntimeTrace(payload, codeResult, language) {
|
|
2178
|
+
const syntheticTrace = createSyntheticTrace(payload, codeResult);
|
|
2179
|
+
const runId = `${language}:run`;
|
|
2180
|
+
const file = defaultRuntimeTraceFile(language);
|
|
2181
|
+
const events = [];
|
|
2182
|
+
for (const step of syntheticTrace) {
|
|
2183
|
+
const base = {
|
|
2184
|
+
runId,
|
|
2185
|
+
file,
|
|
2186
|
+
line: step.line,
|
|
2187
|
+
frameId: runtimeTraceFrameIdForSyntheticStep(step),
|
|
2188
|
+
};
|
|
2189
|
+
if (step.event === 'call') {
|
|
2190
|
+
events.push({ ...base, kind: 'call', function: step.function, args: step.callStack?.at(-1)?.args });
|
|
2191
|
+
} else if (step.event === 'line') {
|
|
2192
|
+
events.push({ ...base, kind: 'line', function: step.function });
|
|
2193
|
+
} else if (step.event === 'return') {
|
|
2194
|
+
events.push({ ...base, kind: 'return', function: step.function, value: step.returnValue });
|
|
2195
|
+
}
|
|
2196
|
+
for (const [variable, value] of Object.entries(step.variables ?? {})) {
|
|
2197
|
+
events.push({ ...base, kind: 'snapshot', target: { variable }, value });
|
|
2198
|
+
}
|
|
2199
|
+
}
|
|
2200
|
+
return {
|
|
2201
|
+
schemaVersion: RUNTIME_TRACE_SCHEMA_VERSION,
|
|
2202
|
+
language,
|
|
2203
|
+
runId,
|
|
2204
|
+
events,
|
|
2205
|
+
lineEventCount: events.filter((event) => event.kind === 'line').length,
|
|
2206
|
+
traceStepCount: events.length,
|
|
2207
|
+
};
|
|
2208
|
+
}
|
|
2209
|
+
|
|
2210
|
+
const RUNTIME_TRACE_SCHEMA_VERSION = 'runtime-trace-2026-04-28';
|
|
2211
|
+
|
|
2212
|
+
function runtimeTraceFrameIdForSyntheticStep(step) {
|
|
2213
|
+
const stack = Array.isArray(step?.callStack) ? step.callStack : [];
|
|
2214
|
+
if (stack.length > 0) {
|
|
2215
|
+
const frame = stack[stack.length - 1];
|
|
2216
|
+
return `${frame.function}:${frame.line}`;
|
|
2217
|
+
}
|
|
2218
|
+
return `${step.function}:${step.line}`;
|
|
2219
|
+
}
|
|
2220
|
+
|
|
2221
|
+
function valueAtPath(value, path) {
|
|
2222
|
+
if (!Array.isArray(path) || path.length === 0) return value;
|
|
2223
|
+
let current = value;
|
|
2224
|
+
for (const part of path) {
|
|
2225
|
+
if (current === null || current === undefined || typeof current !== 'object') return undefined;
|
|
2226
|
+
current = current[String(part)];
|
|
2227
|
+
}
|
|
2228
|
+
return current;
|
|
2229
|
+
}
|
|
2230
|
+
|
|
1675
2231
|
function getTypeScriptCompiler() {
|
|
1676
2232
|
const ts = self?.ts;
|
|
1677
2233
|
if (ts && typeof ts.transpileModule === 'function') {
|
|
@@ -1755,6 +2311,7 @@ function transpileTypeScript(sourceCode) {
|
|
|
1755
2311
|
}
|
|
1756
2312
|
|
|
1757
2313
|
async function prepareExecutableCode(sourceCode, language) {
|
|
2314
|
+
ensureJavaScriptLibraries();
|
|
1758
2315
|
if (language === 'typescript') {
|
|
1759
2316
|
await ensureTypeScriptCompiler();
|
|
1760
2317
|
return transpileTypeScript(sourceCode);
|
|
@@ -1780,6 +2337,51 @@ function addBindingNames(ts, nameNode, names) {
|
|
|
1780
2337
|
}
|
|
1781
2338
|
}
|
|
1782
2339
|
|
|
2340
|
+
function collectBindingNames(ts, nameNode) {
|
|
2341
|
+
const names = new Set();
|
|
2342
|
+
addBindingNames(ts, nameNode, names);
|
|
2343
|
+
return [...names];
|
|
2344
|
+
}
|
|
2345
|
+
|
|
2346
|
+
function addAssignmentTargetNames(ts, node, names) {
|
|
2347
|
+
if (!node) return;
|
|
2348
|
+
if (ts.isParenthesizedExpression(node)) {
|
|
2349
|
+
addAssignmentTargetNames(ts, node.expression, names);
|
|
2350
|
+
return;
|
|
2351
|
+
}
|
|
2352
|
+
if (ts.isIdentifier(node)) {
|
|
2353
|
+
if (!node.text.startsWith('__trace')) names.add(node.text);
|
|
2354
|
+
return;
|
|
2355
|
+
}
|
|
2356
|
+
if (ts.isArrayLiteralExpression(node)) {
|
|
2357
|
+
for (const element of node.elements) {
|
|
2358
|
+
if (ts.isSpreadElement(element)) {
|
|
2359
|
+
addAssignmentTargetNames(ts, element.expression, names);
|
|
2360
|
+
} else {
|
|
2361
|
+
addAssignmentTargetNames(ts, element, names);
|
|
2362
|
+
}
|
|
2363
|
+
}
|
|
2364
|
+
return;
|
|
2365
|
+
}
|
|
2366
|
+
if (ts.isObjectLiteralExpression(node)) {
|
|
2367
|
+
for (const property of node.properties) {
|
|
2368
|
+
if (ts.isShorthandPropertyAssignment(property)) {
|
|
2369
|
+
addAssignmentTargetNames(ts, property.name, names);
|
|
2370
|
+
} else if (ts.isPropertyAssignment(property)) {
|
|
2371
|
+
addAssignmentTargetNames(ts, property.initializer, names);
|
|
2372
|
+
} else if (ts.isSpreadAssignment(property)) {
|
|
2373
|
+
addAssignmentTargetNames(ts, property.expression, names);
|
|
2374
|
+
}
|
|
2375
|
+
}
|
|
2376
|
+
}
|
|
2377
|
+
}
|
|
2378
|
+
|
|
2379
|
+
function collectAssignmentTargetNames(ts, node) {
|
|
2380
|
+
const names = new Set();
|
|
2381
|
+
addAssignmentTargetNames(ts, node, names);
|
|
2382
|
+
return [...names];
|
|
2383
|
+
}
|
|
2384
|
+
|
|
1783
2385
|
function collectTraceVariableNames(ts, sourceFile) {
|
|
1784
2386
|
const names = new Set();
|
|
1785
2387
|
|
|
@@ -1793,11 +2395,10 @@ function collectTraceVariableNames(ts, sourceFile) {
|
|
|
1793
2395
|
} else if (
|
|
1794
2396
|
ts.isBinaryExpression(node) &&
|
|
1795
2397
|
node.left &&
|
|
1796
|
-
ts.isIdentifier(node.left) &&
|
|
1797
2398
|
node.operatorToken.kind >= ts.SyntaxKind.FirstAssignment &&
|
|
1798
2399
|
node.operatorToken.kind <= ts.SyntaxKind.LastAssignment
|
|
1799
2400
|
) {
|
|
1800
|
-
|
|
2401
|
+
addAssignmentTargetNames(ts, node.left, names);
|
|
1801
2402
|
}
|
|
1802
2403
|
ts.forEachChild(node, visit);
|
|
1803
2404
|
}
|
|
@@ -1817,6 +2418,95 @@ function shouldTraceStatement(ts, statement) {
|
|
|
1817
2418
|
);
|
|
1818
2419
|
}
|
|
1819
2420
|
|
|
2421
|
+
function shouldMapStatementLineForFunctionContext(ts, statement) {
|
|
2422
|
+
return (
|
|
2423
|
+
shouldTraceStatement(ts, statement) ||
|
|
2424
|
+
ts.isWhileStatement(statement) ||
|
|
2425
|
+
ts.isForStatement(statement) ||
|
|
2426
|
+
ts.isForOfStatement(statement)
|
|
2427
|
+
);
|
|
2428
|
+
}
|
|
2429
|
+
|
|
2430
|
+
function isSingleLineNode(sourceFile, node) {
|
|
2431
|
+
const start = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line;
|
|
2432
|
+
const end = sourceFile.getLineAndCharacterOfPosition(node.getEnd()).line;
|
|
2433
|
+
return start === end;
|
|
2434
|
+
}
|
|
2435
|
+
|
|
2436
|
+
function statementBypassesFollowingTraceLine(ts, statement) {
|
|
2437
|
+
if (
|
|
2438
|
+
ts.isBreakStatement(statement) ||
|
|
2439
|
+
ts.isContinueStatement(statement) ||
|
|
2440
|
+
ts.isReturnStatement(statement) ||
|
|
2441
|
+
ts.isThrowStatement(statement)
|
|
2442
|
+
) {
|
|
2443
|
+
return true;
|
|
2444
|
+
}
|
|
2445
|
+
if (ts.isBlock(statement)) {
|
|
2446
|
+
return statement.statements.some((nested) => statementBypassesFollowingTraceLine(ts, nested));
|
|
2447
|
+
}
|
|
2448
|
+
return false;
|
|
2449
|
+
}
|
|
2450
|
+
|
|
2451
|
+
function shouldTraceIfStatementPostLine(ts, sourceFile, statement) {
|
|
2452
|
+
if (!isSingleLineNode(sourceFile, statement)) {
|
|
2453
|
+
return false;
|
|
2454
|
+
}
|
|
2455
|
+
if (statementBypassesFollowingTraceLine(ts, statement.thenStatement)) {
|
|
2456
|
+
return false;
|
|
2457
|
+
}
|
|
2458
|
+
if (statement.elseStatement && statementBypassesFollowingTraceLine(ts, statement.elseStatement)) {
|
|
2459
|
+
return false;
|
|
2460
|
+
}
|
|
2461
|
+
return true;
|
|
2462
|
+
}
|
|
2463
|
+
|
|
2464
|
+
function isPostLineStateStatement(ts, sourceFile, statement) {
|
|
2465
|
+
if (ts.isVariableStatement(statement)) {
|
|
2466
|
+
return true;
|
|
2467
|
+
}
|
|
2468
|
+
if (ts.isIfStatement(statement) && shouldTraceIfStatementPostLine(ts, sourceFile, statement)) {
|
|
2469
|
+
return true;
|
|
2470
|
+
}
|
|
2471
|
+
if (!ts.isExpressionStatement(statement)) {
|
|
2472
|
+
return false;
|
|
2473
|
+
}
|
|
2474
|
+
const expression = statement.expression;
|
|
2475
|
+
if (
|
|
2476
|
+
(ts.isPrefixUnaryExpression(expression) || ts.isPostfixUnaryExpression(expression)) &&
|
|
2477
|
+
ts.isIdentifier(expression.operand) &&
|
|
2478
|
+
(expression.operator === ts.SyntaxKind.PlusPlusToken ||
|
|
2479
|
+
expression.operator === ts.SyntaxKind.MinusMinusToken)
|
|
2480
|
+
) {
|
|
2481
|
+
return true;
|
|
2482
|
+
}
|
|
2483
|
+
if (
|
|
2484
|
+
ts.isBinaryExpression(expression) &&
|
|
2485
|
+
isAssignmentOperatorToken(ts, expression.operatorToken.kind) &&
|
|
2486
|
+
ts.isIdentifier(expression.left)
|
|
2487
|
+
) {
|
|
2488
|
+
return true;
|
|
2489
|
+
}
|
|
2490
|
+
if (isTraceStateMutationHelperCall(ts, expression)) {
|
|
2491
|
+
return true;
|
|
2492
|
+
}
|
|
2493
|
+
return false;
|
|
2494
|
+
}
|
|
2495
|
+
|
|
2496
|
+
function isTraceStateMutationHelperCall(ts, expression) {
|
|
2497
|
+
let current = unwrapParenthesizedExpression(ts, expression);
|
|
2498
|
+
if (!current || !ts.isCallExpression(current) || !ts.isIdentifier(current.expression)) {
|
|
2499
|
+
return false;
|
|
2500
|
+
}
|
|
2501
|
+
return [
|
|
2502
|
+
'__traceMutatingCall',
|
|
2503
|
+
'__traceWriteIndex',
|
|
2504
|
+
'__traceAugAssignIndex',
|
|
2505
|
+
'__traceUpdateIndex',
|
|
2506
|
+
'__traceUpdateScalar',
|
|
2507
|
+
].includes(current.expression.text);
|
|
2508
|
+
}
|
|
2509
|
+
|
|
1820
2510
|
function getNodeNameText(ts, nameNode) {
|
|
1821
2511
|
if (!nameNode) return null;
|
|
1822
2512
|
if (ts.isIdentifier(nameNode) || ts.isPrivateIdentifier(nameNode)) {
|
|
@@ -1857,7 +2547,8 @@ function inferTraceFunctionName(ts, node, fallbackFunctionName) {
|
|
|
1857
2547
|
}
|
|
1858
2548
|
|
|
1859
2549
|
if (ts.isArrowFunction(node) || ts.isFunctionExpression(node)) {
|
|
1860
|
-
const
|
|
2550
|
+
const originalNode = ts.getOriginalNode(node);
|
|
2551
|
+
const parent = node.parent ?? originalNode?.parent;
|
|
1861
2552
|
if (parent && ts.isVariableDeclaration(parent) && ts.isIdentifier(parent.name)) {
|
|
1862
2553
|
return parent.name.text;
|
|
1863
2554
|
}
|
|
@@ -1918,7 +2609,7 @@ function buildLineFunctionMap(ts, sourceFile, defaultFunctionName) {
|
|
|
1918
2609
|
return;
|
|
1919
2610
|
}
|
|
1920
2611
|
|
|
1921
|
-
if (ts.isStatement(node) &&
|
|
2612
|
+
if (ts.isStatement(node) && shouldMapStatementLineForFunctionContext(ts, node)) {
|
|
1922
2613
|
mapStatementLine(node, currentFunctionName, currentFunctionStartLine, includeThisSnapshot);
|
|
1923
2614
|
}
|
|
1924
2615
|
|
|
@@ -1931,7 +2622,14 @@ function buildLineFunctionMap(ts, sourceFile, defaultFunctionName) {
|
|
|
1931
2622
|
|
|
1932
2623
|
function unwrapParenthesizedExpression(ts, node) {
|
|
1933
2624
|
let current = node;
|
|
1934
|
-
while (
|
|
2625
|
+
while (
|
|
2626
|
+
current &&
|
|
2627
|
+
(ts.isParenthesizedExpression(current) ||
|
|
2628
|
+
(typeof ts.isAsExpression === 'function' && ts.isAsExpression(current)) ||
|
|
2629
|
+
(typeof ts.isTypeAssertionExpression === 'function' && ts.isTypeAssertionExpression(current)) ||
|
|
2630
|
+
(typeof ts.isSatisfiesExpression === 'function' && ts.isSatisfiesExpression(current)) ||
|
|
2631
|
+
(typeof ts.isNonNullExpression === 'function' && ts.isNonNullExpression(current)))
|
|
2632
|
+
) {
|
|
1935
2633
|
current = current.expression;
|
|
1936
2634
|
}
|
|
1937
2635
|
return current;
|
|
@@ -1951,6 +2649,16 @@ function isAssignmentLikeLeftOperand(ts, node) {
|
|
|
1951
2649
|
);
|
|
1952
2650
|
}
|
|
1953
2651
|
|
|
2652
|
+
function isTraceablePropertyWriteLeftOperand(ts, node) {
|
|
2653
|
+
const parent = node?.parent;
|
|
2654
|
+
return Boolean(
|
|
2655
|
+
parent &&
|
|
2656
|
+
ts.isBinaryExpression(parent) &&
|
|
2657
|
+
parent.left === node &&
|
|
2658
|
+
parent.operatorToken.kind === ts.SyntaxKind.EqualsToken
|
|
2659
|
+
);
|
|
2660
|
+
}
|
|
2661
|
+
|
|
1954
2662
|
function isUpdateExpressionOperand(ts, node) {
|
|
1955
2663
|
const parent = node?.parent;
|
|
1956
2664
|
if (!parent) return false;
|
|
@@ -2006,21 +2714,71 @@ function extractTraceableElementAccess(ts, node) {
|
|
|
2006
2714
|
const indices = [];
|
|
2007
2715
|
let current = unwrapParenthesizedExpression(ts, node);
|
|
2008
2716
|
|
|
2009
|
-
while (current &&
|
|
2010
|
-
|
|
2011
|
-
|
|
2717
|
+
while (current && indices.length < 3) {
|
|
2718
|
+
if (ts.isElementAccessExpression(current)) {
|
|
2719
|
+
indices.unshift(current.argumentExpression);
|
|
2720
|
+
current = unwrapParenthesizedExpression(ts, current.expression);
|
|
2721
|
+
continue;
|
|
2722
|
+
}
|
|
2723
|
+
if (ts.isPropertyAccessExpression(current)) {
|
|
2724
|
+
indices.unshift(ts.factory.createStringLiteral(current.name.text));
|
|
2725
|
+
current = unwrapParenthesizedExpression(ts, current.expression);
|
|
2726
|
+
continue;
|
|
2727
|
+
}
|
|
2728
|
+
break;
|
|
2012
2729
|
}
|
|
2013
2730
|
|
|
2014
|
-
if (!current ||
|
|
2731
|
+
if (!current || indices.length === 0 || indices.length > 2) {
|
|
2732
|
+
return null;
|
|
2733
|
+
}
|
|
2734
|
+
if (ts.isThis(current)) {
|
|
2735
|
+
return {
|
|
2736
|
+
variableName: 'this',
|
|
2737
|
+
receiverExpression: ts.factory.createThis(),
|
|
2738
|
+
indices,
|
|
2739
|
+
};
|
|
2740
|
+
}
|
|
2741
|
+
if (!ts.isIdentifier(current)) {
|
|
2015
2742
|
return null;
|
|
2016
2743
|
}
|
|
2017
2744
|
|
|
2018
2745
|
return {
|
|
2019
2746
|
variableName: current.text,
|
|
2747
|
+
receiverExpression: ts.factory.createIdentifier(current.text),
|
|
2020
2748
|
indices,
|
|
2021
2749
|
};
|
|
2022
2750
|
}
|
|
2023
2751
|
|
|
2752
|
+
function extractTraceablePropertyAccess(ts, node) {
|
|
2753
|
+
const current = unwrapParenthesizedExpression(ts, node);
|
|
2754
|
+
if (!current || !ts.isPropertyAccessExpression(current)) {
|
|
2755
|
+
return null;
|
|
2756
|
+
}
|
|
2757
|
+
const receiver = unwrapParenthesizedExpression(ts, current.expression);
|
|
2758
|
+
if (!receiver) {
|
|
2759
|
+
return null;
|
|
2760
|
+
}
|
|
2761
|
+
if (ts.isThis(receiver)) {
|
|
2762
|
+
return {
|
|
2763
|
+
variableName: 'this',
|
|
2764
|
+
propertyName: current.name.text,
|
|
2765
|
+
scope: 'receiver',
|
|
2766
|
+
};
|
|
2767
|
+
}
|
|
2768
|
+
if (!ts.isIdentifier(receiver)) {
|
|
2769
|
+
return null;
|
|
2770
|
+
}
|
|
2771
|
+
return {
|
|
2772
|
+
variableName: receiver.text,
|
|
2773
|
+
propertyName: current.name.text,
|
|
2774
|
+
};
|
|
2775
|
+
}
|
|
2776
|
+
|
|
2777
|
+
function runtimeScopeForTraceableReceiver(receiverName, localVariableNames) {
|
|
2778
|
+
if (receiverName === 'this') return 'receiver';
|
|
2779
|
+
return localVariableNames.has(receiverName) ? 'local' : 'global';
|
|
2780
|
+
}
|
|
2781
|
+
|
|
2024
2782
|
function extractTraceableMutatingCall(ts, node) {
|
|
2025
2783
|
if (!ts.isCallExpression(node) || !ts.isPropertyAccessExpression(node.expression)) {
|
|
2026
2784
|
return null;
|
|
@@ -2028,14 +2786,68 @@ function extractTraceableMutatingCall(ts, node) {
|
|
|
2028
2786
|
|
|
2029
2787
|
const receiver = unwrapParenthesizedExpression(ts, node.expression.expression);
|
|
2030
2788
|
const methodName = node.expression.name.text;
|
|
2031
|
-
if (!receiver || !
|
|
2789
|
+
if (!receiver || !isTraceableMutatingMethod(methodName)) {
|
|
2032
2790
|
return null;
|
|
2033
2791
|
}
|
|
2034
2792
|
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2793
|
+
if (ts.isIdentifier(receiver)) {
|
|
2794
|
+
return {
|
|
2795
|
+
variableName: receiver.text,
|
|
2796
|
+
receiverExpression: ts.factory.createIdentifier(receiver.text),
|
|
2797
|
+
methodName,
|
|
2798
|
+
indices: [],
|
|
2799
|
+
};
|
|
2800
|
+
}
|
|
2801
|
+
|
|
2802
|
+
if (
|
|
2803
|
+
ts.isPropertyAccessExpression(receiver) &&
|
|
2804
|
+
ts.isThis(unwrapParenthesizedExpression(ts, receiver.expression))
|
|
2805
|
+
) {
|
|
2806
|
+
return {
|
|
2807
|
+
variableName: 'this',
|
|
2808
|
+
receiverExpression: ts.factory.createThis(),
|
|
2809
|
+
methodName,
|
|
2810
|
+
indices: [ts.factory.createStringLiteral(receiver.name.text)],
|
|
2811
|
+
};
|
|
2812
|
+
}
|
|
2813
|
+
|
|
2814
|
+
const indexedReceiver = extractTraceableElementAccess(ts, receiver);
|
|
2815
|
+
if (indexedReceiver) {
|
|
2816
|
+
return {
|
|
2817
|
+
variableName: indexedReceiver.variableName,
|
|
2818
|
+
receiverExpression: indexedReceiver.receiverExpression,
|
|
2819
|
+
methodName,
|
|
2820
|
+
indices: indexedReceiver.indices,
|
|
2821
|
+
};
|
|
2822
|
+
}
|
|
2823
|
+
|
|
2824
|
+
if (
|
|
2825
|
+
ts.isCallExpression(receiver) &&
|
|
2826
|
+
ts.isPropertyAccessExpression(receiver.expression) &&
|
|
2827
|
+
receiver.expression.name.text === 'get' &&
|
|
2828
|
+
receiver.arguments.length === 1
|
|
2829
|
+
) {
|
|
2830
|
+
const mapReceiver = unwrapParenthesizedExpression(ts, receiver.expression.expression);
|
|
2831
|
+
if (ts.isIdentifier(mapReceiver)) {
|
|
2832
|
+
return {
|
|
2833
|
+
variableName: mapReceiver.text,
|
|
2834
|
+
receiverExpression: ts.factory.createIdentifier(mapReceiver.text),
|
|
2835
|
+
methodName,
|
|
2836
|
+
indices: [receiver.arguments[0]],
|
|
2837
|
+
};
|
|
2838
|
+
}
|
|
2839
|
+
const tracedMapReceiver = extractTraceableElementAccess(ts, mapReceiver);
|
|
2840
|
+
if (tracedMapReceiver) {
|
|
2841
|
+
return {
|
|
2842
|
+
variableName: tracedMapReceiver.variableName,
|
|
2843
|
+
receiverExpression: tracedMapReceiver.receiverExpression,
|
|
2844
|
+
methodName,
|
|
2845
|
+
indices: [...tracedMapReceiver.indices, receiver.arguments[0]],
|
|
2846
|
+
};
|
|
2847
|
+
}
|
|
2848
|
+
}
|
|
2849
|
+
|
|
2850
|
+
return null;
|
|
2039
2851
|
}
|
|
2040
2852
|
|
|
2041
2853
|
function getCompoundAssignmentOperatorName(ts, tokenKind) {
|
|
@@ -2071,24 +2883,275 @@ function createIndicesArrayExpression(ts, indices) {
|
|
|
2071
2883
|
return ts.factory.createArrayLiteralExpression(indices, false);
|
|
2072
2884
|
}
|
|
2073
2885
|
|
|
2074
|
-
function
|
|
2886
|
+
function createIndexSourcesArrayExpression(ts, sourceFile, indices) {
|
|
2887
|
+
return ts.factory.createArrayLiteralExpression(
|
|
2888
|
+
indices.map((index) => {
|
|
2889
|
+
const source = indexSourceExpressionText(ts, sourceFile, index);
|
|
2890
|
+
return source ? ts.factory.createStringLiteral(source) : ts.factory.createNull();
|
|
2891
|
+
}),
|
|
2892
|
+
false
|
|
2893
|
+
);
|
|
2894
|
+
}
|
|
2895
|
+
|
|
2896
|
+
function indexSourceExpressionText(ts, sourceFile, index) {
|
|
2897
|
+
if (ts.isIdentifier(index)) return index.text;
|
|
2898
|
+
if (typeof index.pos === 'number' && index.pos < 0) return null;
|
|
2899
|
+
let text = '';
|
|
2900
|
+
try {
|
|
2901
|
+
text = typeof index.getText === 'function' ? index.getText(sourceFile).trim().replace(/\s+/g, ' ') : '';
|
|
2902
|
+
} catch {
|
|
2903
|
+
text = '';
|
|
2904
|
+
}
|
|
2905
|
+
if (!text) return null;
|
|
2906
|
+
return isSafeIndexSourceExpression(ts, index) ? text : null;
|
|
2907
|
+
}
|
|
2908
|
+
|
|
2909
|
+
function isSafeIndexSourceExpression(ts, node) {
|
|
2910
|
+
const unwrapped = unwrapParenthesizedExpression(ts, node);
|
|
2911
|
+
if (!unwrapped) return false;
|
|
2912
|
+
if (ts.isIdentifier(unwrapped) || ts.isNumericLiteral(unwrapped) || ts.isStringLiteral(unwrapped)) {
|
|
2913
|
+
return true;
|
|
2914
|
+
}
|
|
2915
|
+
if (unwrapped.kind === ts.SyntaxKind.ThisKeyword) {
|
|
2916
|
+
return true;
|
|
2917
|
+
}
|
|
2918
|
+
if (ts.isPrefixUnaryExpression(unwrapped)) {
|
|
2919
|
+
if (
|
|
2920
|
+
(unwrapped.operator === ts.SyntaxKind.PlusPlusToken || unwrapped.operator === ts.SyntaxKind.MinusMinusToken) &&
|
|
2921
|
+
ts.isIdentifier(unwrapped.operand)
|
|
2922
|
+
) {
|
|
2923
|
+
return true;
|
|
2924
|
+
}
|
|
2925
|
+
return (
|
|
2926
|
+
(unwrapped.operator === ts.SyntaxKind.PlusToken || unwrapped.operator === ts.SyntaxKind.MinusToken) &&
|
|
2927
|
+
isSafeIndexSourceExpression(ts, unwrapped.operand)
|
|
2928
|
+
);
|
|
2929
|
+
}
|
|
2930
|
+
if (ts.isPostfixUnaryExpression(unwrapped)) {
|
|
2931
|
+
return (
|
|
2932
|
+
(unwrapped.operator === ts.SyntaxKind.PlusPlusToken || unwrapped.operator === ts.SyntaxKind.MinusMinusToken) &&
|
|
2933
|
+
ts.isIdentifier(unwrapped.operand)
|
|
2934
|
+
);
|
|
2935
|
+
}
|
|
2936
|
+
if (ts.isPropertyAccessExpression(unwrapped)) {
|
|
2937
|
+
return isSafeIndexSourceExpression(ts, unwrapped.expression);
|
|
2938
|
+
}
|
|
2939
|
+
if (ts.isElementAccessExpression(unwrapped)) {
|
|
2940
|
+
return (
|
|
2941
|
+
isSafeIndexSourceExpression(ts, unwrapped.expression) &&
|
|
2942
|
+
Boolean(unwrapped.argumentExpression) &&
|
|
2943
|
+
isSafeIndexSourceExpression(ts, unwrapped.argumentExpression)
|
|
2944
|
+
);
|
|
2945
|
+
}
|
|
2946
|
+
if (ts.isCallExpression(unwrapped)) {
|
|
2947
|
+
const expression = unwrapParenthesizedExpression(ts, unwrapped.expression);
|
|
2948
|
+
if (!expression || !ts.isPropertyAccessExpression(expression)) return false;
|
|
2949
|
+
const safeIndexMethods = new Set(['at', 'charAt', 'charCodeAt', 'codePointAt']);
|
|
2950
|
+
return (
|
|
2951
|
+
safeIndexMethods.has(expression.name.text) &&
|
|
2952
|
+
isSafeIndexSourceExpression(ts, expression.expression) &&
|
|
2953
|
+
unwrapped.arguments.every((argument) => isSafeIndexSourceExpression(ts, argument))
|
|
2954
|
+
);
|
|
2955
|
+
}
|
|
2956
|
+
if (ts.isBinaryExpression(unwrapped)) {
|
|
2957
|
+
const allowedOperators = new Set([
|
|
2958
|
+
ts.SyntaxKind.PlusToken,
|
|
2959
|
+
ts.SyntaxKind.MinusToken,
|
|
2960
|
+
ts.SyntaxKind.AsteriskToken,
|
|
2961
|
+
ts.SyntaxKind.SlashToken,
|
|
2962
|
+
ts.SyntaxKind.PercentToken,
|
|
2963
|
+
]);
|
|
2964
|
+
return (
|
|
2965
|
+
allowedOperators.has(unwrapped.operatorToken.kind) &&
|
|
2966
|
+
isSafeIndexSourceExpression(ts, unwrapped.left) &&
|
|
2967
|
+
isSafeIndexSourceExpression(ts, unwrapped.right)
|
|
2968
|
+
);
|
|
2969
|
+
}
|
|
2970
|
+
return false;
|
|
2971
|
+
}
|
|
2972
|
+
|
|
2973
|
+
function createTraceReadIndexExpression(ts, sourceFile, node, variableName, indices, indexSourceExpressions = indices) {
|
|
2974
|
+
const receiverExpression = variableName === 'this'
|
|
2975
|
+
? ts.factory.createThis()
|
|
2976
|
+
: ts.factory.createIdentifier(variableName);
|
|
2977
|
+
return createTraceReadIndexExpressionForReceiver(
|
|
2978
|
+
ts,
|
|
2979
|
+
sourceFile,
|
|
2980
|
+
node,
|
|
2981
|
+
variableName,
|
|
2982
|
+
receiverExpression,
|
|
2983
|
+
indices,
|
|
2984
|
+
indexSourceExpressions
|
|
2985
|
+
);
|
|
2986
|
+
}
|
|
2987
|
+
|
|
2988
|
+
function createTraceReadIndexExpressionForReceiver(
|
|
2989
|
+
ts,
|
|
2990
|
+
sourceFile,
|
|
2991
|
+
node,
|
|
2992
|
+
variableName,
|
|
2993
|
+
receiverExpression,
|
|
2994
|
+
indices,
|
|
2995
|
+
indexSourceExpressions = indices
|
|
2996
|
+
) {
|
|
2075
2997
|
return ts.factory.createCallExpression(ts.factory.createIdentifier('__traceReadIndex'), undefined, [
|
|
2076
2998
|
ts.factory.createStringLiteral(variableName),
|
|
2077
|
-
|
|
2999
|
+
receiverExpression,
|
|
2078
3000
|
createIndicesArrayExpression(ts, indices),
|
|
3001
|
+
createIndexSourcesArrayExpression(ts, sourceFile, indexSourceExpressions),
|
|
3002
|
+
createSourceLocationObject(ts, sourceFile, node),
|
|
2079
3003
|
]);
|
|
2080
3004
|
}
|
|
2081
3005
|
|
|
2082
|
-
function createTraceWriteIndexExpression(ts, variableName, indices, value) {
|
|
3006
|
+
function createTraceWriteIndexExpression(ts, sourceFile, node, variableName, indices, value, indexSourceExpressions = indices) {
|
|
3007
|
+
const receiverExpression = variableName === 'this'
|
|
3008
|
+
? ts.factory.createThis()
|
|
3009
|
+
: ts.factory.createIdentifier(variableName);
|
|
2083
3010
|
return ts.factory.createCallExpression(ts.factory.createIdentifier('__traceWriteIndex'), undefined, [
|
|
2084
3011
|
ts.factory.createStringLiteral(variableName),
|
|
2085
|
-
|
|
3012
|
+
receiverExpression,
|
|
2086
3013
|
createIndicesArrayExpression(ts, indices),
|
|
3014
|
+
createIndexSourcesArrayExpression(ts, sourceFile, indexSourceExpressions),
|
|
2087
3015
|
value,
|
|
3016
|
+
createSourceLocationObject(ts, sourceFile, node),
|
|
2088
3017
|
]);
|
|
2089
3018
|
}
|
|
2090
3019
|
|
|
2091
|
-
function
|
|
3020
|
+
function createSourceLocationObject(ts, sourceFile, node) {
|
|
3021
|
+
const position = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));
|
|
3022
|
+
return ts.factory.createObjectLiteralExpression(
|
|
3023
|
+
[
|
|
3024
|
+
ts.factory.createPropertyAssignment('line', ts.factory.createNumericLiteral(position.line + 1)),
|
|
3025
|
+
ts.factory.createPropertyAssignment('column', ts.factory.createNumericLiteral(position.character + 1)),
|
|
3026
|
+
],
|
|
3027
|
+
false
|
|
3028
|
+
);
|
|
3029
|
+
}
|
|
3030
|
+
|
|
3031
|
+
function createTraceReadPropertyExpression(ts, sourceFile, node, variableName, propertyName, scope) {
|
|
3032
|
+
const receiverExpression = variableName === 'this'
|
|
3033
|
+
? ts.factory.createThis()
|
|
3034
|
+
: ts.factory.createIdentifier(variableName);
|
|
3035
|
+
const args = [
|
|
3036
|
+
ts.factory.createStringLiteral(variableName),
|
|
3037
|
+
receiverExpression,
|
|
3038
|
+
ts.factory.createStringLiteral(propertyName),
|
|
3039
|
+
];
|
|
3040
|
+
if (scope) {
|
|
3041
|
+
args.push(ts.factory.createStringLiteral(scope));
|
|
3042
|
+
}
|
|
3043
|
+
args.push(createSourceLocationObject(ts, sourceFile, node));
|
|
3044
|
+
return ts.factory.createCallExpression(ts.factory.createIdentifier('__traceReadProperty'), undefined, args);
|
|
3045
|
+
}
|
|
3046
|
+
|
|
3047
|
+
function createTraceWritePropertyExpression(ts, sourceFile, node, variableName, propertyName, value) {
|
|
3048
|
+
const receiverExpression = variableName === 'this'
|
|
3049
|
+
? ts.factory.createThis()
|
|
3050
|
+
: ts.factory.createIdentifier(variableName);
|
|
3051
|
+
return ts.factory.createCallExpression(ts.factory.createIdentifier('__traceWriteIndex'), undefined, [
|
|
3052
|
+
ts.factory.createStringLiteral(variableName),
|
|
3053
|
+
receiverExpression,
|
|
3054
|
+
createIndicesArrayExpression(ts, [ts.factory.createStringLiteral(propertyName)]),
|
|
3055
|
+
ts.factory.createArrayLiteralExpression([ts.factory.createNull()], false),
|
|
3056
|
+
value,
|
|
3057
|
+
createSourceLocationObject(ts, sourceFile, node),
|
|
3058
|
+
]);
|
|
3059
|
+
}
|
|
3060
|
+
|
|
3061
|
+
function createTraceScalarWriteExpression(ts, sourceFile, node, variableName, value) {
|
|
3062
|
+
return ts.factory.createCallExpression(ts.factory.createIdentifier('__traceAssignScalar'), undefined, [
|
|
3063
|
+
ts.factory.createStringLiteral(variableName),
|
|
3064
|
+
value,
|
|
3065
|
+
createSourceLocationObject(ts, sourceFile, node),
|
|
3066
|
+
]);
|
|
3067
|
+
}
|
|
3068
|
+
|
|
3069
|
+
function createTraceScalarUpdateExpression(ts, sourceFile, node, variableName, operatorName, isPrefix) {
|
|
3070
|
+
return ts.factory.createCallExpression(ts.factory.createIdentifier('__traceUpdateScalar'), undefined, [
|
|
3071
|
+
ts.factory.createStringLiteral(variableName),
|
|
3072
|
+
ts.factory.createArrowFunction(
|
|
3073
|
+
undefined,
|
|
3074
|
+
undefined,
|
|
3075
|
+
[],
|
|
3076
|
+
undefined,
|
|
3077
|
+
ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
|
|
3078
|
+
isPrefix
|
|
3079
|
+
? ts.factory.createPrefixUnaryExpression(
|
|
3080
|
+
operatorName === 'inc' ? ts.SyntaxKind.PlusPlusToken : ts.SyntaxKind.MinusMinusToken,
|
|
3081
|
+
ts.factory.createIdentifier(variableName)
|
|
3082
|
+
)
|
|
3083
|
+
: ts.factory.createPostfixUnaryExpression(
|
|
3084
|
+
ts.factory.createIdentifier(variableName),
|
|
3085
|
+
operatorName === 'inc' ? ts.SyntaxKind.PlusPlusToken : ts.SyntaxKind.MinusMinusToken
|
|
3086
|
+
)
|
|
3087
|
+
),
|
|
3088
|
+
ts.factory.createArrowFunction(
|
|
3089
|
+
undefined,
|
|
3090
|
+
undefined,
|
|
3091
|
+
[],
|
|
3092
|
+
undefined,
|
|
3093
|
+
ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
|
|
3094
|
+
ts.factory.createIdentifier(variableName)
|
|
3095
|
+
),
|
|
3096
|
+
isPrefix ? ts.factory.createTrue() : ts.factory.createFalse(),
|
|
3097
|
+
createSourceLocationObject(ts, sourceFile, node),
|
|
3098
|
+
]);
|
|
3099
|
+
}
|
|
3100
|
+
|
|
3101
|
+
function createTraceScalarWriteStatement(ts, sourceFile, node, variableName) {
|
|
3102
|
+
return ts.factory.createExpressionStatement(
|
|
3103
|
+
ts.factory.createCallExpression(ts.factory.createIdentifier('__traceScalarWrite'), undefined, [
|
|
3104
|
+
ts.factory.createStringLiteral(variableName),
|
|
3105
|
+
ts.factory.createIdentifier(variableName),
|
|
3106
|
+
createSourceLocationObject(ts, sourceFile, node),
|
|
3107
|
+
])
|
|
3108
|
+
);
|
|
3109
|
+
}
|
|
3110
|
+
|
|
3111
|
+
function traceScalarWriteStatementsForVariableStatement(ts, sourceFile, statement) {
|
|
3112
|
+
if (!ts.isVariableStatement(statement)) return [];
|
|
3113
|
+
const statements = [];
|
|
3114
|
+
for (const declaration of statement.declarationList.declarations) {
|
|
3115
|
+
if (!declaration.initializer) continue;
|
|
3116
|
+
if (
|
|
3117
|
+
ts.isArrowFunction(declaration.initializer) ||
|
|
3118
|
+
ts.isFunctionExpression(declaration.initializer) ||
|
|
3119
|
+
ts.isClassExpression(declaration.initializer)
|
|
3120
|
+
) {
|
|
3121
|
+
continue;
|
|
3122
|
+
}
|
|
3123
|
+
for (const variableName of collectBindingNames(ts, declaration.name)) {
|
|
3124
|
+
statements.push(createTraceScalarWriteStatement(ts, sourceFile, declaration.name, variableName));
|
|
3125
|
+
}
|
|
3126
|
+
}
|
|
3127
|
+
return statements;
|
|
3128
|
+
}
|
|
3129
|
+
|
|
3130
|
+
function traceScalarWriteStatementsForDestructuringAssignmentStatement(ts, sourceFile, statement) {
|
|
3131
|
+
if (!ts.isExpressionStatement(statement)) return [];
|
|
3132
|
+
const expression = ts.isParenthesizedExpression(statement.expression)
|
|
3133
|
+
? statement.expression.expression
|
|
3134
|
+
: statement.expression;
|
|
3135
|
+
if (!ts.isBinaryExpression(expression) || expression.operatorToken.kind !== ts.SyntaxKind.EqualsToken) {
|
|
3136
|
+
return [];
|
|
3137
|
+
}
|
|
3138
|
+
if (!ts.isArrayLiteralExpression(expression.left) && !ts.isObjectLiteralExpression(expression.left)) {
|
|
3139
|
+
return [];
|
|
3140
|
+
}
|
|
3141
|
+
return collectAssignmentTargetNames(ts, expression.left)
|
|
3142
|
+
.map((variableName) => createTraceScalarWriteStatement(ts, sourceFile, expression.left, variableName));
|
|
3143
|
+
}
|
|
3144
|
+
|
|
3145
|
+
function createTraceAugAssignExpression(
|
|
3146
|
+
ts,
|
|
3147
|
+
sourceFile,
|
|
3148
|
+
node,
|
|
3149
|
+
variableName,
|
|
3150
|
+
indices,
|
|
3151
|
+
operatorName,
|
|
3152
|
+
rhs,
|
|
3153
|
+
indexSourceExpressions = indices
|
|
3154
|
+
) {
|
|
2092
3155
|
return ts.factory.createCallExpression(
|
|
2093
3156
|
ts.factory.createIdentifier('__traceAugAssignIndex'),
|
|
2094
3157
|
undefined,
|
|
@@ -2096,13 +3159,24 @@ function createTraceAugAssignExpression(ts, variableName, indices, operatorName,
|
|
|
2096
3159
|
ts.factory.createStringLiteral(variableName),
|
|
2097
3160
|
ts.factory.createIdentifier(variableName),
|
|
2098
3161
|
createIndicesArrayExpression(ts, indices),
|
|
3162
|
+
createIndexSourcesArrayExpression(ts, sourceFile, indexSourceExpressions),
|
|
2099
3163
|
ts.factory.createStringLiteral(operatorName),
|
|
2100
3164
|
rhs,
|
|
3165
|
+
createSourceLocationObject(ts, sourceFile, node),
|
|
2101
3166
|
]
|
|
2102
3167
|
);
|
|
2103
3168
|
}
|
|
2104
3169
|
|
|
2105
|
-
function createTraceUpdateExpression(
|
|
3170
|
+
function createTraceUpdateExpression(
|
|
3171
|
+
ts,
|
|
3172
|
+
sourceFile,
|
|
3173
|
+
node,
|
|
3174
|
+
variableName,
|
|
3175
|
+
indices,
|
|
3176
|
+
operatorName,
|
|
3177
|
+
isPrefix,
|
|
3178
|
+
indexSourceExpressions = indices
|
|
3179
|
+
) {
|
|
2106
3180
|
return ts.factory.createCallExpression(
|
|
2107
3181
|
ts.factory.createIdentifier('__traceUpdateIndex'),
|
|
2108
3182
|
undefined,
|
|
@@ -2110,25 +3184,106 @@ function createTraceUpdateExpression(ts, variableName, indices, operatorName, is
|
|
|
2110
3184
|
ts.factory.createStringLiteral(variableName),
|
|
2111
3185
|
ts.factory.createIdentifier(variableName),
|
|
2112
3186
|
createIndicesArrayExpression(ts, indices),
|
|
3187
|
+
createIndexSourcesArrayExpression(ts, sourceFile, indexSourceExpressions),
|
|
2113
3188
|
ts.factory.createStringLiteral(operatorName),
|
|
2114
3189
|
isPrefix ? ts.factory.createTrue() : ts.factory.createFalse(),
|
|
3190
|
+
createSourceLocationObject(ts, sourceFile, node),
|
|
2115
3191
|
]
|
|
2116
3192
|
);
|
|
2117
3193
|
}
|
|
2118
3194
|
|
|
2119
|
-
function createTraceMutatingCallExpression(
|
|
3195
|
+
function createTraceMutatingCallExpression(
|
|
3196
|
+
ts,
|
|
3197
|
+
sourceFile,
|
|
3198
|
+
node,
|
|
3199
|
+
variableName,
|
|
3200
|
+
methodName,
|
|
3201
|
+
args,
|
|
3202
|
+
indices = [],
|
|
3203
|
+
indexSourceExpressions = indices
|
|
3204
|
+
) {
|
|
3205
|
+
const receiverExpression = variableName === 'this'
|
|
3206
|
+
? ts.factory.createThis()
|
|
3207
|
+
: ts.factory.createIdentifier(variableName);
|
|
3208
|
+
return createTraceMutatingCallExpressionForReceiver(
|
|
3209
|
+
ts,
|
|
3210
|
+
sourceFile,
|
|
3211
|
+
node,
|
|
3212
|
+
variableName,
|
|
3213
|
+
receiverExpression,
|
|
3214
|
+
methodName,
|
|
3215
|
+
args,
|
|
3216
|
+
indices,
|
|
3217
|
+
indexSourceExpressions
|
|
3218
|
+
);
|
|
3219
|
+
}
|
|
3220
|
+
|
|
3221
|
+
function createTraceMutatingCallExpressionForReceiver(
|
|
3222
|
+
ts,
|
|
3223
|
+
sourceFile,
|
|
3224
|
+
node,
|
|
3225
|
+
variableName,
|
|
3226
|
+
receiverExpression,
|
|
3227
|
+
methodName,
|
|
3228
|
+
args,
|
|
3229
|
+
indices = [],
|
|
3230
|
+
indexSourceExpressions = indices
|
|
3231
|
+
) {
|
|
3232
|
+
const effectiveIndexSourceExpressions = ['set', 'get', 'has'].includes(methodName) && args.length > 0
|
|
3233
|
+
? [...indexSourceExpressions, args[0]]
|
|
3234
|
+
: indexSourceExpressions;
|
|
2120
3235
|
return ts.factory.createCallExpression(
|
|
2121
3236
|
ts.factory.createIdentifier('__traceMutatingCall'),
|
|
2122
3237
|
undefined,
|
|
2123
3238
|
[
|
|
2124
3239
|
ts.factory.createStringLiteral(variableName),
|
|
2125
|
-
|
|
3240
|
+
receiverExpression,
|
|
3241
|
+
createIndicesArrayExpression(ts, indices),
|
|
3242
|
+
createIndexSourcesArrayExpression(ts, sourceFile, effectiveIndexSourceExpressions),
|
|
2126
3243
|
ts.factory.createStringLiteral(methodName),
|
|
3244
|
+
createSourceLocationObject(ts, sourceFile, node),
|
|
2127
3245
|
...args,
|
|
2128
3246
|
]
|
|
2129
3247
|
);
|
|
2130
3248
|
}
|
|
2131
3249
|
|
|
3250
|
+
function isConsoleLogCall(ts, node) {
|
|
3251
|
+
return Boolean(
|
|
3252
|
+
ts.isCallExpression(node) &&
|
|
3253
|
+
ts.isPropertyAccessExpression(node.expression) &&
|
|
3254
|
+
ts.isIdentifier(node.expression.expression) &&
|
|
3255
|
+
node.expression.expression.text === 'console' &&
|
|
3256
|
+
node.expression.name.text === 'log'
|
|
3257
|
+
);
|
|
3258
|
+
}
|
|
3259
|
+
|
|
3260
|
+
function createTraceStdoutExpression(ts, sourceFile, node) {
|
|
3261
|
+
const lineNumber = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line + 1;
|
|
3262
|
+
return ts.factory.createCallExpression(
|
|
3263
|
+
ts.factory.createIdentifier('__traceStdout'),
|
|
3264
|
+
undefined,
|
|
3265
|
+
[
|
|
3266
|
+
ts.factory.createNumericLiteral(lineNumber),
|
|
3267
|
+
...node.arguments,
|
|
3268
|
+
]
|
|
3269
|
+
);
|
|
3270
|
+
}
|
|
3271
|
+
|
|
3272
|
+
function createTraceThrowExpression(ts, sourceFile, node) {
|
|
3273
|
+
const lineNumber = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line + 1;
|
|
3274
|
+
return ts.factory.updateThrowStatement(
|
|
3275
|
+
node,
|
|
3276
|
+
ts.factory.createCallExpression(
|
|
3277
|
+
ts.factory.createIdentifier('__traceExceptionValue'),
|
|
3278
|
+
undefined,
|
|
3279
|
+
[
|
|
3280
|
+
ts.factory.createNumericLiteral(lineNumber),
|
|
3281
|
+
node.expression ?? ts.factory.createIdentifier('undefined'),
|
|
3282
|
+
]
|
|
3283
|
+
)
|
|
3284
|
+
);
|
|
3285
|
+
}
|
|
3286
|
+
|
|
2132
3287
|
function createSnapshotFactory(ts, variableNames, includeThis = false) {
|
|
2133
3288
|
const properties = variableNames.map((name) =>
|
|
2134
3289
|
ts.factory.createPropertyAssignment(
|
|
@@ -2222,6 +3377,19 @@ function createTraceLineStatement(ts, sourceFile, statement, variableNames, line
|
|
|
2222
3377
|
);
|
|
2223
3378
|
}
|
|
2224
3379
|
|
|
3380
|
+
function createAttachPendingAccessesStatement(ts) {
|
|
3381
|
+
return ts.factory.createExpressionStatement(
|
|
3382
|
+
ts.factory.createCallExpression(
|
|
3383
|
+
ts.factory.createPropertyAccessExpression(
|
|
3384
|
+
ts.factory.createIdentifier('__traceRecorder'),
|
|
3385
|
+
ts.factory.createIdentifier('attachPendingAccessesToPreviousLine')
|
|
3386
|
+
),
|
|
3387
|
+
undefined,
|
|
3388
|
+
[]
|
|
3389
|
+
)
|
|
3390
|
+
);
|
|
3391
|
+
}
|
|
3392
|
+
|
|
2225
3393
|
function ensureBlockStatement(ts, statement) {
|
|
2226
3394
|
if (ts.isBlock(statement)) {
|
|
2227
3395
|
return statement;
|
|
@@ -2229,6 +3397,28 @@ function ensureBlockStatement(ts, statement) {
|
|
|
2229
3397
|
return ts.factory.createBlock([statement], true);
|
|
2230
3398
|
}
|
|
2231
3399
|
|
|
3400
|
+
function wrapTraceCondition(ts, expression, deferAccessesToNextLine = false) {
|
|
3401
|
+
const recorderMethod = deferAccessesToNextLine ? 'tracePostLineCondition' : 'traceCondition';
|
|
3402
|
+
const argument = deferAccessesToNextLine
|
|
3403
|
+
? ts.factory.createArrowFunction(
|
|
3404
|
+
undefined,
|
|
3405
|
+
undefined,
|
|
3406
|
+
[],
|
|
3407
|
+
undefined,
|
|
3408
|
+
ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
|
|
3409
|
+
expression
|
|
3410
|
+
)
|
|
3411
|
+
: expression;
|
|
3412
|
+
return ts.factory.createCallExpression(
|
|
3413
|
+
ts.factory.createPropertyAccessExpression(
|
|
3414
|
+
ts.factory.createIdentifier('__traceRecorder'),
|
|
3415
|
+
ts.factory.createIdentifier(recorderMethod)
|
|
3416
|
+
),
|
|
3417
|
+
undefined,
|
|
3418
|
+
[argument]
|
|
3419
|
+
);
|
|
3420
|
+
}
|
|
3421
|
+
|
|
2232
3422
|
function rewriteWhileStatementForTracing(ts, sourceFile, whileStatement, variableNames, lineFunctionMap, defaultFunctionName) {
|
|
2233
3423
|
const originalNode = ts.getOriginalNode(whileStatement) ?? whileStatement;
|
|
2234
3424
|
const tracedLine = createTraceLineStatement(
|
|
@@ -2243,7 +3433,7 @@ function rewriteWhileStatementForTracing(ts, sourceFile, whileStatement, variabl
|
|
|
2243
3433
|
const guardedBreak = ts.factory.createIfStatement(
|
|
2244
3434
|
ts.factory.createPrefixUnaryExpression(
|
|
2245
3435
|
ts.SyntaxKind.ExclamationToken,
|
|
2246
|
-
whileStatement.expression
|
|
3436
|
+
wrapTraceCondition(ts, whileStatement.expression)
|
|
2247
3437
|
),
|
|
2248
3438
|
ts.factory.createBreakStatement(),
|
|
2249
3439
|
undefined
|
|
@@ -2276,27 +3466,82 @@ function rewriteForStatementForTracing(ts, sourceFile, forStatement, variableNam
|
|
|
2276
3466
|
ts.factory.createBinaryExpression(
|
|
2277
3467
|
tracedLineCall,
|
|
2278
3468
|
ts.SyntaxKind.CommaToken,
|
|
2279
|
-
condition
|
|
3469
|
+
wrapTraceCondition(ts, condition)
|
|
2280
3470
|
)
|
|
2281
3471
|
);
|
|
2282
|
-
|
|
3472
|
+
const initializerWriteStatements = [];
|
|
3473
|
+
if (forStatement.initializer && ts.isVariableDeclarationList(forStatement.initializer)) {
|
|
3474
|
+
for (const declaration of forStatement.initializer.declarations) {
|
|
3475
|
+
if (!ts.isIdentifier(declaration.name)) continue;
|
|
3476
|
+
initializerWriteStatements.push(createTraceScalarWriteStatement(ts, sourceFile, originalNode, declaration.name.text));
|
|
3477
|
+
}
|
|
3478
|
+
}
|
|
3479
|
+
const rewrittenFor = ts.factory.updateForStatement(
|
|
2283
3480
|
forStatement,
|
|
2284
|
-
forStatement.initializer,
|
|
3481
|
+
initializerWriteStatements.length > 0 ? undefined : forStatement.initializer,
|
|
2285
3482
|
tracedCondition,
|
|
2286
3483
|
forStatement.incrementor,
|
|
2287
3484
|
forStatement.statement
|
|
2288
3485
|
);
|
|
3486
|
+
if (initializerWriteStatements.length === 0 || !forStatement.initializer || !ts.isVariableDeclarationList(forStatement.initializer)) {
|
|
3487
|
+
return rewrittenFor;
|
|
3488
|
+
}
|
|
3489
|
+
return ts.factory.createBlock(
|
|
3490
|
+
[
|
|
3491
|
+
ts.factory.createVariableStatement(undefined, forStatement.initializer),
|
|
3492
|
+
...initializerWriteStatements,
|
|
3493
|
+
rewrittenFor,
|
|
3494
|
+
],
|
|
3495
|
+
true
|
|
3496
|
+
);
|
|
2289
3497
|
}
|
|
2290
3498
|
|
|
2291
|
-
function rewriteForOfStatementForTracing(ts, sourceFile, forOfStatement, variableNames, lineFunctionMap, defaultFunctionName) {
|
|
3499
|
+
function rewriteForOfStatementForTracing(ts, sourceFile, context, forOfStatement, variableNames, lineFunctionMap, defaultFunctionName) {
|
|
2292
3500
|
const originalNode = ts.getOriginalNode(forOfStatement) ?? forOfStatement;
|
|
2293
|
-
const lineNumber = ts.getLineAndCharacterOfPosition(sourceFile, originalNode.getStart(sourceFile)).line + 1;
|
|
2294
|
-
const tempIndexName = `__traceForOfIndex_${lineNumber}_${originalNode.pos < 0 ? 0 : originalNode.pos}`;
|
|
2295
|
-
const tempArrayName = `__traceForOfArray_${lineNumber}_${originalNode.pos < 0 ? 0 : originalNode.pos}`;
|
|
2296
|
-
const arrayId = ts.factory.createIdentifier(tempArrayName);
|
|
2297
|
-
const indexId = ts.factory.createIdentifier(tempIndexName);
|
|
2298
3501
|
const visitedBodyBlock = ensureBlockStatement(ts, forOfStatement.statement);
|
|
2299
|
-
const
|
|
3502
|
+
const originalExpression = originalNode.expression ?? forOfStatement.expression;
|
|
3503
|
+
const indexedSource = extractTraceableElementAccess(ts, originalExpression);
|
|
3504
|
+
const sourceName = ts.isIdentifier(forOfStatement.expression) ? forOfStatement.expression.text : null;
|
|
3505
|
+
const bindingName =
|
|
3506
|
+
ts.isVariableDeclarationList(forOfStatement.initializer) &&
|
|
3507
|
+
forOfStatement.initializer.declarations.length === 1 &&
|
|
3508
|
+
collectBindingNames(ts, forOfStatement.initializer.declarations[0].name).length > 0
|
|
3509
|
+
? collectBindingNames(ts, forOfStatement.initializer.declarations[0].name).join(',')
|
|
3510
|
+
: ts.isIdentifier(forOfStatement.initializer)
|
|
3511
|
+
? forOfStatement.initializer.text
|
|
3512
|
+
: null;
|
|
3513
|
+
const lineNumber = sourceFile.getLineAndCharacterOfPosition(originalNode.getStart(sourceFile)).line + 1;
|
|
3514
|
+
const tracedExpression =
|
|
3515
|
+
indexedSource && bindingName
|
|
3516
|
+
? ts.factory.createCallExpression(
|
|
3517
|
+
ts.factory.createIdentifier('__traceIterableBindIndexed'),
|
|
3518
|
+
undefined,
|
|
3519
|
+
[
|
|
3520
|
+
ts.factory.createStringLiteral(indexedSource.variableName),
|
|
3521
|
+
forOfStatement.expression,
|
|
3522
|
+
createIndicesArrayExpression(ts, indexedSource.indices),
|
|
3523
|
+
createIndexSourcesArrayExpression(ts, sourceFile, indexedSource.indices),
|
|
3524
|
+
ts.factory.createStringLiteral(bindingName),
|
|
3525
|
+
ts.factory.createObjectLiteralExpression([
|
|
3526
|
+
ts.factory.createPropertyAssignment('line', ts.factory.createNumericLiteral(lineNumber)),
|
|
3527
|
+
]),
|
|
3528
|
+
]
|
|
3529
|
+
)
|
|
3530
|
+
: sourceName && bindingName
|
|
3531
|
+
? ts.factory.createCallExpression(
|
|
3532
|
+
ts.factory.createIdentifier('__traceIterableBind'),
|
|
3533
|
+
undefined,
|
|
3534
|
+
[
|
|
3535
|
+
ts.factory.createStringLiteral(sourceName),
|
|
3536
|
+
forOfStatement.expression,
|
|
3537
|
+
ts.factory.createStringLiteral(bindingName),
|
|
3538
|
+
ts.factory.createObjectLiteralExpression([
|
|
3539
|
+
ts.factory.createPropertyAssignment('line', ts.factory.createNumericLiteral(lineNumber)),
|
|
3540
|
+
]),
|
|
3541
|
+
]
|
|
3542
|
+
)
|
|
3543
|
+
: forOfStatement.expression;
|
|
3544
|
+
const createHeaderLine = () => createTraceLineStatement(
|
|
2300
3545
|
ts,
|
|
2301
3546
|
sourceFile,
|
|
2302
3547
|
originalNode,
|
|
@@ -2304,75 +3549,40 @@ function rewriteForOfStatementForTracing(ts, sourceFile, forOfStatement, variabl
|
|
|
2304
3549
|
lineFunctionMap,
|
|
2305
3550
|
defaultFunctionName
|
|
2306
3551
|
);
|
|
2307
|
-
const
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
ts.factory.
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
);
|
|
2331
|
-
} else {
|
|
2332
|
-
bindingStatement = ts.factory.createExpressionStatement(
|
|
2333
|
-
ts.factory.createAssignment(forOfStatement.initializer, ts.factory.createElementAccessExpression(arrayId, indexId))
|
|
2334
|
-
);
|
|
2335
|
-
}
|
|
3552
|
+
const bodyTracedLine = createHeaderLine();
|
|
3553
|
+
const rewriteContinueForHeader = (node) => {
|
|
3554
|
+
if (ts.isFunctionLike(node)) return node;
|
|
3555
|
+
if (
|
|
3556
|
+
node !== visitedBodyBlock &&
|
|
3557
|
+
(ts.isForStatement(node) ||
|
|
3558
|
+
ts.isForInStatement(node) ||
|
|
3559
|
+
ts.isForOfStatement(node) ||
|
|
3560
|
+
ts.isWhileStatement(node) ||
|
|
3561
|
+
ts.isDoStatement(node))
|
|
3562
|
+
) {
|
|
3563
|
+
return node;
|
|
3564
|
+
}
|
|
3565
|
+
if (ts.isContinueStatement(node) && !node.label) {
|
|
3566
|
+
return ts.factory.createBlock([createHeaderLine(), node], true);
|
|
3567
|
+
}
|
|
3568
|
+
return ts.visitEachChild(node, rewriteContinueForHeader, context);
|
|
3569
|
+
};
|
|
3570
|
+
const bodyStatements = visitedBodyBlock.statements.map((statement) => ts.visitNode(statement, rewriteContinueForHeader));
|
|
3571
|
+
const bodyBlock = ts.factory.updateBlock(visitedBodyBlock, [
|
|
3572
|
+
bodyTracedLine,
|
|
3573
|
+
...bodyStatements,
|
|
3574
|
+
]);
|
|
2336
3575
|
|
|
2337
3576
|
return ts.factory.createBlock(
|
|
2338
3577
|
[
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
)
|
|
2346
|
-
),
|
|
2347
|
-
ts.factory.createExpressionStatement(
|
|
2348
|
-
ts.factory.createCallExpression(
|
|
2349
|
-
ts.factory.createPropertyAccessExpression(
|
|
2350
|
-
ts.factory.createIdentifier('__traceRecorder'),
|
|
2351
|
-
ts.factory.createIdentifier('deferPendingAccesses')
|
|
2352
|
-
),
|
|
2353
|
-
undefined,
|
|
2354
|
-
[ts.factory.createNumericLiteral(1)]
|
|
2355
|
-
)
|
|
2356
|
-
),
|
|
2357
|
-
ts.factory.createForStatement(
|
|
2358
|
-
ts.factory.createVariableDeclarationList(
|
|
2359
|
-
[ts.factory.createVariableDeclaration(indexId, undefined, undefined, ts.factory.createNumericLiteral(0))],
|
|
2360
|
-
ts.NodeFlags.Let
|
|
2361
|
-
),
|
|
2362
|
-
ts.factory.createParenthesizedExpression(
|
|
2363
|
-
ts.factory.createBinaryExpression(
|
|
2364
|
-
tracedLineCall,
|
|
2365
|
-
ts.SyntaxKind.CommaToken,
|
|
2366
|
-
ts.factory.createBinaryExpression(
|
|
2367
|
-
indexId,
|
|
2368
|
-
ts.SyntaxKind.LessThanToken,
|
|
2369
|
-
ts.factory.createPropertyAccessExpression(arrayId, 'length')
|
|
2370
|
-
)
|
|
2371
|
-
)
|
|
2372
|
-
),
|
|
2373
|
-
ts.factory.createPostfixIncrement(indexId),
|
|
2374
|
-
ts.factory.createBlock([bindingStatement, ...visitedBodyBlock.statements], true)
|
|
3578
|
+
ts.factory.updateForOfStatement(
|
|
3579
|
+
forOfStatement,
|
|
3580
|
+
forOfStatement.awaitModifier,
|
|
3581
|
+
forOfStatement.initializer,
|
|
3582
|
+
tracedExpression,
|
|
3583
|
+
bodyBlock
|
|
2375
3584
|
),
|
|
3585
|
+
createAttachPendingAccessesStatement(ts),
|
|
2376
3586
|
],
|
|
2377
3587
|
true
|
|
2378
3588
|
);
|
|
@@ -2395,16 +3605,28 @@ function instrumentStatementList(
|
|
|
2395
3605
|
ts.getOriginalNode(visitedStatement) ??
|
|
2396
3606
|
visitedStatement;
|
|
2397
3607
|
if (shouldTraceStatement(ts, visitedStatement)) {
|
|
3608
|
+
const tracedLineStatement = createTraceLineStatement(
|
|
3609
|
+
ts,
|
|
3610
|
+
sourceFile,
|
|
3611
|
+
originalStatement,
|
|
3612
|
+
variableNames,
|
|
3613
|
+
lineFunctionMap,
|
|
3614
|
+
defaultFunctionName
|
|
3615
|
+
);
|
|
3616
|
+
if (isPostLineStateStatement(ts, sourceFile, originalStatement)) {
|
|
3617
|
+
nextStatements.push(visitedStatement);
|
|
3618
|
+
nextStatements.push(...traceScalarWriteStatementsForVariableStatement(ts, sourceFile, originalStatement));
|
|
3619
|
+
nextStatements.push(tracedLineStatement);
|
|
3620
|
+
continue;
|
|
3621
|
+
}
|
|
2398
3622
|
nextStatements.push(
|
|
2399
|
-
|
|
2400
|
-
ts,
|
|
2401
|
-
sourceFile,
|
|
2402
|
-
originalStatement,
|
|
2403
|
-
variableNames,
|
|
2404
|
-
lineFunctionMap,
|
|
2405
|
-
defaultFunctionName
|
|
2406
|
-
)
|
|
3623
|
+
tracedLineStatement
|
|
2407
3624
|
);
|
|
3625
|
+
nextStatements.push(visitedStatement);
|
|
3626
|
+
nextStatements.push(...traceScalarWriteStatementsForVariableStatement(ts, sourceFile, originalStatement));
|
|
3627
|
+
nextStatements.push(...traceScalarWriteStatementsForDestructuringAssignmentStatement(ts, sourceFile, originalStatement));
|
|
3628
|
+
nextStatements.push(createAttachPendingAccessesStatement(ts));
|
|
3629
|
+
continue;
|
|
2408
3630
|
}
|
|
2409
3631
|
nextStatements.push(visitedStatement);
|
|
2410
3632
|
}
|
|
@@ -2642,6 +3864,7 @@ async function instrumentCodeForTracing(sourceCode, language, traceFunctionName)
|
|
|
2642
3864
|
);
|
|
2643
3865
|
|
|
2644
3866
|
const variableNames = collectTraceVariableNames(ts, sourceFile);
|
|
3867
|
+
const localVariableNames = new Set(variableNames);
|
|
2645
3868
|
const effectiveFunctionName =
|
|
2646
3869
|
typeof traceFunctionName === 'string' && traceFunctionName.length > 0
|
|
2647
3870
|
? traceFunctionName
|
|
@@ -2662,14 +3885,31 @@ async function instrumentCodeForTracing(sourceCode, language, traceFunctionName)
|
|
|
2662
3885
|
const visitedIndices = tracedOperand.indices.map((indexExpr) => ts.visitNode(indexExpr, visit));
|
|
2663
3886
|
return createTraceUpdateExpression(
|
|
2664
3887
|
ts,
|
|
3888
|
+
sourceFile,
|
|
3889
|
+
node,
|
|
2665
3890
|
tracedOperand.variableName,
|
|
2666
3891
|
visitedIndices,
|
|
2667
3892
|
operatorName,
|
|
3893
|
+
ts.isPrefixUnaryExpression(node),
|
|
3894
|
+
tracedOperand.indices
|
|
3895
|
+
);
|
|
3896
|
+
}
|
|
3897
|
+
if (ts.isIdentifier(node.operand) && operatorName) {
|
|
3898
|
+
return createTraceScalarUpdateExpression(
|
|
3899
|
+
ts,
|
|
3900
|
+
sourceFile,
|
|
3901
|
+
node,
|
|
3902
|
+
node.operand.text,
|
|
3903
|
+
operatorName,
|
|
2668
3904
|
ts.isPrefixUnaryExpression(node)
|
|
2669
3905
|
);
|
|
2670
3906
|
}
|
|
2671
3907
|
}
|
|
2672
3908
|
|
|
3909
|
+
if (ts.isThrowStatement(node)) {
|
|
3910
|
+
return createTraceThrowExpression(ts, sourceFile, node);
|
|
3911
|
+
}
|
|
3912
|
+
|
|
2673
3913
|
if (ts.isBinaryExpression(node)) {
|
|
2674
3914
|
const tracedLeft = extractTraceableElementAccess(ts, node.left);
|
|
2675
3915
|
if (tracedLeft && isAssignmentOperatorToken(ts, node.operatorToken.kind)) {
|
|
@@ -2678,9 +3918,12 @@ async function instrumentCodeForTracing(sourceCode, language, traceFunctionName)
|
|
|
2678
3918
|
if (node.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
|
|
2679
3919
|
return createTraceWriteIndexExpression(
|
|
2680
3920
|
ts,
|
|
3921
|
+
sourceFile,
|
|
3922
|
+
node.left,
|
|
2681
3923
|
tracedLeft.variableName,
|
|
2682
3924
|
visitedIndices,
|
|
2683
|
-
visitedRight
|
|
3925
|
+
visitedRight,
|
|
3926
|
+
tracedLeft.indices
|
|
2684
3927
|
);
|
|
2685
3928
|
}
|
|
2686
3929
|
|
|
@@ -2688,34 +3931,87 @@ async function instrumentCodeForTracing(sourceCode, language, traceFunctionName)
|
|
|
2688
3931
|
if (operatorName) {
|
|
2689
3932
|
return createTraceAugAssignExpression(
|
|
2690
3933
|
ts,
|
|
3934
|
+
sourceFile,
|
|
3935
|
+
node.left,
|
|
2691
3936
|
tracedLeft.variableName,
|
|
2692
3937
|
visitedIndices,
|
|
2693
3938
|
operatorName,
|
|
2694
|
-
visitedRight
|
|
3939
|
+
visitedRight,
|
|
3940
|
+
tracedLeft.indices
|
|
2695
3941
|
);
|
|
2696
3942
|
}
|
|
2697
3943
|
}
|
|
3944
|
+
|
|
3945
|
+
if (ts.isIdentifier(node.left) && isAssignmentOperatorToken(ts, node.operatorToken.kind)) {
|
|
3946
|
+
const visitedRight = ts.visitNode(node.right, visit);
|
|
3947
|
+
const rewrittenAssignment = ts.factory.updateBinaryExpression(
|
|
3948
|
+
node,
|
|
3949
|
+
node.left,
|
|
3950
|
+
node.operatorToken,
|
|
3951
|
+
visitedRight
|
|
3952
|
+
);
|
|
3953
|
+
return createTraceScalarWriteExpression(
|
|
3954
|
+
ts,
|
|
3955
|
+
sourceFile,
|
|
3956
|
+
node.left,
|
|
3957
|
+
node.left.text,
|
|
3958
|
+
rewrittenAssignment
|
|
3959
|
+
);
|
|
3960
|
+
}
|
|
3961
|
+
|
|
3962
|
+
const tracedPropertyLeft = extractTraceablePropertyAccess(ts, node.left);
|
|
3963
|
+
if (tracedPropertyLeft && node.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
|
|
3964
|
+
const visitedRight = ts.visitNode(node.right, visit);
|
|
3965
|
+
return createTraceWritePropertyExpression(
|
|
3966
|
+
ts,
|
|
3967
|
+
sourceFile,
|
|
3968
|
+
node.left,
|
|
3969
|
+
tracedPropertyLeft.variableName,
|
|
3970
|
+
tracedPropertyLeft.propertyName,
|
|
3971
|
+
visitedRight
|
|
3972
|
+
);
|
|
3973
|
+
}
|
|
2698
3974
|
}
|
|
2699
3975
|
|
|
2700
3976
|
if (ts.isCallExpression(node)) {
|
|
3977
|
+
if (isConsoleLogCall(ts, node)) {
|
|
3978
|
+
return createTraceStdoutExpression(ts, sourceFile, node);
|
|
3979
|
+
}
|
|
2701
3980
|
const tracedCall = extractTraceableMutatingCall(ts, node);
|
|
2702
3981
|
if (tracedCall) {
|
|
2703
3982
|
const visitedArgs = node.arguments.map((arg) => ts.visitNode(arg, visit));
|
|
2704
|
-
return
|
|
3983
|
+
return createTraceMutatingCallExpressionForReceiver(
|
|
2705
3984
|
ts,
|
|
3985
|
+
sourceFile,
|
|
3986
|
+
node,
|
|
2706
3987
|
tracedCall.variableName,
|
|
3988
|
+
tracedCall.receiverExpression,
|
|
2707
3989
|
tracedCall.methodName,
|
|
2708
|
-
visitedArgs
|
|
3990
|
+
visitedArgs,
|
|
3991
|
+
tracedCall.indices?.map((indexExpr) => ts.visitNode(indexExpr, visit)) ?? [],
|
|
3992
|
+
tracedCall.indices ?? []
|
|
2709
3993
|
);
|
|
2710
3994
|
}
|
|
2711
3995
|
}
|
|
2712
3996
|
|
|
3997
|
+
if (ts.isIfStatement(node)) {
|
|
3998
|
+
const visited = ts.visitEachChild(node, visit, context);
|
|
3999
|
+
return ts.factory.updateIfStatement(
|
|
4000
|
+
visited,
|
|
4001
|
+
wrapTraceCondition(ts, visited.expression, shouldTraceIfStatementPostLine(ts, sourceFile, node)),
|
|
4002
|
+
visited.thenStatement,
|
|
4003
|
+
visited.elseStatement
|
|
4004
|
+
);
|
|
4005
|
+
}
|
|
4006
|
+
|
|
2713
4007
|
if (ts.isElementAccessExpression(node)) {
|
|
4008
|
+
const parent = node.parent;
|
|
2714
4009
|
if (
|
|
2715
4010
|
isNestedElementAccessExpression(ts, node) ||
|
|
2716
4011
|
isAssignmentLikeLeftOperand(ts, node) ||
|
|
2717
4012
|
isUpdateExpressionOperand(ts, node) ||
|
|
2718
|
-
isDestructuringAssignmentTarget(ts, node)
|
|
4013
|
+
isDestructuringAssignmentTarget(ts, node) ||
|
|
4014
|
+
(parent && ts.isCallExpression(parent) && parent.expression === node)
|
|
2719
4015
|
) {
|
|
2720
4016
|
return ts.visitEachChild(node, visit, context);
|
|
2721
4017
|
}
|
|
@@ -2723,7 +4019,57 @@ async function instrumentCodeForTracing(sourceCode, language, traceFunctionName)
|
|
|
2723
4019
|
const tracedAccess = extractTraceableElementAccess(ts, node);
|
|
2724
4020
|
if (tracedAccess) {
|
|
2725
4021
|
const visitedIndices = tracedAccess.indices.map((indexExpr) => ts.visitNode(indexExpr, visit));
|
|
2726
|
-
return createTraceReadIndexExpression(
|
|
4022
|
+
return createTraceReadIndexExpression(
|
|
4023
|
+
ts,
|
|
4024
|
+
sourceFile,
|
|
4025
|
+
node,
|
|
4026
|
+
tracedAccess.variableName,
|
|
4027
|
+
visitedIndices,
|
|
4028
|
+
tracedAccess.indices
|
|
4029
|
+
);
|
|
4030
|
+
}
|
|
4031
|
+
}
|
|
4032
|
+
|
|
4033
|
+
if (ts.isPropertyAccessExpression(node)) {
|
|
4034
|
+
const parent = node.parent;
|
|
4035
|
+
const grandparent = parent?.parent;
|
|
4036
|
+
if (
|
|
4037
|
+
isTraceablePropertyWriteLeftOperand(ts, node) ||
|
|
4038
|
+
isDestructuringAssignmentTarget(ts, node) ||
|
|
4039
|
+
(parent && ts.isCallExpression(parent) && parent.expression === node) ||
|
|
4040
|
+
(parent &&
|
|
4041
|
+
ts.isPropertyAccessExpression(parent) &&
|
|
4042
|
+
parent.expression === node &&
|
|
4043
|
+
grandparent &&
|
|
4044
|
+
ts.isCallExpression(grandparent) &&
|
|
4045
|
+
grandparent.expression === parent)
|
|
4046
|
+
) {
|
|
4047
|
+
return ts.visitEachChild(node, visit, context);
|
|
4048
|
+
}
|
|
4049
|
+
|
|
4050
|
+
const tracedIndexedPropertyAccess = extractTraceableElementAccess(ts, node);
|
|
4051
|
+
if (tracedIndexedPropertyAccess && tracedIndexedPropertyAccess.indices.length > 1) {
|
|
4052
|
+
const visitedIndices = tracedIndexedPropertyAccess.indices.map((indexExpr) => ts.visitNode(indexExpr, visit));
|
|
4053
|
+
return createTraceReadIndexExpression(
|
|
4054
|
+
ts,
|
|
4055
|
+
sourceFile,
|
|
4056
|
+
node,
|
|
4057
|
+
tracedIndexedPropertyAccess.variableName,
|
|
4058
|
+
visitedIndices,
|
|
4059
|
+
tracedIndexedPropertyAccess.indices
|
|
4060
|
+
);
|
|
4061
|
+
}
|
|
4062
|
+
|
|
4063
|
+
const tracedAccess = extractTraceablePropertyAccess(ts, node);
|
|
4064
|
+
if (tracedAccess) {
|
|
4065
|
+
return createTraceReadPropertyExpression(
|
|
4066
|
+
ts,
|
|
4067
|
+
sourceFile,
|
|
4068
|
+
node,
|
|
4069
|
+
tracedAccess.variableName,
|
|
4070
|
+
tracedAccess.propertyName,
|
|
4071
|
+
tracedAccess.scope ?? runtimeScopeForTraceableReceiver(tracedAccess.variableName, localVariableNames)
|
|
4072
|
+
);
|
|
2727
4073
|
}
|
|
2728
4074
|
}
|
|
2729
4075
|
|
|
@@ -2803,6 +4149,7 @@ async function instrumentCodeForTracing(sourceCode, language, traceFunctionName)
|
|
|
2803
4149
|
return rewriteForOfStatementForTracing(
|
|
2804
4150
|
ts,
|
|
2805
4151
|
sourceFile,
|
|
4152
|
+
context,
|
|
2806
4153
|
visited,
|
|
2807
4154
|
variableNames,
|
|
2808
4155
|
lineFunctionMap,
|
|
@@ -2865,9 +4212,7 @@ async function instrumentCodeForTracing(sourceCode, language, traceFunctionName)
|
|
|
2865
4212
|
function buildScriptExecutionRunner(code) {
|
|
2866
4213
|
return new Function(
|
|
2867
4214
|
'console',
|
|
2868
|
-
|
|
2869
|
-
${JAVASCRIPT_RUNTIME_PRELUDE}
|
|
2870
|
-
let result;
|
|
4215
|
+
`${JAVASCRIPT_RUNTIME_PRELUDE}
|
|
2871
4216
|
${code}
|
|
2872
4217
|
if (typeof result === 'undefined') {
|
|
2873
4218
|
return null;
|
|
@@ -2879,19 +4224,41 @@ return result;`
|
|
|
2879
4224
|
const TRACING_RUNTIME_HELPERS_SOURCE = `
|
|
2880
4225
|
function __traceNormalizeIndices(__indices, __maxDepth = 2) {
|
|
2881
4226
|
if (!Array.isArray(__indices) || __indices.length === 0 || __indices.length > __maxDepth) return null;
|
|
2882
|
-
if (!__indices.every((__index) =>
|
|
2883
|
-
|
|
4227
|
+
if (!__indices.every((__index) =>
|
|
4228
|
+
(typeof __index === 'number' && Number.isInteger(__index)) ||
|
|
4229
|
+
(typeof __index === 'string' && __index.length > 0)
|
|
4230
|
+
)) return null;
|
|
4231
|
+
return __indices.map((__index) => typeof __index === 'number' ? Math.trunc(__index) : __index);
|
|
4232
|
+
}
|
|
4233
|
+
|
|
4234
|
+
function __traceNormalizeIndexSources(__indexSources, __pathLength) {
|
|
4235
|
+
if (!Array.isArray(__indexSources) || !Number.isInteger(__pathLength) || __pathLength <= 0) return null;
|
|
4236
|
+
const __normalized = __indexSources.slice(0, __pathLength).map((__source) =>
|
|
4237
|
+
typeof __source === 'string' && __source.length > 0 ? __source : null
|
|
4238
|
+
);
|
|
4239
|
+
while (__normalized.length < __pathLength) __normalized.push(null);
|
|
4240
|
+
return __normalized.some((__source) => __source !== null) ? __normalized : null;
|
|
2884
4241
|
}
|
|
2885
4242
|
|
|
2886
4243
|
function __traceReadValueAtIndices(__container, __indices) {
|
|
2887
4244
|
let __current = __container;
|
|
2888
4245
|
for (const __index of __indices) {
|
|
2889
4246
|
if (__current === null || __current === undefined) return undefined;
|
|
2890
|
-
__current = __current[__index];
|
|
4247
|
+
__current = __traceIsMapLike(__current) ? __current.get(__index) : __current[__index];
|
|
2891
4248
|
}
|
|
2892
4249
|
return __current;
|
|
2893
4250
|
}
|
|
2894
4251
|
|
|
4252
|
+
function __traceIsMapLike(__value) {
|
|
4253
|
+
return __value instanceof Map ||
|
|
4254
|
+
(!!__value &&
|
|
4255
|
+
typeof __value === 'object' &&
|
|
4256
|
+
typeof __value.get === 'function' &&
|
|
4257
|
+
typeof __value.set === 'function' &&
|
|
4258
|
+
typeof __value.has === 'function' &&
|
|
4259
|
+
typeof __value.delete === 'function');
|
|
4260
|
+
}
|
|
4261
|
+
|
|
2895
4262
|
function __traceWriteValueAtIndices(__container, __indices, __value) {
|
|
2896
4263
|
if (__indices.length === 1) {
|
|
2897
4264
|
__container[__indices[0]] = __value;
|
|
@@ -2907,33 +4274,156 @@ function __traceWriteValueAtIndices(__container, __indices, __value) {
|
|
|
2907
4274
|
return __value;
|
|
2908
4275
|
}
|
|
2909
4276
|
|
|
2910
|
-
function __traceReadIndex(__varName, __container, __indices) {
|
|
4277
|
+
function __traceReadIndex(__varName, __container, __indices, __indexSources, __location) {
|
|
2911
4278
|
const __normalized = __traceNormalizeIndices(__indices);
|
|
4279
|
+
const __normalizedSources = __traceNormalizeIndexSources(__indexSources, __normalized?.length ?? 0);
|
|
4280
|
+
const __value = __traceReadValueAtIndices(__container, Array.isArray(__indices) ? __indices : []);
|
|
2912
4281
|
if (__normalized) {
|
|
2913
4282
|
__traceRecorder.recordAccess({
|
|
2914
4283
|
variable: __varName,
|
|
2915
4284
|
kind: __normalized.length === 2 ? 'cell-read' : 'indexed-read',
|
|
2916
4285
|
indices: __normalized,
|
|
4286
|
+
...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
|
|
2917
4287
|
pathDepth: __normalized.length,
|
|
4288
|
+
value: __value,
|
|
4289
|
+
...__traceNormalizeSourceLocation(__location),
|
|
4290
|
+
});
|
|
4291
|
+
}
|
|
4292
|
+
return __value;
|
|
4293
|
+
}
|
|
4294
|
+
|
|
4295
|
+
function* __traceIterableBind(__varName, __iterable, __bindingName, __location) {
|
|
4296
|
+
if (
|
|
4297
|
+
typeof __varName !== 'string' ||
|
|
4298
|
+
typeof __bindingName !== 'string' ||
|
|
4299
|
+
(__iterable === null || __iterable === undefined) ||
|
|
4300
|
+
typeof __iterable[Symbol.iterator] !== 'function'
|
|
4301
|
+
) {
|
|
4302
|
+
yield* __iterable;
|
|
4303
|
+
return;
|
|
4304
|
+
}
|
|
4305
|
+
let __index = 0;
|
|
4306
|
+
for (const __value of __iterable) {
|
|
4307
|
+
__traceRecorder.recordAccess({
|
|
4308
|
+
variable: __varName,
|
|
4309
|
+
kind: 'indexed-read',
|
|
4310
|
+
indices: [__index],
|
|
4311
|
+
pathDepth: 1,
|
|
4312
|
+
value: __value,
|
|
4313
|
+
binding: { kind: 'iteration', variable: __bindingName },
|
|
4314
|
+
...__traceNormalizeSourceLocation(__location),
|
|
2918
4315
|
});
|
|
4316
|
+
__index += 1;
|
|
4317
|
+
yield __value;
|
|
4318
|
+
}
|
|
4319
|
+
}
|
|
4320
|
+
|
|
4321
|
+
function* __traceIterableBindIndexed(__varName, __iterable, __baseIndices, __indexSources, __bindingName, __location) {
|
|
4322
|
+
if (
|
|
4323
|
+
typeof __varName !== 'string' ||
|
|
4324
|
+
typeof __bindingName !== 'string' ||
|
|
4325
|
+
(__iterable === null || __iterable === undefined) ||
|
|
4326
|
+
typeof __iterable[Symbol.iterator] !== 'function'
|
|
4327
|
+
) {
|
|
4328
|
+
yield* __iterable;
|
|
4329
|
+
return;
|
|
4330
|
+
}
|
|
4331
|
+
const __base = __traceNormalizeIndices(__baseIndices);
|
|
4332
|
+
const __baseSources = __traceNormalizeIndexSources(__indexSources, __base?.length ?? 0);
|
|
4333
|
+
let __index = 0;
|
|
4334
|
+
for (const __value of __iterable) {
|
|
4335
|
+
if (__base) {
|
|
4336
|
+
const __path = [...__base, __index];
|
|
4337
|
+
const __sources = Array.isArray(__baseSources) ? [...__baseSources, null] : null;
|
|
4338
|
+
__traceRecorder.recordAccess({
|
|
4339
|
+
variable: __varName,
|
|
4340
|
+
kind: __path.length === 2 ? 'cell-read' : 'indexed-read',
|
|
4341
|
+
indices: __path,
|
|
4342
|
+
pathDepth: __path.length,
|
|
4343
|
+
value: __value,
|
|
4344
|
+
...(Array.isArray(__sources) ? { indexSources: __sources } : {}),
|
|
4345
|
+
binding: { kind: 'iteration', variable: __bindingName },
|
|
4346
|
+
...__traceNormalizeSourceLocation(__location),
|
|
4347
|
+
});
|
|
4348
|
+
}
|
|
4349
|
+
__index += 1;
|
|
4350
|
+
yield __value;
|
|
4351
|
+
}
|
|
4352
|
+
}
|
|
4353
|
+
|
|
4354
|
+
function __traceIsMetadataProperty(__container, __propertyName) {
|
|
4355
|
+
if (__propertyName === 'length') {
|
|
4356
|
+
return Array.isArray(__container) || typeof __container === 'string';
|
|
4357
|
+
}
|
|
4358
|
+
if (__propertyName === 'size') {
|
|
4359
|
+
return __traceIsMapLike(__container) || __container instanceof Set;
|
|
2919
4360
|
}
|
|
2920
|
-
return
|
|
4361
|
+
return false;
|
|
4362
|
+
}
|
|
4363
|
+
|
|
4364
|
+
function __traceNormalizeSourceLocation(__location) {
|
|
4365
|
+
if (!__location || typeof __location !== 'object') return {};
|
|
4366
|
+
const __line = Number(__location.line);
|
|
4367
|
+
const __column = Number(__location.column);
|
|
4368
|
+
return {
|
|
4369
|
+
...(Number.isFinite(__line) && __line > 0 ? { line: Math.trunc(__line) } : {}),
|
|
4370
|
+
...(Number.isFinite(__column) && __column >= 0 ? { column: Math.trunc(__column) } : {}),
|
|
4371
|
+
};
|
|
4372
|
+
}
|
|
4373
|
+
|
|
4374
|
+
function __traceReadProperty(__varName, __container, __propertyName, __scopeOrLocation, __maybeLocation) {
|
|
4375
|
+
const __scope = typeof __scopeOrLocation === 'string' ? __scopeOrLocation : undefined;
|
|
4376
|
+
const __location = typeof __scopeOrLocation === 'string' ? __maybeLocation : __scopeOrLocation;
|
|
4377
|
+
__traceRecorder.recordAccess({
|
|
4378
|
+
variable: __varName,
|
|
4379
|
+
kind: 'indexed-read',
|
|
4380
|
+
indices: [__propertyName],
|
|
4381
|
+
pathDepth: 1,
|
|
4382
|
+
...(__scope ? { scope: __scope } : {}),
|
|
4383
|
+
...__traceNormalizeSourceLocation(__location),
|
|
4384
|
+
});
|
|
4385
|
+
return __container?.[__propertyName];
|
|
2921
4386
|
}
|
|
2922
4387
|
|
|
2923
|
-
function __traceWriteIndex(__varName, __container, __indices, __value) {
|
|
4388
|
+
function __traceWriteIndex(__varName, __container, __indices, __indexSources, __value, __location) {
|
|
2924
4389
|
const __normalized = __traceNormalizeIndices(__indices);
|
|
4390
|
+
const __normalizedSources = __traceNormalizeIndexSources(__indexSources, __normalized?.length ?? 0);
|
|
2925
4391
|
const __result = __traceWriteValueAtIndices(__container, Array.isArray(__indices) ? __indices : [], __value);
|
|
2926
4392
|
if (__normalized) {
|
|
2927
4393
|
__traceRecorder.recordAccess({
|
|
2928
4394
|
variable: __varName,
|
|
2929
4395
|
kind: __normalized.length === 2 ? 'cell-write' : 'indexed-write',
|
|
2930
4396
|
indices: __normalized,
|
|
4397
|
+
...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
|
|
2931
4398
|
pathDepth: __normalized.length,
|
|
4399
|
+
value: __result,
|
|
4400
|
+
...__traceNormalizeSourceLocation(__location),
|
|
2932
4401
|
});
|
|
2933
4402
|
}
|
|
2934
4403
|
return __result;
|
|
2935
4404
|
}
|
|
2936
4405
|
|
|
4406
|
+
function __traceScalarWrite(__varName, __value, __location) {
|
|
4407
|
+
__traceRecorder.recordAccess({
|
|
4408
|
+
variable: __varName,
|
|
4409
|
+
kind: 'indexed-write',
|
|
4410
|
+
value: __value,
|
|
4411
|
+
...__traceNormalizeSourceLocation(__location),
|
|
4412
|
+
});
|
|
4413
|
+
return __value;
|
|
4414
|
+
}
|
|
4415
|
+
|
|
4416
|
+
function __traceAssignScalar(__varName, __value, __location) {
|
|
4417
|
+
return __traceScalarWrite(__varName, __value, __location);
|
|
4418
|
+
}
|
|
4419
|
+
|
|
4420
|
+
function __traceUpdateScalar(__varName, __update, __current, __isPrefix, __location) {
|
|
4421
|
+
const __result = typeof __update === 'function' ? __update() : undefined;
|
|
4422
|
+
const __value = typeof __current === 'function' ? __current() : __result;
|
|
4423
|
+
__traceScalarWrite(__varName, __value, __location);
|
|
4424
|
+
return __isPrefix ? __value : __result;
|
|
4425
|
+
}
|
|
4426
|
+
|
|
2937
4427
|
function __traceApplyAugmentedValue(__current, __op, __rhs) {
|
|
2938
4428
|
switch (__op) {
|
|
2939
4429
|
case 'add': return __current + __rhs;
|
|
@@ -2951,8 +4441,9 @@ function __traceApplyAugmentedValue(__current, __op, __rhs) {
|
|
|
2951
4441
|
}
|
|
2952
4442
|
}
|
|
2953
4443
|
|
|
2954
|
-
function __traceAugAssignIndex(__varName, __container, __indices, __op, __rhs) {
|
|
4444
|
+
function __traceAugAssignIndex(__varName, __container, __indices, __indexSources, __op, __rhs, __location) {
|
|
2955
4445
|
const __normalized = __traceNormalizeIndices(__indices);
|
|
4446
|
+
const __normalizedSources = __traceNormalizeIndexSources(__indexSources, __normalized?.length ?? 0);
|
|
2956
4447
|
const __effectiveIndices = Array.isArray(__indices) ? __indices : [];
|
|
2957
4448
|
const __current = __traceReadValueAtIndices(__container, __effectiveIndices);
|
|
2958
4449
|
if (__normalized) {
|
|
@@ -2960,7 +4451,9 @@ function __traceAugAssignIndex(__varName, __container, __indices, __op, __rhs) {
|
|
|
2960
4451
|
variable: __varName,
|
|
2961
4452
|
kind: __normalized.length === 2 ? 'cell-read' : 'indexed-read',
|
|
2962
4453
|
indices: __normalized,
|
|
4454
|
+
...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
|
|
2963
4455
|
pathDepth: __normalized.length,
|
|
4456
|
+
...__traceNormalizeSourceLocation(__location),
|
|
2964
4457
|
});
|
|
2965
4458
|
}
|
|
2966
4459
|
const __next = __traceApplyAugmentedValue(__current, __op, __rhs);
|
|
@@ -2970,14 +4463,18 @@ function __traceAugAssignIndex(__varName, __container, __indices, __op, __rhs) {
|
|
|
2970
4463
|
variable: __varName,
|
|
2971
4464
|
kind: __normalized.length === 2 ? 'cell-write' : 'indexed-write',
|
|
2972
4465
|
indices: __normalized,
|
|
4466
|
+
...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
|
|
2973
4467
|
pathDepth: __normalized.length,
|
|
4468
|
+
value: __next,
|
|
4469
|
+
...__traceNormalizeSourceLocation(__location),
|
|
2974
4470
|
});
|
|
2975
4471
|
}
|
|
2976
4472
|
return __next;
|
|
2977
4473
|
}
|
|
2978
4474
|
|
|
2979
|
-
function __traceUpdateIndex(__varName, __container, __indices, __op, __isPrefix) {
|
|
4475
|
+
function __traceUpdateIndex(__varName, __container, __indices, __indexSources, __op, __isPrefix, __location) {
|
|
2980
4476
|
const __normalized = __traceNormalizeIndices(__indices);
|
|
4477
|
+
const __normalizedSources = __traceNormalizeIndexSources(__indexSources, __normalized?.length ?? 0);
|
|
2981
4478
|
const __effectiveIndices = Array.isArray(__indices) ? __indices : [];
|
|
2982
4479
|
const __current = __traceReadValueAtIndices(__container, __effectiveIndices);
|
|
2983
4480
|
if (__normalized) {
|
|
@@ -2985,7 +4482,9 @@ function __traceUpdateIndex(__varName, __container, __indices, __op, __isPrefix)
|
|
|
2985
4482
|
variable: __varName,
|
|
2986
4483
|
kind: __normalized.length === 2 ? 'cell-read' : 'indexed-read',
|
|
2987
4484
|
indices: __normalized,
|
|
4485
|
+
...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
|
|
2988
4486
|
pathDepth: __normalized.length,
|
|
4487
|
+
...__traceNormalizeSourceLocation(__location),
|
|
2989
4488
|
});
|
|
2990
4489
|
}
|
|
2991
4490
|
const __delta = __op === 'dec' ? -1 : 1;
|
|
@@ -2996,20 +4495,111 @@ function __traceUpdateIndex(__varName, __container, __indices, __op, __isPrefix)
|
|
|
2996
4495
|
variable: __varName,
|
|
2997
4496
|
kind: __normalized.length === 2 ? 'cell-write' : 'indexed-write',
|
|
2998
4497
|
indices: __normalized,
|
|
4498
|
+
...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
|
|
2999
4499
|
pathDepth: __normalized.length,
|
|
4500
|
+
value: __next,
|
|
4501
|
+
...__traceNormalizeSourceLocation(__location),
|
|
3000
4502
|
});
|
|
3001
4503
|
}
|
|
3002
4504
|
return __isPrefix ? __next : __current;
|
|
3003
4505
|
}
|
|
3004
4506
|
|
|
3005
|
-
function
|
|
3006
|
-
|
|
3007
|
-
|
|
4507
|
+
function __traceNormalizeMethodName(__container, __method, __args) {
|
|
4508
|
+
void __container;
|
|
4509
|
+
void __args;
|
|
4510
|
+
return __method;
|
|
4511
|
+
}
|
|
4512
|
+
|
|
4513
|
+
function __traceStdout(__line, ...__args) {
|
|
4514
|
+
console.log(...__args);
|
|
4515
|
+
__traceRecorder.recordStdout(__line, __args.map((__arg) => String(__arg)).join(' '));
|
|
4516
|
+
}
|
|
4517
|
+
|
|
4518
|
+
function __traceExceptionValue(__line, __error) {
|
|
4519
|
+
__traceRecorder.recordException(__line, __error);
|
|
4520
|
+
return __error;
|
|
4521
|
+
}
|
|
4522
|
+
|
|
4523
|
+
function __traceMutatingCall(__varName, __container, __indices, __indexSources, __method, __location, ...__args) {
|
|
4524
|
+
const __sourceLocation = __traceNormalizeSourceLocation(__location);
|
|
4525
|
+
let __target = __container;
|
|
4526
|
+
for (const __index of __indices || []) {
|
|
4527
|
+
__target = __traceIsMapLike(__target) ? __target.get(__index) : __target?.[__index];
|
|
4528
|
+
}
|
|
4529
|
+
const __mayMutate = ['push', 'pop', 'shift', 'unshift', 'splice', 'set', 'add', 'delete', 'clear'].includes(__method);
|
|
4530
|
+
const __result = __target[__method](...__args);
|
|
4531
|
+
if (['push', 'pop', 'shift', 'unshift', 'splice', 'set', 'get', 'has', 'add', 'delete', 'clear'].includes(__method)) {
|
|
4532
|
+
const __path = __indices || [];
|
|
4533
|
+
const __isMapLike = __traceIsMapLike(__target);
|
|
4534
|
+
const __isNestedMap = __path.length > 0 && __traceIsMapLike(__target);
|
|
4535
|
+
if (__isMapLike && __method === 'set') {
|
|
4536
|
+
const __normalizedSources = __traceNormalizeIndexSources(__indexSources, __path.length + 1);
|
|
4537
|
+
const __targetPath = [...__path, __args[0]];
|
|
4538
|
+
__traceRecorder.recordAccess({
|
|
4539
|
+
variable: __varName,
|
|
4540
|
+
kind: 'indexed-write',
|
|
4541
|
+
indices: __targetPath,
|
|
4542
|
+
pathDepth: __path.length + 1,
|
|
4543
|
+
...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
|
|
4544
|
+
value: serializeValue(__args[1]),
|
|
4545
|
+
...__sourceLocation,
|
|
4546
|
+
});
|
|
4547
|
+
__traceRecorder.recordAccess({
|
|
4548
|
+
variable: __varName,
|
|
4549
|
+
kind: 'mutating-call',
|
|
4550
|
+
method: __traceNormalizeMethodName(__target, __method, __args),
|
|
4551
|
+
args: __args,
|
|
4552
|
+
indices: __targetPath,
|
|
4553
|
+
pathDepth: __path.length + 1,
|
|
4554
|
+
...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
|
|
4555
|
+
...__sourceLocation,
|
|
4556
|
+
});
|
|
4557
|
+
return __result;
|
|
4558
|
+
}
|
|
4559
|
+
if (__isMapLike && (__method === 'get' || __method === 'has')) {
|
|
4560
|
+
const __normalizedSources = __traceNormalizeIndexSources(__indexSources, __path.length + 1);
|
|
4561
|
+
__traceRecorder.recordAccess({
|
|
4562
|
+
variable: __varName,
|
|
4563
|
+
kind: 'indexed-read',
|
|
4564
|
+
indices: [...__path, __args[0]],
|
|
4565
|
+
pathDepth: __path.length + 1,
|
|
4566
|
+
...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
|
|
4567
|
+
value: serializeValue(__result),
|
|
4568
|
+
...__sourceLocation,
|
|
4569
|
+
});
|
|
4570
|
+
return __result;
|
|
4571
|
+
}
|
|
4572
|
+
if (__target instanceof Set && __method === 'has') {
|
|
4573
|
+
__traceRecorder.recordAccess({
|
|
4574
|
+
variable: __varName,
|
|
4575
|
+
kind: 'indexed-read',
|
|
4576
|
+
indices: [...__path, __args[0]],
|
|
4577
|
+
pathDepth: __path.length + 1,
|
|
4578
|
+
...__sourceLocation,
|
|
4579
|
+
});
|
|
4580
|
+
return __result;
|
|
4581
|
+
}
|
|
4582
|
+
if (__path.length > 0) {
|
|
4583
|
+
const __normalizedSources = __traceNormalizeIndexSources(__indexSources, __path.length);
|
|
4584
|
+
__traceRecorder.recordAccess({
|
|
4585
|
+
variable: __varName,
|
|
4586
|
+
kind: 'indexed-read',
|
|
4587
|
+
indices: __path,
|
|
4588
|
+
pathDepth: __path.length,
|
|
4589
|
+
...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
|
|
4590
|
+
...__sourceLocation,
|
|
4591
|
+
});
|
|
4592
|
+
}
|
|
4593
|
+
const __normalizedSources = __traceNormalizeIndexSources(__indexSources, __path.length);
|
|
3008
4594
|
__traceRecorder.recordAccess({
|
|
3009
4595
|
variable: __varName,
|
|
3010
4596
|
kind: 'mutating-call',
|
|
3011
|
-
method: __method,
|
|
3012
|
-
|
|
4597
|
+
method: __traceNormalizeMethodName(__target, __method, __args),
|
|
4598
|
+
args: __args,
|
|
4599
|
+
indices: __path,
|
|
4600
|
+
pathDepth: __path.length,
|
|
4601
|
+
...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
|
|
4602
|
+
...__sourceLocation,
|
|
3013
4603
|
});
|
|
3014
4604
|
}
|
|
3015
4605
|
return __result;
|
|
@@ -3021,10 +4611,8 @@ function buildScriptTracingRunner(code) {
|
|
|
3021
4611
|
'console',
|
|
3022
4612
|
'__traceRecorder',
|
|
3023
4613
|
'__traceCtx',
|
|
3024
|
-
|
|
3025
|
-
${JAVASCRIPT_RUNTIME_PRELUDE}
|
|
4614
|
+
`${JAVASCRIPT_RUNTIME_PRELUDE}
|
|
3026
4615
|
${TRACING_RUNTIME_HELPERS_SOURCE}
|
|
3027
|
-
let result;
|
|
3028
4616
|
${code}
|
|
3029
4617
|
if (typeof result === 'undefined') {
|
|
3030
4618
|
return null;
|
|
@@ -3042,6 +4630,7 @@ function buildFunctionExecutionRunner(code, executionStyle, argNames) {
|
|
|
3042
4630
|
`"use strict";
|
|
3043
4631
|
${JAVASCRIPT_RUNTIME_PRELUDE}
|
|
3044
4632
|
${code}
|
|
4633
|
+
${CUSTOM_OBJECT_MATERIALIZER_SOURCE}
|
|
3045
4634
|
let __target;
|
|
3046
4635
|
try {
|
|
3047
4636
|
__target = eval(__functionName);
|
|
@@ -3051,7 +4640,7 @@ try {
|
|
|
3051
4640
|
if (typeof __target !== 'function') {
|
|
3052
4641
|
throw new Error('Function "' + __functionName + '" not found');
|
|
3053
4642
|
}
|
|
3054
|
-
return __target(${argNames.join(', ')});`
|
|
4643
|
+
return __target(${argNames.map((name) => `__tracecodeMaterializeCustomObject(${name})`).join(', ')});`
|
|
3055
4644
|
);
|
|
3056
4645
|
}
|
|
3057
4646
|
|
|
@@ -3063,6 +4652,7 @@ return __target(${argNames.join(', ')});`
|
|
|
3063
4652
|
`"use strict";
|
|
3064
4653
|
${JAVASCRIPT_RUNTIME_PRELUDE}
|
|
3065
4654
|
${code}
|
|
4655
|
+
${CUSTOM_OBJECT_MATERIALIZER_SOURCE}
|
|
3066
4656
|
if (typeof Solution !== 'function') {
|
|
3067
4657
|
throw new Error('Class "Solution" not found');
|
|
3068
4658
|
}
|
|
@@ -3071,7 +4661,7 @@ const __method = __solver[__functionName];
|
|
|
3071
4661
|
if (typeof __method !== 'function') {
|
|
3072
4662
|
throw new Error('Method "Solution.' + __functionName + '" not found');
|
|
3073
4663
|
}
|
|
3074
|
-
return __method.call(__solver, ${argNames.join(', ')});`
|
|
4664
|
+
return __method.call(__solver, ${argNames.map((name) => `__tracecodeMaterializeCustomObject(${name})`).join(', ')});`
|
|
3075
4665
|
);
|
|
3076
4666
|
}
|
|
3077
4667
|
|
|
@@ -3084,6 +4674,7 @@ return __method.call(__solver, ${argNames.join(', ')});`
|
|
|
3084
4674
|
`"use strict";
|
|
3085
4675
|
${JAVASCRIPT_RUNTIME_PRELUDE}
|
|
3086
4676
|
${code}
|
|
4677
|
+
${CUSTOM_OBJECT_MATERIALIZER_SOURCE}
|
|
3087
4678
|
if (!Array.isArray(__operations) || !Array.isArray(__arguments)) {
|
|
3088
4679
|
throw new Error('ops-class execution requires inputs.operations and inputs.arguments (or ops/args)');
|
|
3089
4680
|
}
|
|
@@ -3110,6 +4701,7 @@ for (let __i = 0; __i < __operations.length; __i++) {
|
|
|
3110
4701
|
if (!Array.isArray(__callArgs)) {
|
|
3111
4702
|
__callArgs = [__callArgs];
|
|
3112
4703
|
}
|
|
4704
|
+
__callArgs = __callArgs.map((__arg) => __tracecodeMaterializeCustomObject(__arg));
|
|
3113
4705
|
if (__i === 0) {
|
|
3114
4706
|
__instance = new __targetClass(...__callArgs);
|
|
3115
4707
|
__out.push(null);
|
|
@@ -3139,6 +4731,7 @@ function buildFunctionTracingRunner(code, executionStyle, argNames) {
|
|
|
3139
4731
|
${JAVASCRIPT_RUNTIME_PRELUDE}
|
|
3140
4732
|
${TRACING_RUNTIME_HELPERS_SOURCE}
|
|
3141
4733
|
${code}
|
|
4734
|
+
${CUSTOM_OBJECT_MATERIALIZER_SOURCE}
|
|
3142
4735
|
let __target;
|
|
3143
4736
|
try {
|
|
3144
4737
|
__target = eval(__functionName);
|
|
@@ -3148,7 +4741,7 @@ try {
|
|
|
3148
4741
|
if (typeof __target !== 'function') {
|
|
3149
4742
|
throw new Error('Function "' + __functionName + '" not found');
|
|
3150
4743
|
}
|
|
3151
|
-
return __target(${argNames.join(', ')});`
|
|
4744
|
+
return __target(${argNames.map((name) => `__tracecodeMaterializeCustomObject(${name})`).join(', ')});`
|
|
3152
4745
|
);
|
|
3153
4746
|
}
|
|
3154
4747
|
|
|
@@ -3163,6 +4756,7 @@ return __target(${argNames.join(', ')});`
|
|
|
3163
4756
|
${JAVASCRIPT_RUNTIME_PRELUDE}
|
|
3164
4757
|
${TRACING_RUNTIME_HELPERS_SOURCE}
|
|
3165
4758
|
${code}
|
|
4759
|
+
${CUSTOM_OBJECT_MATERIALIZER_SOURCE}
|
|
3166
4760
|
if (typeof Solution !== 'function') {
|
|
3167
4761
|
throw new Error('Class "Solution" not found');
|
|
3168
4762
|
}
|
|
@@ -3171,7 +4765,7 @@ const __method = __solver[__functionName];
|
|
|
3171
4765
|
if (typeof __method !== 'function') {
|
|
3172
4766
|
throw new Error('Method "Solution.' + __functionName + '" not found');
|
|
3173
4767
|
}
|
|
3174
|
-
return __method.call(__solver, ${argNames.join(', ')});`
|
|
4768
|
+
return __method.call(__solver, ${argNames.map((name) => `__tracecodeMaterializeCustomObject(${name})`).join(', ')});`
|
|
3175
4769
|
);
|
|
3176
4770
|
}
|
|
3177
4771
|
|
|
@@ -3187,6 +4781,7 @@ return __method.call(__solver, ${argNames.join(', ')});`
|
|
|
3187
4781
|
${JAVASCRIPT_RUNTIME_PRELUDE}
|
|
3188
4782
|
${TRACING_RUNTIME_HELPERS_SOURCE}
|
|
3189
4783
|
${code}
|
|
4784
|
+
${CUSTOM_OBJECT_MATERIALIZER_SOURCE}
|
|
3190
4785
|
if (!Array.isArray(__operations) || !Array.isArray(__arguments)) {
|
|
3191
4786
|
throw new Error('ops-class execution requires inputs.operations and inputs.arguments (or ops/args)');
|
|
3192
4787
|
}
|
|
@@ -3213,6 +4808,7 @@ for (let __i = 0; __i < __operations.length; __i++) {
|
|
|
3213
4808
|
if (!Array.isArray(__callArgs)) {
|
|
3214
4809
|
__callArgs = [__callArgs];
|
|
3215
4810
|
}
|
|
4811
|
+
__callArgs = __callArgs.map((__arg) => __tracecodeMaterializeCustomObject(__arg));
|
|
3216
4812
|
if (__i === 0) {
|
|
3217
4813
|
__instance = new __targetClass(...__callArgs);
|
|
3218
4814
|
__out.push(null);
|
|
@@ -3291,7 +4887,7 @@ async function executeCode(payload) {
|
|
|
3291
4887
|
|
|
3292
4888
|
return {
|
|
3293
4889
|
success: true,
|
|
3294
|
-
output:
|
|
4890
|
+
output: serializeOutputValue(output),
|
|
3295
4891
|
consoleOutput,
|
|
3296
4892
|
};
|
|
3297
4893
|
} catch (error) {
|
|
@@ -3347,11 +4943,11 @@ async function executeWithTracing(payload) {
|
|
|
3347
4943
|
instrumentedCode = await instrumentCodeForTracing(executableCode, language, traceFunctionName);
|
|
3348
4944
|
}
|
|
3349
4945
|
} catch (instrumentationError) {
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
}
|
|
4946
|
+
const message =
|
|
4947
|
+
instrumentationError instanceof Error ? instrumentationError.message : String(instrumentationError);
|
|
4948
|
+
emitRuntimeDiagnostic('warn', 'trace-instrumentation-fallback', 'Trace instrumentation failed; using synthetic fallback.', {
|
|
4949
|
+
message,
|
|
4950
|
+
});
|
|
3355
4951
|
}
|
|
3356
4952
|
|
|
3357
4953
|
if (!instrumentedCode) {
|
|
@@ -3359,27 +4955,28 @@ async function executeWithTracing(payload) {
|
|
|
3359
4955
|
const executionTimeMs = performanceNow() - startedAt;
|
|
3360
4956
|
|
|
3361
4957
|
if (!fallbackResult.success) {
|
|
4958
|
+
const trace = createEmptyRuntimeTrace(language);
|
|
3362
4959
|
return {
|
|
3363
4960
|
success: false,
|
|
3364
4961
|
error: fallbackResult.error,
|
|
3365
4962
|
errorLine: fallbackResult.errorLine,
|
|
3366
|
-
trace
|
|
4963
|
+
trace,
|
|
3367
4964
|
executionTimeMs,
|
|
3368
4965
|
consoleOutput: fallbackResult.consoleOutput ?? [],
|
|
3369
|
-
lineEventCount:
|
|
3370
|
-
traceStepCount:
|
|
4966
|
+
lineEventCount: trace.lineEventCount,
|
|
4967
|
+
traceStepCount: trace.traceStepCount,
|
|
3371
4968
|
};
|
|
3372
4969
|
}
|
|
3373
4970
|
|
|
3374
|
-
const
|
|
4971
|
+
const trace = createSyntheticRuntimeTrace(payload, fallbackResult, language);
|
|
3375
4972
|
return {
|
|
3376
4973
|
success: true,
|
|
3377
4974
|
output: fallbackResult.output,
|
|
3378
|
-
trace
|
|
4975
|
+
trace,
|
|
3379
4976
|
executionTimeMs,
|
|
3380
4977
|
consoleOutput: fallbackResult.consoleOutput ?? [],
|
|
3381
|
-
lineEventCount:
|
|
3382
|
-
traceStepCount:
|
|
4978
|
+
lineEventCount: trace.lineEventCount,
|
|
4979
|
+
traceStepCount: trace.traceStepCount,
|
|
3383
4980
|
};
|
|
3384
4981
|
}
|
|
3385
4982
|
|
|
@@ -3422,21 +5019,23 @@ async function executeWithTracing(payload) {
|
|
|
3422
5019
|
);
|
|
3423
5020
|
}
|
|
3424
5021
|
|
|
3425
|
-
const
|
|
5022
|
+
const serializedTraceOutput = serializeValue(output);
|
|
5023
|
+
const serializedOutput = serializeOutputValue(output);
|
|
3426
5024
|
if (!hasNamedFunction) {
|
|
3427
5025
|
traceRecorder.popToFunction(traceFunctionName);
|
|
3428
|
-
traceRecorder.recordReturn(traceLineBounds.endLine,
|
|
5026
|
+
traceRecorder.recordReturn(traceLineBounds.endLine, serializedTraceOutput, traceFunctionName);
|
|
3429
5027
|
}
|
|
3430
5028
|
|
|
3431
5029
|
const executionTimeMs = performanceNow() - startedAt;
|
|
5030
|
+
const trace = traceRecorder.getRuntimeTrace(language, `${language}:run`, defaultRuntimeTraceFile(language));
|
|
3432
5031
|
return {
|
|
3433
5032
|
success: true,
|
|
3434
5033
|
output: serializedOutput,
|
|
3435
|
-
trace
|
|
5034
|
+
trace,
|
|
3436
5035
|
executionTimeMs,
|
|
3437
5036
|
consoleOutput,
|
|
3438
|
-
lineEventCount:
|
|
3439
|
-
traceStepCount:
|
|
5037
|
+
lineEventCount: trace.lineEventCount,
|
|
5038
|
+
traceStepCount: trace.traceStepCount,
|
|
3440
5039
|
traceLimitExceeded: traceRecorder.isTraceLimitExceeded(),
|
|
3441
5040
|
timeoutReason: traceRecorder.getTimeoutReason(),
|
|
3442
5041
|
};
|
|
@@ -3461,16 +5060,17 @@ async function executeWithTracing(payload) {
|
|
|
3461
5060
|
traceRecorder.recordException(traceErrorLine, message, traceFunctionName);
|
|
3462
5061
|
}
|
|
3463
5062
|
|
|
5063
|
+
const trace = traceRecorder.getRuntimeTrace(language, `${language}:run`, defaultRuntimeTraceFile(language));
|
|
3464
5064
|
return {
|
|
3465
5065
|
success: false,
|
|
3466
5066
|
output: null,
|
|
3467
5067
|
error: message,
|
|
3468
5068
|
errorLine,
|
|
3469
|
-
trace
|
|
5069
|
+
trace,
|
|
3470
5070
|
executionTimeMs,
|
|
3471
5071
|
consoleOutput,
|
|
3472
|
-
lineEventCount:
|
|
3473
|
-
traceStepCount:
|
|
5072
|
+
lineEventCount: trace.lineEventCount,
|
|
5073
|
+
traceStepCount: trace.traceStepCount,
|
|
3474
5074
|
traceLimitExceeded,
|
|
3475
5075
|
timeoutReason,
|
|
3476
5076
|
};
|
|
@@ -3537,11 +5137,37 @@ async function initRuntime() {
|
|
|
3537
5137
|
|
|
3538
5138
|
isLoading = true;
|
|
3539
5139
|
const startedAt = performanceNow();
|
|
5140
|
+
ensureJavaScriptLibraries();
|
|
3540
5141
|
isInitialized = true;
|
|
3541
5142
|
isLoading = false;
|
|
3542
5143
|
return { success: true, loadTimeMs: performanceNow() - startedAt };
|
|
3543
5144
|
}
|
|
3544
5145
|
|
|
5146
|
+
async function warmRuntime(payload = {}) {
|
|
5147
|
+
const startedAt = performanceNow();
|
|
5148
|
+
const initStartedAt = performanceNow();
|
|
5149
|
+
await initRuntime();
|
|
5150
|
+
const initMs = performanceNow() - initStartedAt;
|
|
5151
|
+
let compilerWarmupMs = 0;
|
|
5152
|
+
|
|
5153
|
+
if (payload?.language === 'typescript' || payload?.preloadTypeScriptCompiler === true) {
|
|
5154
|
+
const compilerStartedAt = performanceNow();
|
|
5155
|
+
await ensureTypeScriptCompiler();
|
|
5156
|
+
compilerWarmupMs = performanceNow() - compilerStartedAt;
|
|
5157
|
+
}
|
|
5158
|
+
|
|
5159
|
+
const totalMs = performanceNow() - startedAt;
|
|
5160
|
+
return {
|
|
5161
|
+
success: true,
|
|
5162
|
+
loadTimeMs: totalMs,
|
|
5163
|
+
timings: {
|
|
5164
|
+
totalMs,
|
|
5165
|
+
initMs,
|
|
5166
|
+
warmupMs: compilerWarmupMs,
|
|
5167
|
+
},
|
|
5168
|
+
};
|
|
5169
|
+
}
|
|
5170
|
+
|
|
3545
5171
|
async function processMessage(data) {
|
|
3546
5172
|
const { id, type, payload } = data;
|
|
3547
5173
|
|
|
@@ -3553,6 +5179,12 @@ async function processMessage(data) {
|
|
|
3553
5179
|
break;
|
|
3554
5180
|
}
|
|
3555
5181
|
|
|
5182
|
+
case 'warmup': {
|
|
5183
|
+
const result = await warmRuntime(payload);
|
|
5184
|
+
self.postMessage({ id, type: 'warmup-result', payload: result });
|
|
5185
|
+
break;
|
|
5186
|
+
}
|
|
5187
|
+
|
|
3556
5188
|
case 'execute-with-tracing': {
|
|
3557
5189
|
const result = await executeWithTracing(payload);
|
|
3558
5190
|
self.postMessage({ id, type: 'execute-result', payload: result });
|
|
@@ -3616,7 +5248,5 @@ self.onmessage = function(event) {
|
|
|
3616
5248
|
});
|
|
3617
5249
|
};
|
|
3618
5250
|
|
|
3619
|
-
|
|
3620
|
-
console.log('[JavaScriptWorker] ready');
|
|
3621
|
-
}
|
|
5251
|
+
emitRuntimeDiagnostic('info', 'worker-ready', 'JavaScript worker is ready.');
|
|
3622
5252
|
self.postMessage({ type: 'worker-ready' });
|