@tracecode/harness 0.6.6 → 0.7.0-beta8
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 +6169 -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 +907 -0
- package/workers/java/java-worker.js +2161 -177
- package/workers/java/src/harness/browser/JavaRewriteLibrary.java +1659 -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 +1414 -0
- package/workers/javascript/javascript-libraries-entry.js +71 -0
- package/workers/javascript/javascript-worker.js +2055 -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,41 @@ 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
|
+
createHeaderLine(),
|
|
3586
|
+
createAttachPendingAccessesStatement(ts),
|
|
2376
3587
|
],
|
|
2377
3588
|
true
|
|
2378
3589
|
);
|
|
@@ -2395,16 +3606,28 @@ function instrumentStatementList(
|
|
|
2395
3606
|
ts.getOriginalNode(visitedStatement) ??
|
|
2396
3607
|
visitedStatement;
|
|
2397
3608
|
if (shouldTraceStatement(ts, visitedStatement)) {
|
|
3609
|
+
const tracedLineStatement = createTraceLineStatement(
|
|
3610
|
+
ts,
|
|
3611
|
+
sourceFile,
|
|
3612
|
+
originalStatement,
|
|
3613
|
+
variableNames,
|
|
3614
|
+
lineFunctionMap,
|
|
3615
|
+
defaultFunctionName
|
|
3616
|
+
);
|
|
3617
|
+
if (isPostLineStateStatement(ts, sourceFile, originalStatement)) {
|
|
3618
|
+
nextStatements.push(visitedStatement);
|
|
3619
|
+
nextStatements.push(...traceScalarWriteStatementsForVariableStatement(ts, sourceFile, originalStatement));
|
|
3620
|
+
nextStatements.push(tracedLineStatement);
|
|
3621
|
+
continue;
|
|
3622
|
+
}
|
|
2398
3623
|
nextStatements.push(
|
|
2399
|
-
|
|
2400
|
-
ts,
|
|
2401
|
-
sourceFile,
|
|
2402
|
-
originalStatement,
|
|
2403
|
-
variableNames,
|
|
2404
|
-
lineFunctionMap,
|
|
2405
|
-
defaultFunctionName
|
|
2406
|
-
)
|
|
3624
|
+
tracedLineStatement
|
|
2407
3625
|
);
|
|
3626
|
+
nextStatements.push(visitedStatement);
|
|
3627
|
+
nextStatements.push(...traceScalarWriteStatementsForVariableStatement(ts, sourceFile, originalStatement));
|
|
3628
|
+
nextStatements.push(...traceScalarWriteStatementsForDestructuringAssignmentStatement(ts, sourceFile, originalStatement));
|
|
3629
|
+
nextStatements.push(createAttachPendingAccessesStatement(ts));
|
|
3630
|
+
continue;
|
|
2408
3631
|
}
|
|
2409
3632
|
nextStatements.push(visitedStatement);
|
|
2410
3633
|
}
|
|
@@ -2642,6 +3865,7 @@ async function instrumentCodeForTracing(sourceCode, language, traceFunctionName)
|
|
|
2642
3865
|
);
|
|
2643
3866
|
|
|
2644
3867
|
const variableNames = collectTraceVariableNames(ts, sourceFile);
|
|
3868
|
+
const localVariableNames = new Set(variableNames);
|
|
2645
3869
|
const effectiveFunctionName =
|
|
2646
3870
|
typeof traceFunctionName === 'string' && traceFunctionName.length > 0
|
|
2647
3871
|
? traceFunctionName
|
|
@@ -2662,14 +3886,31 @@ async function instrumentCodeForTracing(sourceCode, language, traceFunctionName)
|
|
|
2662
3886
|
const visitedIndices = tracedOperand.indices.map((indexExpr) => ts.visitNode(indexExpr, visit));
|
|
2663
3887
|
return createTraceUpdateExpression(
|
|
2664
3888
|
ts,
|
|
3889
|
+
sourceFile,
|
|
3890
|
+
node,
|
|
2665
3891
|
tracedOperand.variableName,
|
|
2666
3892
|
visitedIndices,
|
|
2667
3893
|
operatorName,
|
|
3894
|
+
ts.isPrefixUnaryExpression(node),
|
|
3895
|
+
tracedOperand.indices
|
|
3896
|
+
);
|
|
3897
|
+
}
|
|
3898
|
+
if (ts.isIdentifier(node.operand) && operatorName) {
|
|
3899
|
+
return createTraceScalarUpdateExpression(
|
|
3900
|
+
ts,
|
|
3901
|
+
sourceFile,
|
|
3902
|
+
node,
|
|
3903
|
+
node.operand.text,
|
|
3904
|
+
operatorName,
|
|
2668
3905
|
ts.isPrefixUnaryExpression(node)
|
|
2669
3906
|
);
|
|
2670
3907
|
}
|
|
2671
3908
|
}
|
|
2672
3909
|
|
|
3910
|
+
if (ts.isThrowStatement(node)) {
|
|
3911
|
+
return createTraceThrowExpression(ts, sourceFile, node);
|
|
3912
|
+
}
|
|
3913
|
+
|
|
2673
3914
|
if (ts.isBinaryExpression(node)) {
|
|
2674
3915
|
const tracedLeft = extractTraceableElementAccess(ts, node.left);
|
|
2675
3916
|
if (tracedLeft && isAssignmentOperatorToken(ts, node.operatorToken.kind)) {
|
|
@@ -2678,9 +3919,12 @@ async function instrumentCodeForTracing(sourceCode, language, traceFunctionName)
|
|
|
2678
3919
|
if (node.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
|
|
2679
3920
|
return createTraceWriteIndexExpression(
|
|
2680
3921
|
ts,
|
|
3922
|
+
sourceFile,
|
|
3923
|
+
node.left,
|
|
2681
3924
|
tracedLeft.variableName,
|
|
2682
3925
|
visitedIndices,
|
|
2683
|
-
visitedRight
|
|
3926
|
+
visitedRight,
|
|
3927
|
+
tracedLeft.indices
|
|
2684
3928
|
);
|
|
2685
3929
|
}
|
|
2686
3930
|
|
|
@@ -2688,34 +3932,87 @@ async function instrumentCodeForTracing(sourceCode, language, traceFunctionName)
|
|
|
2688
3932
|
if (operatorName) {
|
|
2689
3933
|
return createTraceAugAssignExpression(
|
|
2690
3934
|
ts,
|
|
3935
|
+
sourceFile,
|
|
3936
|
+
node.left,
|
|
2691
3937
|
tracedLeft.variableName,
|
|
2692
3938
|
visitedIndices,
|
|
2693
3939
|
operatorName,
|
|
2694
|
-
visitedRight
|
|
3940
|
+
visitedRight,
|
|
3941
|
+
tracedLeft.indices
|
|
2695
3942
|
);
|
|
2696
3943
|
}
|
|
2697
3944
|
}
|
|
3945
|
+
|
|
3946
|
+
if (ts.isIdentifier(node.left) && isAssignmentOperatorToken(ts, node.operatorToken.kind)) {
|
|
3947
|
+
const visitedRight = ts.visitNode(node.right, visit);
|
|
3948
|
+
const rewrittenAssignment = ts.factory.updateBinaryExpression(
|
|
3949
|
+
node,
|
|
3950
|
+
node.left,
|
|
3951
|
+
node.operatorToken,
|
|
3952
|
+
visitedRight
|
|
3953
|
+
);
|
|
3954
|
+
return createTraceScalarWriteExpression(
|
|
3955
|
+
ts,
|
|
3956
|
+
sourceFile,
|
|
3957
|
+
node.left,
|
|
3958
|
+
node.left.text,
|
|
3959
|
+
rewrittenAssignment
|
|
3960
|
+
);
|
|
3961
|
+
}
|
|
3962
|
+
|
|
3963
|
+
const tracedPropertyLeft = extractTraceablePropertyAccess(ts, node.left);
|
|
3964
|
+
if (tracedPropertyLeft && node.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
|
|
3965
|
+
const visitedRight = ts.visitNode(node.right, visit);
|
|
3966
|
+
return createTraceWritePropertyExpression(
|
|
3967
|
+
ts,
|
|
3968
|
+
sourceFile,
|
|
3969
|
+
node.left,
|
|
3970
|
+
tracedPropertyLeft.variableName,
|
|
3971
|
+
tracedPropertyLeft.propertyName,
|
|
3972
|
+
visitedRight
|
|
3973
|
+
);
|
|
3974
|
+
}
|
|
2698
3975
|
}
|
|
2699
3976
|
|
|
2700
3977
|
if (ts.isCallExpression(node)) {
|
|
3978
|
+
if (isConsoleLogCall(ts, node)) {
|
|
3979
|
+
return createTraceStdoutExpression(ts, sourceFile, node);
|
|
3980
|
+
}
|
|
2701
3981
|
const tracedCall = extractTraceableMutatingCall(ts, node);
|
|
2702
3982
|
if (tracedCall) {
|
|
2703
3983
|
const visitedArgs = node.arguments.map((arg) => ts.visitNode(arg, visit));
|
|
2704
|
-
return
|
|
3984
|
+
return createTraceMutatingCallExpressionForReceiver(
|
|
2705
3985
|
ts,
|
|
3986
|
+
sourceFile,
|
|
3987
|
+
node,
|
|
2706
3988
|
tracedCall.variableName,
|
|
3989
|
+
tracedCall.receiverExpression,
|
|
2707
3990
|
tracedCall.methodName,
|
|
2708
|
-
visitedArgs
|
|
3991
|
+
visitedArgs,
|
|
3992
|
+
tracedCall.indices?.map((indexExpr) => ts.visitNode(indexExpr, visit)) ?? [],
|
|
3993
|
+
tracedCall.indices ?? []
|
|
2709
3994
|
);
|
|
2710
3995
|
}
|
|
2711
3996
|
}
|
|
2712
3997
|
|
|
3998
|
+
if (ts.isIfStatement(node)) {
|
|
3999
|
+
const visited = ts.visitEachChild(node, visit, context);
|
|
4000
|
+
return ts.factory.updateIfStatement(
|
|
4001
|
+
visited,
|
|
4002
|
+
wrapTraceCondition(ts, visited.expression, shouldTraceIfStatementPostLine(ts, sourceFile, node)),
|
|
4003
|
+
visited.thenStatement,
|
|
4004
|
+
visited.elseStatement
|
|
4005
|
+
);
|
|
4006
|
+
}
|
|
4007
|
+
|
|
2713
4008
|
if (ts.isElementAccessExpression(node)) {
|
|
4009
|
+
const parent = node.parent;
|
|
2714
4010
|
if (
|
|
2715
4011
|
isNestedElementAccessExpression(ts, node) ||
|
|
2716
4012
|
isAssignmentLikeLeftOperand(ts, node) ||
|
|
2717
4013
|
isUpdateExpressionOperand(ts, node) ||
|
|
2718
|
-
isDestructuringAssignmentTarget(ts, node)
|
|
4014
|
+
isDestructuringAssignmentTarget(ts, node) ||
|
|
4015
|
+
(parent && ts.isCallExpression(parent) && parent.expression === node)
|
|
2719
4016
|
) {
|
|
2720
4017
|
return ts.visitEachChild(node, visit, context);
|
|
2721
4018
|
}
|
|
@@ -2723,7 +4020,57 @@ async function instrumentCodeForTracing(sourceCode, language, traceFunctionName)
|
|
|
2723
4020
|
const tracedAccess = extractTraceableElementAccess(ts, node);
|
|
2724
4021
|
if (tracedAccess) {
|
|
2725
4022
|
const visitedIndices = tracedAccess.indices.map((indexExpr) => ts.visitNode(indexExpr, visit));
|
|
2726
|
-
return createTraceReadIndexExpression(
|
|
4023
|
+
return createTraceReadIndexExpression(
|
|
4024
|
+
ts,
|
|
4025
|
+
sourceFile,
|
|
4026
|
+
node,
|
|
4027
|
+
tracedAccess.variableName,
|
|
4028
|
+
visitedIndices,
|
|
4029
|
+
tracedAccess.indices
|
|
4030
|
+
);
|
|
4031
|
+
}
|
|
4032
|
+
}
|
|
4033
|
+
|
|
4034
|
+
if (ts.isPropertyAccessExpression(node)) {
|
|
4035
|
+
const parent = node.parent;
|
|
4036
|
+
const grandparent = parent?.parent;
|
|
4037
|
+
if (
|
|
4038
|
+
isTraceablePropertyWriteLeftOperand(ts, node) ||
|
|
4039
|
+
isDestructuringAssignmentTarget(ts, node) ||
|
|
4040
|
+
(parent && ts.isCallExpression(parent) && parent.expression === node) ||
|
|
4041
|
+
(parent &&
|
|
4042
|
+
ts.isPropertyAccessExpression(parent) &&
|
|
4043
|
+
parent.expression === node &&
|
|
4044
|
+
grandparent &&
|
|
4045
|
+
ts.isCallExpression(grandparent) &&
|
|
4046
|
+
grandparent.expression === parent)
|
|
4047
|
+
) {
|
|
4048
|
+
return ts.visitEachChild(node, visit, context);
|
|
4049
|
+
}
|
|
4050
|
+
|
|
4051
|
+
const tracedIndexedPropertyAccess = extractTraceableElementAccess(ts, node);
|
|
4052
|
+
if (tracedIndexedPropertyAccess && tracedIndexedPropertyAccess.indices.length > 1) {
|
|
4053
|
+
const visitedIndices = tracedIndexedPropertyAccess.indices.map((indexExpr) => ts.visitNode(indexExpr, visit));
|
|
4054
|
+
return createTraceReadIndexExpression(
|
|
4055
|
+
ts,
|
|
4056
|
+
sourceFile,
|
|
4057
|
+
node,
|
|
4058
|
+
tracedIndexedPropertyAccess.variableName,
|
|
4059
|
+
visitedIndices,
|
|
4060
|
+
tracedIndexedPropertyAccess.indices
|
|
4061
|
+
);
|
|
4062
|
+
}
|
|
4063
|
+
|
|
4064
|
+
const tracedAccess = extractTraceablePropertyAccess(ts, node);
|
|
4065
|
+
if (tracedAccess) {
|
|
4066
|
+
return createTraceReadPropertyExpression(
|
|
4067
|
+
ts,
|
|
4068
|
+
sourceFile,
|
|
4069
|
+
node,
|
|
4070
|
+
tracedAccess.variableName,
|
|
4071
|
+
tracedAccess.propertyName,
|
|
4072
|
+
tracedAccess.scope ?? runtimeScopeForTraceableReceiver(tracedAccess.variableName, localVariableNames)
|
|
4073
|
+
);
|
|
2727
4074
|
}
|
|
2728
4075
|
}
|
|
2729
4076
|
|
|
@@ -2803,6 +4150,7 @@ async function instrumentCodeForTracing(sourceCode, language, traceFunctionName)
|
|
|
2803
4150
|
return rewriteForOfStatementForTracing(
|
|
2804
4151
|
ts,
|
|
2805
4152
|
sourceFile,
|
|
4153
|
+
context,
|
|
2806
4154
|
visited,
|
|
2807
4155
|
variableNames,
|
|
2808
4156
|
lineFunctionMap,
|
|
@@ -2865,9 +4213,7 @@ async function instrumentCodeForTracing(sourceCode, language, traceFunctionName)
|
|
|
2865
4213
|
function buildScriptExecutionRunner(code) {
|
|
2866
4214
|
return new Function(
|
|
2867
4215
|
'console',
|
|
2868
|
-
|
|
2869
|
-
${JAVASCRIPT_RUNTIME_PRELUDE}
|
|
2870
|
-
let result;
|
|
4216
|
+
`${JAVASCRIPT_RUNTIME_PRELUDE}
|
|
2871
4217
|
${code}
|
|
2872
4218
|
if (typeof result === 'undefined') {
|
|
2873
4219
|
return null;
|
|
@@ -2879,19 +4225,41 @@ return result;`
|
|
|
2879
4225
|
const TRACING_RUNTIME_HELPERS_SOURCE = `
|
|
2880
4226
|
function __traceNormalizeIndices(__indices, __maxDepth = 2) {
|
|
2881
4227
|
if (!Array.isArray(__indices) || __indices.length === 0 || __indices.length > __maxDepth) return null;
|
|
2882
|
-
if (!__indices.every((__index) =>
|
|
2883
|
-
|
|
4228
|
+
if (!__indices.every((__index) =>
|
|
4229
|
+
(typeof __index === 'number' && Number.isInteger(__index)) ||
|
|
4230
|
+
(typeof __index === 'string' && __index.length > 0)
|
|
4231
|
+
)) return null;
|
|
4232
|
+
return __indices.map((__index) => typeof __index === 'number' ? Math.trunc(__index) : __index);
|
|
4233
|
+
}
|
|
4234
|
+
|
|
4235
|
+
function __traceNormalizeIndexSources(__indexSources, __pathLength) {
|
|
4236
|
+
if (!Array.isArray(__indexSources) || !Number.isInteger(__pathLength) || __pathLength <= 0) return null;
|
|
4237
|
+
const __normalized = __indexSources.slice(0, __pathLength).map((__source) =>
|
|
4238
|
+
typeof __source === 'string' && __source.length > 0 ? __source : null
|
|
4239
|
+
);
|
|
4240
|
+
while (__normalized.length < __pathLength) __normalized.push(null);
|
|
4241
|
+
return __normalized.some((__source) => __source !== null) ? __normalized : null;
|
|
2884
4242
|
}
|
|
2885
4243
|
|
|
2886
4244
|
function __traceReadValueAtIndices(__container, __indices) {
|
|
2887
4245
|
let __current = __container;
|
|
2888
4246
|
for (const __index of __indices) {
|
|
2889
4247
|
if (__current === null || __current === undefined) return undefined;
|
|
2890
|
-
__current = __current[__index];
|
|
4248
|
+
__current = __traceIsMapLike(__current) ? __current.get(__index) : __current[__index];
|
|
2891
4249
|
}
|
|
2892
4250
|
return __current;
|
|
2893
4251
|
}
|
|
2894
4252
|
|
|
4253
|
+
function __traceIsMapLike(__value) {
|
|
4254
|
+
return __value instanceof Map ||
|
|
4255
|
+
(!!__value &&
|
|
4256
|
+
typeof __value === 'object' &&
|
|
4257
|
+
typeof __value.get === 'function' &&
|
|
4258
|
+
typeof __value.set === 'function' &&
|
|
4259
|
+
typeof __value.has === 'function' &&
|
|
4260
|
+
typeof __value.delete === 'function');
|
|
4261
|
+
}
|
|
4262
|
+
|
|
2895
4263
|
function __traceWriteValueAtIndices(__container, __indices, __value) {
|
|
2896
4264
|
if (__indices.length === 1) {
|
|
2897
4265
|
__container[__indices[0]] = __value;
|
|
@@ -2907,33 +4275,156 @@ function __traceWriteValueAtIndices(__container, __indices, __value) {
|
|
|
2907
4275
|
return __value;
|
|
2908
4276
|
}
|
|
2909
4277
|
|
|
2910
|
-
function __traceReadIndex(__varName, __container, __indices) {
|
|
4278
|
+
function __traceReadIndex(__varName, __container, __indices, __indexSources, __location) {
|
|
2911
4279
|
const __normalized = __traceNormalizeIndices(__indices);
|
|
4280
|
+
const __normalizedSources = __traceNormalizeIndexSources(__indexSources, __normalized?.length ?? 0);
|
|
4281
|
+
const __value = __traceReadValueAtIndices(__container, Array.isArray(__indices) ? __indices : []);
|
|
2912
4282
|
if (__normalized) {
|
|
2913
4283
|
__traceRecorder.recordAccess({
|
|
2914
4284
|
variable: __varName,
|
|
2915
4285
|
kind: __normalized.length === 2 ? 'cell-read' : 'indexed-read',
|
|
2916
4286
|
indices: __normalized,
|
|
4287
|
+
...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
|
|
2917
4288
|
pathDepth: __normalized.length,
|
|
4289
|
+
value: __value,
|
|
4290
|
+
...__traceNormalizeSourceLocation(__location),
|
|
4291
|
+
});
|
|
4292
|
+
}
|
|
4293
|
+
return __value;
|
|
4294
|
+
}
|
|
4295
|
+
|
|
4296
|
+
function* __traceIterableBind(__varName, __iterable, __bindingName, __location) {
|
|
4297
|
+
if (
|
|
4298
|
+
typeof __varName !== 'string' ||
|
|
4299
|
+
typeof __bindingName !== 'string' ||
|
|
4300
|
+
(__iterable === null || __iterable === undefined) ||
|
|
4301
|
+
typeof __iterable[Symbol.iterator] !== 'function'
|
|
4302
|
+
) {
|
|
4303
|
+
yield* __iterable;
|
|
4304
|
+
return;
|
|
4305
|
+
}
|
|
4306
|
+
let __index = 0;
|
|
4307
|
+
for (const __value of __iterable) {
|
|
4308
|
+
__traceRecorder.recordAccess({
|
|
4309
|
+
variable: __varName,
|
|
4310
|
+
kind: 'indexed-read',
|
|
4311
|
+
indices: [__index],
|
|
4312
|
+
pathDepth: 1,
|
|
4313
|
+
value: __value,
|
|
4314
|
+
binding: { kind: 'iteration', variable: __bindingName },
|
|
4315
|
+
...__traceNormalizeSourceLocation(__location),
|
|
2918
4316
|
});
|
|
4317
|
+
__index += 1;
|
|
4318
|
+
yield __value;
|
|
4319
|
+
}
|
|
4320
|
+
}
|
|
4321
|
+
|
|
4322
|
+
function* __traceIterableBindIndexed(__varName, __iterable, __baseIndices, __indexSources, __bindingName, __location) {
|
|
4323
|
+
if (
|
|
4324
|
+
typeof __varName !== 'string' ||
|
|
4325
|
+
typeof __bindingName !== 'string' ||
|
|
4326
|
+
(__iterable === null || __iterable === undefined) ||
|
|
4327
|
+
typeof __iterable[Symbol.iterator] !== 'function'
|
|
4328
|
+
) {
|
|
4329
|
+
yield* __iterable;
|
|
4330
|
+
return;
|
|
4331
|
+
}
|
|
4332
|
+
const __base = __traceNormalizeIndices(__baseIndices);
|
|
4333
|
+
const __baseSources = __traceNormalizeIndexSources(__indexSources, __base?.length ?? 0);
|
|
4334
|
+
let __index = 0;
|
|
4335
|
+
for (const __value of __iterable) {
|
|
4336
|
+
if (__base) {
|
|
4337
|
+
const __path = [...__base, __index];
|
|
4338
|
+
const __sources = Array.isArray(__baseSources) ? [...__baseSources, null] : null;
|
|
4339
|
+
__traceRecorder.recordAccess({
|
|
4340
|
+
variable: __varName,
|
|
4341
|
+
kind: __path.length === 2 ? 'cell-read' : 'indexed-read',
|
|
4342
|
+
indices: __path,
|
|
4343
|
+
pathDepth: __path.length,
|
|
4344
|
+
value: __value,
|
|
4345
|
+
...(Array.isArray(__sources) ? { indexSources: __sources } : {}),
|
|
4346
|
+
binding: { kind: 'iteration', variable: __bindingName },
|
|
4347
|
+
...__traceNormalizeSourceLocation(__location),
|
|
4348
|
+
});
|
|
4349
|
+
}
|
|
4350
|
+
__index += 1;
|
|
4351
|
+
yield __value;
|
|
4352
|
+
}
|
|
4353
|
+
}
|
|
4354
|
+
|
|
4355
|
+
function __traceIsMetadataProperty(__container, __propertyName) {
|
|
4356
|
+
if (__propertyName === 'length') {
|
|
4357
|
+
return Array.isArray(__container) || typeof __container === 'string';
|
|
4358
|
+
}
|
|
4359
|
+
if (__propertyName === 'size') {
|
|
4360
|
+
return __traceIsMapLike(__container) || __container instanceof Set;
|
|
2919
4361
|
}
|
|
2920
|
-
return
|
|
4362
|
+
return false;
|
|
4363
|
+
}
|
|
4364
|
+
|
|
4365
|
+
function __traceNormalizeSourceLocation(__location) {
|
|
4366
|
+
if (!__location || typeof __location !== 'object') return {};
|
|
4367
|
+
const __line = Number(__location.line);
|
|
4368
|
+
const __column = Number(__location.column);
|
|
4369
|
+
return {
|
|
4370
|
+
...(Number.isFinite(__line) && __line > 0 ? { line: Math.trunc(__line) } : {}),
|
|
4371
|
+
...(Number.isFinite(__column) && __column >= 0 ? { column: Math.trunc(__column) } : {}),
|
|
4372
|
+
};
|
|
4373
|
+
}
|
|
4374
|
+
|
|
4375
|
+
function __traceReadProperty(__varName, __container, __propertyName, __scopeOrLocation, __maybeLocation) {
|
|
4376
|
+
const __scope = typeof __scopeOrLocation === 'string' ? __scopeOrLocation : undefined;
|
|
4377
|
+
const __location = typeof __scopeOrLocation === 'string' ? __maybeLocation : __scopeOrLocation;
|
|
4378
|
+
__traceRecorder.recordAccess({
|
|
4379
|
+
variable: __varName,
|
|
4380
|
+
kind: 'indexed-read',
|
|
4381
|
+
indices: [__propertyName],
|
|
4382
|
+
pathDepth: 1,
|
|
4383
|
+
...(__scope ? { scope: __scope } : {}),
|
|
4384
|
+
...__traceNormalizeSourceLocation(__location),
|
|
4385
|
+
});
|
|
4386
|
+
return __container?.[__propertyName];
|
|
2921
4387
|
}
|
|
2922
4388
|
|
|
2923
|
-
function __traceWriteIndex(__varName, __container, __indices, __value) {
|
|
4389
|
+
function __traceWriteIndex(__varName, __container, __indices, __indexSources, __value, __location) {
|
|
2924
4390
|
const __normalized = __traceNormalizeIndices(__indices);
|
|
4391
|
+
const __normalizedSources = __traceNormalizeIndexSources(__indexSources, __normalized?.length ?? 0);
|
|
2925
4392
|
const __result = __traceWriteValueAtIndices(__container, Array.isArray(__indices) ? __indices : [], __value);
|
|
2926
4393
|
if (__normalized) {
|
|
2927
4394
|
__traceRecorder.recordAccess({
|
|
2928
4395
|
variable: __varName,
|
|
2929
4396
|
kind: __normalized.length === 2 ? 'cell-write' : 'indexed-write',
|
|
2930
4397
|
indices: __normalized,
|
|
4398
|
+
...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
|
|
2931
4399
|
pathDepth: __normalized.length,
|
|
4400
|
+
value: __result,
|
|
4401
|
+
...__traceNormalizeSourceLocation(__location),
|
|
2932
4402
|
});
|
|
2933
4403
|
}
|
|
2934
4404
|
return __result;
|
|
2935
4405
|
}
|
|
2936
4406
|
|
|
4407
|
+
function __traceScalarWrite(__varName, __value, __location) {
|
|
4408
|
+
__traceRecorder.recordAccess({
|
|
4409
|
+
variable: __varName,
|
|
4410
|
+
kind: 'indexed-write',
|
|
4411
|
+
value: __value,
|
|
4412
|
+
...__traceNormalizeSourceLocation(__location),
|
|
4413
|
+
});
|
|
4414
|
+
return __value;
|
|
4415
|
+
}
|
|
4416
|
+
|
|
4417
|
+
function __traceAssignScalar(__varName, __value, __location) {
|
|
4418
|
+
return __traceScalarWrite(__varName, __value, __location);
|
|
4419
|
+
}
|
|
4420
|
+
|
|
4421
|
+
function __traceUpdateScalar(__varName, __update, __current, __isPrefix, __location) {
|
|
4422
|
+
const __result = typeof __update === 'function' ? __update() : undefined;
|
|
4423
|
+
const __value = typeof __current === 'function' ? __current() : __result;
|
|
4424
|
+
__traceScalarWrite(__varName, __value, __location);
|
|
4425
|
+
return __isPrefix ? __value : __result;
|
|
4426
|
+
}
|
|
4427
|
+
|
|
2937
4428
|
function __traceApplyAugmentedValue(__current, __op, __rhs) {
|
|
2938
4429
|
switch (__op) {
|
|
2939
4430
|
case 'add': return __current + __rhs;
|
|
@@ -2951,8 +4442,9 @@ function __traceApplyAugmentedValue(__current, __op, __rhs) {
|
|
|
2951
4442
|
}
|
|
2952
4443
|
}
|
|
2953
4444
|
|
|
2954
|
-
function __traceAugAssignIndex(__varName, __container, __indices, __op, __rhs) {
|
|
4445
|
+
function __traceAugAssignIndex(__varName, __container, __indices, __indexSources, __op, __rhs, __location) {
|
|
2955
4446
|
const __normalized = __traceNormalizeIndices(__indices);
|
|
4447
|
+
const __normalizedSources = __traceNormalizeIndexSources(__indexSources, __normalized?.length ?? 0);
|
|
2956
4448
|
const __effectiveIndices = Array.isArray(__indices) ? __indices : [];
|
|
2957
4449
|
const __current = __traceReadValueAtIndices(__container, __effectiveIndices);
|
|
2958
4450
|
if (__normalized) {
|
|
@@ -2960,7 +4452,9 @@ function __traceAugAssignIndex(__varName, __container, __indices, __op, __rhs) {
|
|
|
2960
4452
|
variable: __varName,
|
|
2961
4453
|
kind: __normalized.length === 2 ? 'cell-read' : 'indexed-read',
|
|
2962
4454
|
indices: __normalized,
|
|
4455
|
+
...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
|
|
2963
4456
|
pathDepth: __normalized.length,
|
|
4457
|
+
...__traceNormalizeSourceLocation(__location),
|
|
2964
4458
|
});
|
|
2965
4459
|
}
|
|
2966
4460
|
const __next = __traceApplyAugmentedValue(__current, __op, __rhs);
|
|
@@ -2970,14 +4464,18 @@ function __traceAugAssignIndex(__varName, __container, __indices, __op, __rhs) {
|
|
|
2970
4464
|
variable: __varName,
|
|
2971
4465
|
kind: __normalized.length === 2 ? 'cell-write' : 'indexed-write',
|
|
2972
4466
|
indices: __normalized,
|
|
4467
|
+
...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
|
|
2973
4468
|
pathDepth: __normalized.length,
|
|
4469
|
+
value: __next,
|
|
4470
|
+
...__traceNormalizeSourceLocation(__location),
|
|
2974
4471
|
});
|
|
2975
4472
|
}
|
|
2976
4473
|
return __next;
|
|
2977
4474
|
}
|
|
2978
4475
|
|
|
2979
|
-
function __traceUpdateIndex(__varName, __container, __indices, __op, __isPrefix) {
|
|
4476
|
+
function __traceUpdateIndex(__varName, __container, __indices, __indexSources, __op, __isPrefix, __location) {
|
|
2980
4477
|
const __normalized = __traceNormalizeIndices(__indices);
|
|
4478
|
+
const __normalizedSources = __traceNormalizeIndexSources(__indexSources, __normalized?.length ?? 0);
|
|
2981
4479
|
const __effectiveIndices = Array.isArray(__indices) ? __indices : [];
|
|
2982
4480
|
const __current = __traceReadValueAtIndices(__container, __effectiveIndices);
|
|
2983
4481
|
if (__normalized) {
|
|
@@ -2985,7 +4483,9 @@ function __traceUpdateIndex(__varName, __container, __indices, __op, __isPrefix)
|
|
|
2985
4483
|
variable: __varName,
|
|
2986
4484
|
kind: __normalized.length === 2 ? 'cell-read' : 'indexed-read',
|
|
2987
4485
|
indices: __normalized,
|
|
4486
|
+
...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
|
|
2988
4487
|
pathDepth: __normalized.length,
|
|
4488
|
+
...__traceNormalizeSourceLocation(__location),
|
|
2989
4489
|
});
|
|
2990
4490
|
}
|
|
2991
4491
|
const __delta = __op === 'dec' ? -1 : 1;
|
|
@@ -2996,20 +4496,111 @@ function __traceUpdateIndex(__varName, __container, __indices, __op, __isPrefix)
|
|
|
2996
4496
|
variable: __varName,
|
|
2997
4497
|
kind: __normalized.length === 2 ? 'cell-write' : 'indexed-write',
|
|
2998
4498
|
indices: __normalized,
|
|
4499
|
+
...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
|
|
2999
4500
|
pathDepth: __normalized.length,
|
|
4501
|
+
value: __next,
|
|
4502
|
+
...__traceNormalizeSourceLocation(__location),
|
|
3000
4503
|
});
|
|
3001
4504
|
}
|
|
3002
4505
|
return __isPrefix ? __next : __current;
|
|
3003
4506
|
}
|
|
3004
4507
|
|
|
3005
|
-
function
|
|
3006
|
-
|
|
3007
|
-
|
|
4508
|
+
function __traceNormalizeMethodName(__container, __method, __args) {
|
|
4509
|
+
void __container;
|
|
4510
|
+
void __args;
|
|
4511
|
+
return __method;
|
|
4512
|
+
}
|
|
4513
|
+
|
|
4514
|
+
function __traceStdout(__line, ...__args) {
|
|
4515
|
+
console.log(...__args);
|
|
4516
|
+
__traceRecorder.recordStdout(__line, __args.map((__arg) => String(__arg)).join(' '));
|
|
4517
|
+
}
|
|
4518
|
+
|
|
4519
|
+
function __traceExceptionValue(__line, __error) {
|
|
4520
|
+
__traceRecorder.recordException(__line, __error);
|
|
4521
|
+
return __error;
|
|
4522
|
+
}
|
|
4523
|
+
|
|
4524
|
+
function __traceMutatingCall(__varName, __container, __indices, __indexSources, __method, __location, ...__args) {
|
|
4525
|
+
const __sourceLocation = __traceNormalizeSourceLocation(__location);
|
|
4526
|
+
let __target = __container;
|
|
4527
|
+
for (const __index of __indices || []) {
|
|
4528
|
+
__target = __traceIsMapLike(__target) ? __target.get(__index) : __target?.[__index];
|
|
4529
|
+
}
|
|
4530
|
+
const __mayMutate = ['push', 'pop', 'shift', 'unshift', 'splice', 'set', 'add', 'delete', 'clear'].includes(__method);
|
|
4531
|
+
const __result = __target[__method](...__args);
|
|
4532
|
+
if (['push', 'pop', 'shift', 'unshift', 'splice', 'set', 'get', 'has', 'add', 'delete', 'clear'].includes(__method)) {
|
|
4533
|
+
const __path = __indices || [];
|
|
4534
|
+
const __isMapLike = __traceIsMapLike(__target);
|
|
4535
|
+
const __isNestedMap = __path.length > 0 && __traceIsMapLike(__target);
|
|
4536
|
+
if (__isMapLike && __method === 'set') {
|
|
4537
|
+
const __normalizedSources = __traceNormalizeIndexSources(__indexSources, __path.length + 1);
|
|
4538
|
+
const __targetPath = [...__path, __args[0]];
|
|
4539
|
+
__traceRecorder.recordAccess({
|
|
4540
|
+
variable: __varName,
|
|
4541
|
+
kind: 'indexed-write',
|
|
4542
|
+
indices: __targetPath,
|
|
4543
|
+
pathDepth: __path.length + 1,
|
|
4544
|
+
...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
|
|
4545
|
+
value: serializeValue(__args[1]),
|
|
4546
|
+
...__sourceLocation,
|
|
4547
|
+
});
|
|
4548
|
+
__traceRecorder.recordAccess({
|
|
4549
|
+
variable: __varName,
|
|
4550
|
+
kind: 'mutating-call',
|
|
4551
|
+
method: __traceNormalizeMethodName(__target, __method, __args),
|
|
4552
|
+
args: __args,
|
|
4553
|
+
indices: __targetPath,
|
|
4554
|
+
pathDepth: __path.length + 1,
|
|
4555
|
+
...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
|
|
4556
|
+
...__sourceLocation,
|
|
4557
|
+
});
|
|
4558
|
+
return __result;
|
|
4559
|
+
}
|
|
4560
|
+
if (__isMapLike && (__method === 'get' || __method === 'has')) {
|
|
4561
|
+
const __normalizedSources = __traceNormalizeIndexSources(__indexSources, __path.length + 1);
|
|
4562
|
+
__traceRecorder.recordAccess({
|
|
4563
|
+
variable: __varName,
|
|
4564
|
+
kind: 'indexed-read',
|
|
4565
|
+
indices: [...__path, __args[0]],
|
|
4566
|
+
pathDepth: __path.length + 1,
|
|
4567
|
+
...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
|
|
4568
|
+
value: serializeValue(__result),
|
|
4569
|
+
...__sourceLocation,
|
|
4570
|
+
});
|
|
4571
|
+
return __result;
|
|
4572
|
+
}
|
|
4573
|
+
if (__target instanceof Set && __method === 'has') {
|
|
4574
|
+
__traceRecorder.recordAccess({
|
|
4575
|
+
variable: __varName,
|
|
4576
|
+
kind: 'indexed-read',
|
|
4577
|
+
indices: [...__path, __args[0]],
|
|
4578
|
+
pathDepth: __path.length + 1,
|
|
4579
|
+
...__sourceLocation,
|
|
4580
|
+
});
|
|
4581
|
+
return __result;
|
|
4582
|
+
}
|
|
4583
|
+
if (__path.length > 0) {
|
|
4584
|
+
const __normalizedSources = __traceNormalizeIndexSources(__indexSources, __path.length);
|
|
4585
|
+
__traceRecorder.recordAccess({
|
|
4586
|
+
variable: __varName,
|
|
4587
|
+
kind: 'indexed-read',
|
|
4588
|
+
indices: __path,
|
|
4589
|
+
pathDepth: __path.length,
|
|
4590
|
+
...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
|
|
4591
|
+
...__sourceLocation,
|
|
4592
|
+
});
|
|
4593
|
+
}
|
|
4594
|
+
const __normalizedSources = __traceNormalizeIndexSources(__indexSources, __path.length);
|
|
3008
4595
|
__traceRecorder.recordAccess({
|
|
3009
4596
|
variable: __varName,
|
|
3010
4597
|
kind: 'mutating-call',
|
|
3011
|
-
method: __method,
|
|
3012
|
-
|
|
4598
|
+
method: __traceNormalizeMethodName(__target, __method, __args),
|
|
4599
|
+
args: __args,
|
|
4600
|
+
indices: __path,
|
|
4601
|
+
pathDepth: __path.length,
|
|
4602
|
+
...(Array.isArray(__normalizedSources) ? { indexSources: __normalizedSources } : {}),
|
|
4603
|
+
...__sourceLocation,
|
|
3013
4604
|
});
|
|
3014
4605
|
}
|
|
3015
4606
|
return __result;
|
|
@@ -3021,10 +4612,8 @@ function buildScriptTracingRunner(code) {
|
|
|
3021
4612
|
'console',
|
|
3022
4613
|
'__traceRecorder',
|
|
3023
4614
|
'__traceCtx',
|
|
3024
|
-
|
|
3025
|
-
${JAVASCRIPT_RUNTIME_PRELUDE}
|
|
4615
|
+
`${JAVASCRIPT_RUNTIME_PRELUDE}
|
|
3026
4616
|
${TRACING_RUNTIME_HELPERS_SOURCE}
|
|
3027
|
-
let result;
|
|
3028
4617
|
${code}
|
|
3029
4618
|
if (typeof result === 'undefined') {
|
|
3030
4619
|
return null;
|
|
@@ -3042,6 +4631,7 @@ function buildFunctionExecutionRunner(code, executionStyle, argNames) {
|
|
|
3042
4631
|
`"use strict";
|
|
3043
4632
|
${JAVASCRIPT_RUNTIME_PRELUDE}
|
|
3044
4633
|
${code}
|
|
4634
|
+
${CUSTOM_OBJECT_MATERIALIZER_SOURCE}
|
|
3045
4635
|
let __target;
|
|
3046
4636
|
try {
|
|
3047
4637
|
__target = eval(__functionName);
|
|
@@ -3051,7 +4641,7 @@ try {
|
|
|
3051
4641
|
if (typeof __target !== 'function') {
|
|
3052
4642
|
throw new Error('Function "' + __functionName + '" not found');
|
|
3053
4643
|
}
|
|
3054
|
-
return __target(${argNames.join(', ')});`
|
|
4644
|
+
return __target(${argNames.map((name) => `__tracecodeMaterializeCustomObject(${name})`).join(', ')});`
|
|
3055
4645
|
);
|
|
3056
4646
|
}
|
|
3057
4647
|
|
|
@@ -3063,6 +4653,7 @@ return __target(${argNames.join(', ')});`
|
|
|
3063
4653
|
`"use strict";
|
|
3064
4654
|
${JAVASCRIPT_RUNTIME_PRELUDE}
|
|
3065
4655
|
${code}
|
|
4656
|
+
${CUSTOM_OBJECT_MATERIALIZER_SOURCE}
|
|
3066
4657
|
if (typeof Solution !== 'function') {
|
|
3067
4658
|
throw new Error('Class "Solution" not found');
|
|
3068
4659
|
}
|
|
@@ -3071,7 +4662,7 @@ const __method = __solver[__functionName];
|
|
|
3071
4662
|
if (typeof __method !== 'function') {
|
|
3072
4663
|
throw new Error('Method "Solution.' + __functionName + '" not found');
|
|
3073
4664
|
}
|
|
3074
|
-
return __method.call(__solver, ${argNames.join(', ')});`
|
|
4665
|
+
return __method.call(__solver, ${argNames.map((name) => `__tracecodeMaterializeCustomObject(${name})`).join(', ')});`
|
|
3075
4666
|
);
|
|
3076
4667
|
}
|
|
3077
4668
|
|
|
@@ -3084,6 +4675,7 @@ return __method.call(__solver, ${argNames.join(', ')});`
|
|
|
3084
4675
|
`"use strict";
|
|
3085
4676
|
${JAVASCRIPT_RUNTIME_PRELUDE}
|
|
3086
4677
|
${code}
|
|
4678
|
+
${CUSTOM_OBJECT_MATERIALIZER_SOURCE}
|
|
3087
4679
|
if (!Array.isArray(__operations) || !Array.isArray(__arguments)) {
|
|
3088
4680
|
throw new Error('ops-class execution requires inputs.operations and inputs.arguments (or ops/args)');
|
|
3089
4681
|
}
|
|
@@ -3110,6 +4702,7 @@ for (let __i = 0; __i < __operations.length; __i++) {
|
|
|
3110
4702
|
if (!Array.isArray(__callArgs)) {
|
|
3111
4703
|
__callArgs = [__callArgs];
|
|
3112
4704
|
}
|
|
4705
|
+
__callArgs = __callArgs.map((__arg) => __tracecodeMaterializeCustomObject(__arg));
|
|
3113
4706
|
if (__i === 0) {
|
|
3114
4707
|
__instance = new __targetClass(...__callArgs);
|
|
3115
4708
|
__out.push(null);
|
|
@@ -3139,6 +4732,7 @@ function buildFunctionTracingRunner(code, executionStyle, argNames) {
|
|
|
3139
4732
|
${JAVASCRIPT_RUNTIME_PRELUDE}
|
|
3140
4733
|
${TRACING_RUNTIME_HELPERS_SOURCE}
|
|
3141
4734
|
${code}
|
|
4735
|
+
${CUSTOM_OBJECT_MATERIALIZER_SOURCE}
|
|
3142
4736
|
let __target;
|
|
3143
4737
|
try {
|
|
3144
4738
|
__target = eval(__functionName);
|
|
@@ -3148,7 +4742,7 @@ try {
|
|
|
3148
4742
|
if (typeof __target !== 'function') {
|
|
3149
4743
|
throw new Error('Function "' + __functionName + '" not found');
|
|
3150
4744
|
}
|
|
3151
|
-
return __target(${argNames.join(', ')});`
|
|
4745
|
+
return __target(${argNames.map((name) => `__tracecodeMaterializeCustomObject(${name})`).join(', ')});`
|
|
3152
4746
|
);
|
|
3153
4747
|
}
|
|
3154
4748
|
|
|
@@ -3163,6 +4757,7 @@ return __target(${argNames.join(', ')});`
|
|
|
3163
4757
|
${JAVASCRIPT_RUNTIME_PRELUDE}
|
|
3164
4758
|
${TRACING_RUNTIME_HELPERS_SOURCE}
|
|
3165
4759
|
${code}
|
|
4760
|
+
${CUSTOM_OBJECT_MATERIALIZER_SOURCE}
|
|
3166
4761
|
if (typeof Solution !== 'function') {
|
|
3167
4762
|
throw new Error('Class "Solution" not found');
|
|
3168
4763
|
}
|
|
@@ -3171,7 +4766,7 @@ const __method = __solver[__functionName];
|
|
|
3171
4766
|
if (typeof __method !== 'function') {
|
|
3172
4767
|
throw new Error('Method "Solution.' + __functionName + '" not found');
|
|
3173
4768
|
}
|
|
3174
|
-
return __method.call(__solver, ${argNames.join(', ')});`
|
|
4769
|
+
return __method.call(__solver, ${argNames.map((name) => `__tracecodeMaterializeCustomObject(${name})`).join(', ')});`
|
|
3175
4770
|
);
|
|
3176
4771
|
}
|
|
3177
4772
|
|
|
@@ -3187,6 +4782,7 @@ return __method.call(__solver, ${argNames.join(', ')});`
|
|
|
3187
4782
|
${JAVASCRIPT_RUNTIME_PRELUDE}
|
|
3188
4783
|
${TRACING_RUNTIME_HELPERS_SOURCE}
|
|
3189
4784
|
${code}
|
|
4785
|
+
${CUSTOM_OBJECT_MATERIALIZER_SOURCE}
|
|
3190
4786
|
if (!Array.isArray(__operations) || !Array.isArray(__arguments)) {
|
|
3191
4787
|
throw new Error('ops-class execution requires inputs.operations and inputs.arguments (or ops/args)');
|
|
3192
4788
|
}
|
|
@@ -3213,6 +4809,7 @@ for (let __i = 0; __i < __operations.length; __i++) {
|
|
|
3213
4809
|
if (!Array.isArray(__callArgs)) {
|
|
3214
4810
|
__callArgs = [__callArgs];
|
|
3215
4811
|
}
|
|
4812
|
+
__callArgs = __callArgs.map((__arg) => __tracecodeMaterializeCustomObject(__arg));
|
|
3216
4813
|
if (__i === 0) {
|
|
3217
4814
|
__instance = new __targetClass(...__callArgs);
|
|
3218
4815
|
__out.push(null);
|
|
@@ -3291,7 +4888,7 @@ async function executeCode(payload) {
|
|
|
3291
4888
|
|
|
3292
4889
|
return {
|
|
3293
4890
|
success: true,
|
|
3294
|
-
output:
|
|
4891
|
+
output: serializeOutputValue(output),
|
|
3295
4892
|
consoleOutput,
|
|
3296
4893
|
};
|
|
3297
4894
|
} catch (error) {
|
|
@@ -3347,11 +4944,11 @@ async function executeWithTracing(payload) {
|
|
|
3347
4944
|
instrumentedCode = await instrumentCodeForTracing(executableCode, language, traceFunctionName);
|
|
3348
4945
|
}
|
|
3349
4946
|
} catch (instrumentationError) {
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
}
|
|
4947
|
+
const message =
|
|
4948
|
+
instrumentationError instanceof Error ? instrumentationError.message : String(instrumentationError);
|
|
4949
|
+
emitRuntimeDiagnostic('warn', 'trace-instrumentation-fallback', 'Trace instrumentation failed; using synthetic fallback.', {
|
|
4950
|
+
message,
|
|
4951
|
+
});
|
|
3355
4952
|
}
|
|
3356
4953
|
|
|
3357
4954
|
if (!instrumentedCode) {
|
|
@@ -3359,27 +4956,28 @@ async function executeWithTracing(payload) {
|
|
|
3359
4956
|
const executionTimeMs = performanceNow() - startedAt;
|
|
3360
4957
|
|
|
3361
4958
|
if (!fallbackResult.success) {
|
|
4959
|
+
const trace = createEmptyRuntimeTrace(language);
|
|
3362
4960
|
return {
|
|
3363
4961
|
success: false,
|
|
3364
4962
|
error: fallbackResult.error,
|
|
3365
4963
|
errorLine: fallbackResult.errorLine,
|
|
3366
|
-
trace
|
|
4964
|
+
trace,
|
|
3367
4965
|
executionTimeMs,
|
|
3368
4966
|
consoleOutput: fallbackResult.consoleOutput ?? [],
|
|
3369
|
-
lineEventCount:
|
|
3370
|
-
traceStepCount:
|
|
4967
|
+
lineEventCount: trace.lineEventCount,
|
|
4968
|
+
traceStepCount: trace.traceStepCount,
|
|
3371
4969
|
};
|
|
3372
4970
|
}
|
|
3373
4971
|
|
|
3374
|
-
const
|
|
4972
|
+
const trace = createSyntheticRuntimeTrace(payload, fallbackResult, language);
|
|
3375
4973
|
return {
|
|
3376
4974
|
success: true,
|
|
3377
4975
|
output: fallbackResult.output,
|
|
3378
|
-
trace
|
|
4976
|
+
trace,
|
|
3379
4977
|
executionTimeMs,
|
|
3380
4978
|
consoleOutput: fallbackResult.consoleOutput ?? [],
|
|
3381
|
-
lineEventCount:
|
|
3382
|
-
traceStepCount:
|
|
4979
|
+
lineEventCount: trace.lineEventCount,
|
|
4980
|
+
traceStepCount: trace.traceStepCount,
|
|
3383
4981
|
};
|
|
3384
4982
|
}
|
|
3385
4983
|
|
|
@@ -3422,21 +5020,23 @@ async function executeWithTracing(payload) {
|
|
|
3422
5020
|
);
|
|
3423
5021
|
}
|
|
3424
5022
|
|
|
3425
|
-
const
|
|
5023
|
+
const serializedTraceOutput = serializeValue(output);
|
|
5024
|
+
const serializedOutput = serializeOutputValue(output);
|
|
3426
5025
|
if (!hasNamedFunction) {
|
|
3427
5026
|
traceRecorder.popToFunction(traceFunctionName);
|
|
3428
|
-
traceRecorder.recordReturn(traceLineBounds.endLine,
|
|
5027
|
+
traceRecorder.recordReturn(traceLineBounds.endLine, serializedTraceOutput, traceFunctionName);
|
|
3429
5028
|
}
|
|
3430
5029
|
|
|
3431
5030
|
const executionTimeMs = performanceNow() - startedAt;
|
|
5031
|
+
const trace = traceRecorder.getRuntimeTrace(language, `${language}:run`, defaultRuntimeTraceFile(language));
|
|
3432
5032
|
return {
|
|
3433
5033
|
success: true,
|
|
3434
5034
|
output: serializedOutput,
|
|
3435
|
-
trace
|
|
5035
|
+
trace,
|
|
3436
5036
|
executionTimeMs,
|
|
3437
5037
|
consoleOutput,
|
|
3438
|
-
lineEventCount:
|
|
3439
|
-
traceStepCount:
|
|
5038
|
+
lineEventCount: trace.lineEventCount,
|
|
5039
|
+
traceStepCount: trace.traceStepCount,
|
|
3440
5040
|
traceLimitExceeded: traceRecorder.isTraceLimitExceeded(),
|
|
3441
5041
|
timeoutReason: traceRecorder.getTimeoutReason(),
|
|
3442
5042
|
};
|
|
@@ -3461,16 +5061,17 @@ async function executeWithTracing(payload) {
|
|
|
3461
5061
|
traceRecorder.recordException(traceErrorLine, message, traceFunctionName);
|
|
3462
5062
|
}
|
|
3463
5063
|
|
|
5064
|
+
const trace = traceRecorder.getRuntimeTrace(language, `${language}:run`, defaultRuntimeTraceFile(language));
|
|
3464
5065
|
return {
|
|
3465
5066
|
success: false,
|
|
3466
5067
|
output: null,
|
|
3467
5068
|
error: message,
|
|
3468
5069
|
errorLine,
|
|
3469
|
-
trace
|
|
5070
|
+
trace,
|
|
3470
5071
|
executionTimeMs,
|
|
3471
5072
|
consoleOutput,
|
|
3472
|
-
lineEventCount:
|
|
3473
|
-
traceStepCount:
|
|
5073
|
+
lineEventCount: trace.lineEventCount,
|
|
5074
|
+
traceStepCount: trace.traceStepCount,
|
|
3474
5075
|
traceLimitExceeded,
|
|
3475
5076
|
timeoutReason,
|
|
3476
5077
|
};
|
|
@@ -3537,11 +5138,37 @@ async function initRuntime() {
|
|
|
3537
5138
|
|
|
3538
5139
|
isLoading = true;
|
|
3539
5140
|
const startedAt = performanceNow();
|
|
5141
|
+
ensureJavaScriptLibraries();
|
|
3540
5142
|
isInitialized = true;
|
|
3541
5143
|
isLoading = false;
|
|
3542
5144
|
return { success: true, loadTimeMs: performanceNow() - startedAt };
|
|
3543
5145
|
}
|
|
3544
5146
|
|
|
5147
|
+
async function warmRuntime(payload = {}) {
|
|
5148
|
+
const startedAt = performanceNow();
|
|
5149
|
+
const initStartedAt = performanceNow();
|
|
5150
|
+
await initRuntime();
|
|
5151
|
+
const initMs = performanceNow() - initStartedAt;
|
|
5152
|
+
let compilerWarmupMs = 0;
|
|
5153
|
+
|
|
5154
|
+
if (payload?.language === 'typescript' || payload?.preloadTypeScriptCompiler === true) {
|
|
5155
|
+
const compilerStartedAt = performanceNow();
|
|
5156
|
+
await ensureTypeScriptCompiler();
|
|
5157
|
+
compilerWarmupMs = performanceNow() - compilerStartedAt;
|
|
5158
|
+
}
|
|
5159
|
+
|
|
5160
|
+
const totalMs = performanceNow() - startedAt;
|
|
5161
|
+
return {
|
|
5162
|
+
success: true,
|
|
5163
|
+
loadTimeMs: totalMs,
|
|
5164
|
+
timings: {
|
|
5165
|
+
totalMs,
|
|
5166
|
+
initMs,
|
|
5167
|
+
warmupMs: compilerWarmupMs,
|
|
5168
|
+
},
|
|
5169
|
+
};
|
|
5170
|
+
}
|
|
5171
|
+
|
|
3545
5172
|
async function processMessage(data) {
|
|
3546
5173
|
const { id, type, payload } = data;
|
|
3547
5174
|
|
|
@@ -3553,6 +5180,12 @@ async function processMessage(data) {
|
|
|
3553
5180
|
break;
|
|
3554
5181
|
}
|
|
3555
5182
|
|
|
5183
|
+
case 'warmup': {
|
|
5184
|
+
const result = await warmRuntime(payload);
|
|
5185
|
+
self.postMessage({ id, type: 'warmup-result', payload: result });
|
|
5186
|
+
break;
|
|
5187
|
+
}
|
|
5188
|
+
|
|
3556
5189
|
case 'execute-with-tracing': {
|
|
3557
5190
|
const result = await executeWithTracing(payload);
|
|
3558
5191
|
self.postMessage({ id, type: 'execute-result', payload: result });
|
|
@@ -3616,7 +5249,5 @@ self.onmessage = function(event) {
|
|
|
3616
5249
|
});
|
|
3617
5250
|
};
|
|
3618
5251
|
|
|
3619
|
-
|
|
3620
|
-
console.log('[JavaScriptWorker] ready');
|
|
3621
|
-
}
|
|
5252
|
+
emitRuntimeDiagnostic('info', 'worker-ready', 'JavaScript worker is ready.');
|
|
3622
5253
|
self.postMessage({ type: 'worker-ready' });
|