@tracecode/harness 0.6.6 → 0.7.0-beta7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +48 -0
- package/README.md +134 -15
- package/THIRD_PARTY_NOTICES.md +170 -0
- package/dist/browser.cjs +2361 -1033
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +33 -3
- package/dist/browser.d.ts +33 -3
- package/dist/browser.js +2357 -1033
- package/dist/browser.js.map +1 -1
- package/dist/cli.cjs +160 -23
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +161 -24
- package/dist/cli.js.map +1 -1
- package/dist/core.cjs +748 -867
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +21 -85
- package/dist/core.d.ts +21 -85
- package/dist/core.js +734 -855
- package/dist/core.js.map +1 -1
- package/dist/cpp-worker-client-Bn7kC0_L.d.ts +84 -0
- package/dist/cpp-worker-client-BzdJLuZa.d.cts +84 -0
- package/dist/cpp.cjs +1063 -0
- package/dist/cpp.cjs.map +1 -0
- package/dist/cpp.d.cts +7 -0
- package/dist/cpp.d.ts +7 -0
- package/dist/cpp.js +1035 -0
- package/dist/cpp.js.map +1 -0
- package/dist/csharp-worker-client-DMHIa2YG.d.cts +69 -0
- package/dist/csharp-worker-client-JwqS6LiX.d.ts +69 -0
- package/dist/csharp.cjs +1012 -0
- package/dist/csharp.cjs.map +1 -0
- package/dist/csharp.d.cts +7 -0
- package/dist/csharp.d.ts +7 -0
- package/dist/csharp.js +984 -0
- package/dist/csharp.js.map +1 -0
- package/dist/index.cjs +3142 -1160
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -5
- package/dist/index.d.ts +13 -5
- package/dist/index.js +3117 -1148
- package/dist/index.js.map +1 -1
- package/dist/internal/browser.cjs +1639 -30
- package/dist/internal/browser.cjs.map +1 -1
- package/dist/internal/browser.d.cts +6 -199
- package/dist/internal/browser.d.ts +6 -199
- package/dist/internal/browser.js +1636 -30
- package/dist/internal/browser.js.map +1 -1
- package/dist/java-worker-client-BOwKW-11.d.cts +72 -0
- package/dist/java-worker-client-C97DDnCp.d.ts +72 -0
- package/dist/java.cjs +1225 -0
- package/dist/java.cjs.map +1 -0
- package/dist/java.d.cts +7 -0
- package/dist/java.d.ts +7 -0
- package/dist/java.js +1197 -0
- package/dist/java.js.map +1 -0
- package/dist/javascript-worker-client-CYBGEEvc.d.cts +51 -0
- package/dist/javascript-worker-client-DIX1Mp21.d.ts +51 -0
- package/dist/javascript.cjs +1063 -19
- package/dist/javascript.cjs.map +1 -1
- package/dist/javascript.d.cts +7 -4
- package/dist/javascript.d.ts +7 -4
- package/dist/javascript.js +1061 -19
- package/dist/javascript.js.map +1 -1
- package/dist/pyodide-worker-client-C-2rfHj9.d.ts +111 -0
- package/dist/pyodide-worker-client-Cn0a8Uv3.d.cts +111 -0
- package/dist/python.cjs +1282 -74
- package/dist/python.cjs.map +1 -1
- package/dist/python.d.cts +20 -14
- package/dist/python.d.ts +20 -14
- package/dist/python.js +1279 -74
- package/dist/python.js.map +1 -1
- package/dist/runtime-language-info-BFUSti3-.d.ts +43 -0
- package/dist/runtime-language-info-Bxza1cI2.d.cts +43 -0
- package/dist/runtime-types-2qM0MukN.d.cts +244 -0
- package/dist/runtime-types-2qM0MukN.d.ts +244 -0
- package/package.json +73 -8
- package/workers/cpp/cpp-compiler-frame.html +82 -0
- package/workers/cpp/cpp-compiler-worker.js +131 -0
- package/workers/cpp/cpp-worker.js +5790 -0
- package/workers/cpp/tracecode_runtime.hpp +6147 -0
- package/workers/csharp/csharp-worker.js +301 -0
- package/workers/java/.build/classes/harness/browser/JavaRewriteLibrary.class +0 -0
- package/workers/java/java-source-augmentations.js +880 -0
- package/workers/java/java-worker.js +2149 -178
- package/workers/java/src/harness/browser/JavaRewriteLibrary.java +1645 -32
- package/workers/java/src/javafx/util/Pair.java +42 -0
- package/workers/java/src/tracecode/browser/BrowserCompileAndTraceLibrary.java +714 -0
- package/workers/java/src/tracecode/browser/BrowserCompileAndTraceMain.java +76 -0
- package/workers/java/src/tracecode/browser/RuntimeProbeMain.java +14 -0
- package/workers/java/src/tracecode/user/TraceHooks.java +1406 -0
- package/workers/javascript/javascript-libraries-entry.js +71 -0
- package/workers/javascript/javascript-worker.js +2054 -424
- package/workers/python/generated-python-harness-snippets.js +4 -4
- package/workers/python/pyodide-worker.js +222 -61
- package/workers/python/runtime-core.js +1387 -301
- package/workers/vendor/csharp/.stamp +0 -0
- package/workers/vendor/csharp/TraceCode.CSharpHost.runtimeconfig.json +32 -0
- package/workers/vendor/csharp/_framework/Microsoft.CSharp.wasm +0 -0
- package/workers/vendor/csharp/_framework/Microsoft.CodeAnalysis.CSharp.wasm +0 -0
- package/workers/vendor/csharp/_framework/Microsoft.CodeAnalysis.wasm +0 -0
- package/workers/vendor/csharp/_framework/Microsoft.VisualBasic.Core.wasm +0 -0
- package/workers/vendor/csharp/_framework/Microsoft.VisualBasic.wasm +0 -0
- package/workers/vendor/csharp/_framework/Microsoft.Win32.Primitives.wasm +0 -0
- package/workers/vendor/csharp/_framework/Microsoft.Win32.Registry.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.AppContext.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Buffers.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Collections.Concurrent.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Collections.Immutable.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Collections.NonGeneric.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Collections.Specialized.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Collections.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.ComponentModel.Annotations.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.ComponentModel.DataAnnotations.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.ComponentModel.EventBasedAsync.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.ComponentModel.Primitives.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.ComponentModel.TypeConverter.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.ComponentModel.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Configuration.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Console.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Core.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Data.Common.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Data.DataSetExtensions.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Data.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Diagnostics.Contracts.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Diagnostics.Debug.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Diagnostics.DiagnosticSource.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Diagnostics.FileVersionInfo.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Diagnostics.Process.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Diagnostics.StackTrace.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Diagnostics.TextWriterTraceListener.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Diagnostics.Tools.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Diagnostics.TraceSource.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Diagnostics.Tracing.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Drawing.Primitives.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Drawing.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Dynamic.Runtime.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Formats.Asn1.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Formats.Tar.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Globalization.Calendars.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Globalization.Extensions.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Globalization.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.IO.Compression.Brotli.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.IO.Compression.FileSystem.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.IO.Compression.ZipFile.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.IO.Compression.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.IO.FileSystem.AccessControl.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.IO.FileSystem.DriveInfo.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.IO.FileSystem.Primitives.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.IO.FileSystem.Watcher.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.IO.FileSystem.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.IO.IsolatedStorage.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.IO.MemoryMappedFiles.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.IO.Pipelines.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.IO.Pipes.AccessControl.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.IO.Pipes.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.IO.UnmanagedMemoryStream.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.IO.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Linq.AsyncEnumerable.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Linq.Expressions.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Linq.Parallel.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Linq.Queryable.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Linq.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Memory.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.Http.Json.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.Http.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.HttpListener.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.Mail.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.NameResolution.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.NetworkInformation.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.Ping.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.Primitives.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.Quic.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.Requests.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.Security.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.ServerSentEvents.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.ServicePoint.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.Sockets.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.WebClient.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.WebHeaderCollection.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.WebProxy.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.WebSockets.Client.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.WebSockets.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Net.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Numerics.Vectors.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Numerics.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.ObjectModel.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Private.CoreLib.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Private.DataContractSerialization.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Private.Uri.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Private.Xml.Linq.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Private.Xml.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Reflection.DispatchProxy.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Reflection.Emit.ILGeneration.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Reflection.Emit.Lightweight.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Reflection.Emit.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Reflection.Extensions.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Reflection.Metadata.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Reflection.Primitives.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Reflection.TypeExtensions.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Reflection.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Resources.Reader.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Resources.ResourceManager.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Resources.Writer.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Runtime.CompilerServices.Unsafe.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Runtime.CompilerServices.VisualC.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Runtime.Extensions.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Runtime.Handles.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Runtime.InteropServices.JavaScript.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Runtime.InteropServices.RuntimeInformation.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Runtime.InteropServices.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Runtime.Intrinsics.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Runtime.Loader.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Runtime.Numerics.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Runtime.Serialization.Formatters.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Runtime.Serialization.Json.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Runtime.Serialization.Primitives.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Runtime.Serialization.Xml.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Runtime.Serialization.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Runtime.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Security.AccessControl.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Security.Claims.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Security.Cryptography.Algorithms.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Security.Cryptography.Cng.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Security.Cryptography.Csp.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Security.Cryptography.Encoding.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Security.Cryptography.OpenSsl.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Security.Cryptography.Primitives.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Security.Cryptography.X509Certificates.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Security.Cryptography.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Security.Principal.Windows.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Security.Principal.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Security.SecureString.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Security.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.ServiceModel.Web.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.ServiceProcess.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Text.Encoding.CodePages.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Text.Encoding.Extensions.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Text.Encoding.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Text.Encodings.Web.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Text.Json.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Text.RegularExpressions.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Threading.AccessControl.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Threading.Channels.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Threading.Overlapped.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Threading.Tasks.Dataflow.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Threading.Tasks.Extensions.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Threading.Tasks.Parallel.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Threading.Tasks.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Threading.Thread.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Threading.ThreadPool.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Threading.Timer.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Threading.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Transactions.Local.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Transactions.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.ValueTuple.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Web.HttpUtility.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Web.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Windows.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Xml.Linq.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Xml.ReaderWriter.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Xml.Serialization.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Xml.XDocument.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Xml.XPath.XDocument.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Xml.XPath.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Xml.XmlDocument.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Xml.XmlSerializer.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.Xml.wasm +0 -0
- package/workers/vendor/csharp/_framework/System.wasm +0 -0
- package/workers/vendor/csharp/_framework/TraceCode.CSharpHost.wasm +0 -0
- package/workers/vendor/csharp/_framework/WindowsBase.wasm +0 -0
- package/workers/vendor/csharp/_framework/cs/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/cs/Microsoft.CodeAnalysis.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/de/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/de/Microsoft.CodeAnalysis.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/dotnet.boot.js +1958 -0
- package/workers/vendor/csharp/_framework/dotnet.js +4 -0
- package/workers/vendor/csharp/_framework/dotnet.js.map +1 -0
- package/workers/vendor/csharp/_framework/dotnet.native.js +6687 -0
- package/workers/vendor/csharp/_framework/dotnet.native.wasm +0 -0
- package/workers/vendor/csharp/_framework/dotnet.runtime.js +4 -0
- package/workers/vendor/csharp/_framework/dotnet.runtime.js.map +1 -0
- package/workers/vendor/csharp/_framework/es/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/es/Microsoft.CodeAnalysis.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/fr/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/fr/Microsoft.CodeAnalysis.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/it/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/it/Microsoft.CodeAnalysis.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/ja/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/ja/Microsoft.CodeAnalysis.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/ko/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/ko/Microsoft.CodeAnalysis.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/mscorlib.wasm +0 -0
- package/workers/vendor/csharp/_framework/netstandard.wasm +0 -0
- package/workers/vendor/csharp/_framework/pl/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/pl/Microsoft.CodeAnalysis.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/pt-BR/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/pt-BR/Microsoft.CodeAnalysis.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/ru/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/ru/Microsoft.CodeAnalysis.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/0_Microsoft.CodeAnalysis.CSharp.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/100_System.Reflection.Emit.ILGeneration.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/101_System.Reflection.Emit.Lightweight.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/102_System.Reflection.Extensions.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/103_System.Reflection.Metadata.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/104_System.Reflection.Primitives.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/105_System.Reflection.TypeExtensions.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/106_System.Resources.Reader.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/107_System.Resources.ResourceManager.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/108_System.Resources.Writer.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/109_System.Runtime.CompilerServices.Unsafe.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/10_System.Buffers.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/110_System.Runtime.CompilerServices.VisualC.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/111_System.Runtime.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/112_System.Runtime.Extensions.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/113_System.Runtime.Handles.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/114_System.Runtime.InteropServices.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/115_System.Runtime.InteropServices.JavaScript.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/116_System.Runtime.InteropServices.RuntimeInformation.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/117_System.Runtime.Intrinsics.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/118_System.Runtime.Loader.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/119_System.Runtime.Numerics.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/11_System.Collections.Concurrent.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/120_System.Runtime.Serialization.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/121_System.Runtime.Serialization.Formatters.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/122_System.Runtime.Serialization.Json.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/123_System.Runtime.Serialization.Primitives.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/124_System.Runtime.Serialization.Xml.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/125_System.Security.AccessControl.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/126_System.Security.Claims.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/127_System.Security.Cryptography.Algorithms.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/128_System.Security.Cryptography.Cng.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/129_System.Security.Cryptography.Csp.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/12_System.Collections.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/130_System.Security.Cryptography.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/131_System.Security.Cryptography.Encoding.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/132_System.Security.Cryptography.OpenSsl.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/133_System.Security.Cryptography.Primitives.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/134_System.Security.Cryptography.X509Certificates.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/135_System.Security.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/136_System.Security.Principal.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/137_System.Security.Principal.Windows.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/138_System.Security.SecureString.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/139_System.ServiceModel.Web.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/13_System.Collections.Immutable.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/140_System.ServiceProcess.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/141_System.Text.Encoding.CodePages.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/142_System.Text.Encoding.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/143_System.Text.Encoding.Extensions.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/144_System.Text.Encodings.Web.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/145_System.Text.Json.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/146_System.Text.RegularExpressions.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/147_System.Threading.AccessControl.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/148_System.Threading.Channels.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/149_System.Threading.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/14_System.Collections.NonGeneric.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/150_System.Threading.Overlapped.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/151_System.Threading.Tasks.Dataflow.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/152_System.Threading.Tasks.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/153_System.Threading.Tasks.Extensions.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/154_System.Threading.Tasks.Parallel.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/155_System.Threading.Thread.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/156_System.Threading.ThreadPool.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/157_System.Threading.Timer.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/158_System.Transactions.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/159_System.Transactions.Local.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/15_System.Collections.Specialized.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/160_System.ValueTuple.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/161_System.Web.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/162_System.Web.HttpUtility.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/163_System.Windows.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/164_System.Xml.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/165_System.Xml.Linq.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/166_System.Xml.ReaderWriter.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/167_System.Xml.Serialization.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/168_System.Xml.XDocument.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/169_System.Xml.XmlDocument.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/16_System.ComponentModel.Annotations.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/170_System.Xml.XmlSerializer.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/171_System.Xml.XPath.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/172_System.Xml.XPath.XDocument.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/173_TraceCode.CSharpHost.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/174_WindowsBase.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/17_System.ComponentModel.DataAnnotations.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/18_System.ComponentModel.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/19_System.ComponentModel.EventBasedAsync.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/1_Microsoft.CodeAnalysis.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/20_System.ComponentModel.Primitives.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/21_System.ComponentModel.TypeConverter.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/22_System.Configuration.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/23_System.Console.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/24_System.Core.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/25_System.Data.Common.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/26_System.Data.DataSetExtensions.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/27_System.Data.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/28_System.Diagnostics.Contracts.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/29_System.Diagnostics.Debug.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/2_Microsoft.CSharp.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/30_System.Diagnostics.DiagnosticSource.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/31_System.Diagnostics.FileVersionInfo.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/32_System.Diagnostics.Process.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/33_System.Diagnostics.StackTrace.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/34_System.Diagnostics.TextWriterTraceListener.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/35_System.Diagnostics.Tools.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/36_System.Diagnostics.TraceSource.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/37_System.Diagnostics.Tracing.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/38_System.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/39_System.Drawing.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/3_Microsoft.VisualBasic.Core.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/40_System.Drawing.Primitives.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/41_System.Dynamic.Runtime.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/42_System.Formats.Asn1.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/43_System.Formats.Tar.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/44_System.Globalization.Calendars.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/45_System.Globalization.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/46_System.Globalization.Extensions.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/47_System.IO.Compression.Brotli.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/48_System.IO.Compression.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/49_System.IO.Compression.FileSystem.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/4_Microsoft.VisualBasic.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/50_System.IO.Compression.ZipFile.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/51_System.IO.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/52_System.IO.FileSystem.AccessControl.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/53_System.IO.FileSystem.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/54_System.IO.FileSystem.DriveInfo.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/55_System.IO.FileSystem.Primitives.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/56_System.IO.FileSystem.Watcher.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/57_System.IO.IsolatedStorage.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/58_System.IO.MemoryMappedFiles.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/59_System.IO.Pipelines.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/5_Microsoft.Win32.Primitives.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/60_System.IO.Pipes.AccessControl.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/61_System.IO.Pipes.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/62_System.IO.UnmanagedMemoryStream.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/63_System.Linq.AsyncEnumerable.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/64_System.Linq.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/65_System.Linq.Expressions.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/66_System.Linq.Parallel.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/67_System.Linq.Queryable.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/68_System.Memory.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/69_System.Net.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/6_Microsoft.Win32.Registry.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/70_System.Net.Http.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/71_System.Net.Http.Json.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/72_System.Net.HttpListener.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/73_System.Net.Mail.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/74_System.Net.NameResolution.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/75_System.Net.NetworkInformation.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/76_System.Net.Ping.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/77_System.Net.Primitives.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/78_System.Net.Quic.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/79_System.Net.Requests.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/7_mscorlib.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/80_System.Net.Security.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/81_System.Net.ServerSentEvents.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/82_System.Net.ServicePoint.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/83_System.Net.Sockets.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/84_System.Net.WebClient.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/85_System.Net.WebHeaderCollection.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/86_System.Net.WebProxy.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/87_System.Net.WebSockets.Client.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/88_System.Net.WebSockets.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/89_System.Numerics.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/8_netstandard.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/90_System.Numerics.Vectors.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/91_System.ObjectModel.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/92_System.Private.CoreLib.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/93_System.Private.DataContractSerialization.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/94_System.Private.Uri.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/95_System.Private.Xml.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/96_System.Private.Xml.Linq.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/97_System.Reflection.DispatchProxy.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/98_System.Reflection.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/99_System.Reflection.Emit.dll +0 -0
- package/workers/vendor/csharp/_framework/supportFiles/9_System.AppContext.dll +0 -0
- package/workers/vendor/csharp/_framework/tr/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/tr/Microsoft.CodeAnalysis.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/zh-Hans/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/zh-Hans/Microsoft.CodeAnalysis.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/zh-Hant/Microsoft.CodeAnalysis.CSharp.resources.wasm +0 -0
- package/workers/vendor/csharp/_framework/zh-Hant/Microsoft.CodeAnalysis.resources.wasm +0 -0
- package/workers/vendor/csharp/main.mjs +5 -0
- package/workers/vendor/csharp/package.json +1 -0
- package/workers/vendor/java-browser-helper.jar +0 -0
- package/workers/vendor/java-rewriter.jar +0 -0
- package/workers/vendor/javascript-libraries.js +10106 -0
- package/dist/runtime-types-89nchXlY.d.cts +0 -89
- package/dist/runtime-types-CCQ-ZLc9.d.ts +0 -89
- package/dist/types-zyvpJKCi.d.cts +0 -100
- package/dist/types-zyvpJKCi.d.ts +0 -100
- package/workers/java/java-source-augmentations.cjs +0 -242
- package/workers/java/src/spike/user/TraceHooks.java +0 -619
- package/workers/vendor/java-browser-spike-helper.jar +0 -0
- package/workers/vendor/java-practice-rewriter.jar +0 -0
- package/workers/vendor/java-rewrite-bridge.jar +0 -0
|
@@ -1,23 +1,51 @@
|
|
|
1
1
|
const CHEERPJ_LOADER_URL = 'https://cjrtnc.leaningtech.com/4.2/loader.js';
|
|
2
|
-
const HELPER_JAR_PATH = '/app/workers/vendor/java-browser-
|
|
2
|
+
const HELPER_JAR_PATH = '/app/workers/vendor/java-browser-helper.jar';
|
|
3
3
|
const JDK17_COMPILER_JAR_PATH = '/app/workers/vendor/jdk.compiler-17.jar';
|
|
4
|
-
const REWRITER_JAR_PATH = '/app/workers/vendor/java-
|
|
5
|
-
const REWRITER_BRIDGE_JAR_PATH = '/app/workers/vendor/java-rewrite-bridge.jar';
|
|
4
|
+
const REWRITER_JAR_PATH = '/app/workers/vendor/java-rewriter.jar';
|
|
6
5
|
const JAVAPARSER_JAR_PATH = '/app/workers/vendor/javaparser-core-3.25.10.jar';
|
|
7
6
|
const FULL_CLASSPATH = [
|
|
8
7
|
HELPER_JAR_PATH,
|
|
9
8
|
JDK17_COMPILER_JAR_PATH,
|
|
10
9
|
REWRITER_JAR_PATH,
|
|
11
|
-
REWRITER_BRIDGE_JAR_PATH,
|
|
12
10
|
JAVAPARSER_JAR_PATH,
|
|
13
11
|
].join(':');
|
|
14
12
|
const DEFAULT_COMPILER_DEBUG_PROFILE = 'full';
|
|
13
|
+
const DEFAULT_EXECUTE_COMPILER_DEBUG_PROFILE = 'none';
|
|
15
14
|
const DEFAULT_MAX_STORED_EVENTS = 50_000;
|
|
16
|
-
const
|
|
15
|
+
const DEFAULT_IDLE_TIMEOUT_MS = 300_000;
|
|
17
16
|
const SCRIPT_METHOD_NAME = '__tracecodeScript';
|
|
17
|
+
const DYNAMIC_INPUT_PREFIX = '/str/tracecode-java-input';
|
|
18
|
+
const JAVA_DEFAULT_IMPORTS = [
|
|
19
|
+
'import java.util.*;',
|
|
20
|
+
'import java.io.*;',
|
|
21
|
+
'import java.math.*;',
|
|
22
|
+
'import java.util.stream.*;',
|
|
23
|
+
'import javafx.util.Pair;',
|
|
24
|
+
];
|
|
25
|
+
const WORKER_DEBUG = (() => {
|
|
26
|
+
try {
|
|
27
|
+
return typeof self !== 'undefined' && typeof self.location?.search === 'string' && self.location.search.includes('dev=');
|
|
28
|
+
} catch {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
})();
|
|
32
|
+
|
|
33
|
+
function emitRuntimeDiagnostic(level, phase, message, detail) {
|
|
34
|
+
if (!WORKER_DEBUG && level !== 'error') return;
|
|
35
|
+
const method = level === 'error' ? 'error' : level === 'warn' ? 'warn' : level === 'debug' ? 'debug' : 'info';
|
|
36
|
+
console[method]('[TraceRuntime]', {
|
|
37
|
+
schema: 'tracecode.runtime-diagnostic.v1',
|
|
38
|
+
source: 'harness',
|
|
39
|
+
component: 'JavaWorker',
|
|
40
|
+
runtime: 'java',
|
|
41
|
+
phase,
|
|
42
|
+
message,
|
|
43
|
+
...(detail === undefined ? {} : { detail }),
|
|
44
|
+
});
|
|
45
|
+
}
|
|
18
46
|
|
|
19
47
|
if (typeof self.importScripts === 'function') {
|
|
20
|
-
self.importScripts('java-source-augmentations.
|
|
48
|
+
self.importScripts('java-source-augmentations.js');
|
|
21
49
|
}
|
|
22
50
|
|
|
23
51
|
let workerReadyPromise = null;
|
|
@@ -27,13 +55,26 @@ let helperLibraryPromise = null;
|
|
|
27
55
|
let compileLibraryClassPromise = null;
|
|
28
56
|
let rewriteLibraryClassPromise = null;
|
|
29
57
|
let idleGeneration = 0;
|
|
30
|
-
let hostWarmupPromise = null;
|
|
31
58
|
let initLoadTimeMs = null;
|
|
59
|
+
let idleTimeoutMs = DEFAULT_IDLE_TIMEOUT_MS;
|
|
60
|
+
let runWarmupPromise = null;
|
|
32
61
|
|
|
33
62
|
function postMessageResponse(message) {
|
|
34
63
|
self.postMessage(message);
|
|
35
64
|
}
|
|
36
65
|
|
|
66
|
+
function javaDefaultImportsBlock() {
|
|
67
|
+
return JAVA_DEFAULT_IMPORTS.join('\n');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function addJavaDefaultImportsToPackagedSource(source) {
|
|
71
|
+
const importBlock = javaDefaultImportsBlock();
|
|
72
|
+
return String(source).replace(
|
|
73
|
+
/^(package\s+[A-Za-z_][A-Za-z0-9_.]*\s*;\s*\n+)/,
|
|
74
|
+
`$1${importBlock}\n`
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
37
78
|
function formatWorkerErrorMessage(error) {
|
|
38
79
|
if (error instanceof Error && typeof error.message === 'string' && error.message.length > 0) {
|
|
39
80
|
return error.message;
|
|
@@ -119,7 +160,14 @@ function resetIdleTimer() {
|
|
|
119
160
|
if (generation !== idleGeneration) return;
|
|
120
161
|
postMessageResponse({ type: 'idle-timeout' });
|
|
121
162
|
self.close();
|
|
122
|
-
},
|
|
163
|
+
}, idleTimeoutMs);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function applyWorkerOptions(payload) {
|
|
167
|
+
const nextIdleTimeoutMs = Number(payload?.idleTimeoutMs);
|
|
168
|
+
if (Number.isFinite(nextIdleTimeoutMs) && nextIdleTimeoutMs > 0) {
|
|
169
|
+
idleTimeoutMs = Math.max(1_000, Math.floor(nextIdleTimeoutMs));
|
|
170
|
+
}
|
|
123
171
|
}
|
|
124
172
|
|
|
125
173
|
function assertSupportedExecutionStyle(executionStyle) {
|
|
@@ -150,6 +198,8 @@ function isRecord(value) {
|
|
|
150
198
|
|
|
151
199
|
function isListNodeShape(value) {
|
|
152
200
|
if (!isRecord(value)) return false;
|
|
201
|
+
const typeName = typeof value.__type__ === 'string' ? value.__type__ : typeof value.__class__ === 'string' ? value.__class__ : null;
|
|
202
|
+
if (typeName && typeName !== 'ListNode' && typeName !== 'object') return false;
|
|
153
203
|
if (!('val' in value || 'value' in value)) return false;
|
|
154
204
|
if ('next' in value) return true;
|
|
155
205
|
return typeof value.__id__ === 'string' && value.__id__.startsWith('list-');
|
|
@@ -157,19 +207,43 @@ function isListNodeShape(value) {
|
|
|
157
207
|
|
|
158
208
|
function isTreeNodeShape(value) {
|
|
159
209
|
if (!isRecord(value)) return false;
|
|
210
|
+
const typeName = typeof value.__type__ === 'string' ? value.__type__ : typeof value.__class__ === 'string' ? value.__class__ : null;
|
|
211
|
+
if (typeName && typeName !== 'TreeNode' && typeName !== 'object') return false;
|
|
160
212
|
if (!('val' in value || 'value' in value)) return false;
|
|
161
213
|
if ('left' in value || 'right' in value) return true;
|
|
162
214
|
return typeof value.__id__ === 'string' && value.__id__.startsWith('tree-');
|
|
163
215
|
}
|
|
164
216
|
|
|
165
|
-
function detectFeatures(source, input) {
|
|
217
|
+
function detectFeatures(source, input, options = {}) {
|
|
166
218
|
const values = Object.values(input ?? {});
|
|
167
219
|
return {
|
|
168
220
|
hasList: /\bListNode\b/.test(source) || values.some((value) => isListNodeShape(value)),
|
|
169
221
|
hasTree: /\bTreeNode\b/.test(source) || values.some((value) => isTreeNodeShape(value)),
|
|
222
|
+
hasCustomObject: values.some((value) => containsCustomObjectLiteral(value)),
|
|
223
|
+
hasMap: values.some((value) => containsPlainObjectLiteral(value)),
|
|
224
|
+
hasDynamicInputs: options.hasDynamicInputs === true,
|
|
170
225
|
};
|
|
171
226
|
}
|
|
172
227
|
|
|
228
|
+
function containsCustomObjectLiteral(value) {
|
|
229
|
+
if (Array.isArray(value)) return value.some((entry) => containsCustomObjectLiteral(entry));
|
|
230
|
+
if (!isRecord(value)) return false;
|
|
231
|
+
const typeName = typeof value.__type__ === 'string' ? value.__type__ : typeof value.__class__ === 'string' ? value.__class__ : null;
|
|
232
|
+
if (typeName && typeName !== 'TreeNode' && typeName !== 'ListNode' && typeName !== 'object') return true;
|
|
233
|
+
return Object.values(value).some((entry) => containsCustomObjectLiteral(entry));
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function containsPlainObjectLiteral(value) {
|
|
237
|
+
if (Array.isArray(value)) return value.some((entry) => containsPlainObjectLiteral(entry));
|
|
238
|
+
if (!isRecord(value)) return false;
|
|
239
|
+
const typeName = typeof value.__type__ === 'string' ? value.__type__ : typeof value.__class__ === 'string' ? value.__class__ : null;
|
|
240
|
+
if (!typeName) return true;
|
|
241
|
+
if (typeName !== 'TreeNode' && typeName !== 'ListNode' && typeName !== 'object') return false;
|
|
242
|
+
return Object.entries(value)
|
|
243
|
+
.filter(([key]) => key !== '__type__' && key !== '__class__' && key !== '__id__')
|
|
244
|
+
.some(([, entry]) => containsPlainObjectLiteral(entry));
|
|
245
|
+
}
|
|
246
|
+
|
|
173
247
|
function toJavaScalarLiteral(value) {
|
|
174
248
|
if (value === null) return 'null';
|
|
175
249
|
if (typeof value === 'number' || typeof value === 'boolean') return String(value);
|
|
@@ -177,6 +251,23 @@ function toJavaScalarLiteral(value) {
|
|
|
177
251
|
throw new Error(`Unsupported scalar literal: ${JSON.stringify(value)}`);
|
|
178
252
|
}
|
|
179
253
|
|
|
254
|
+
function toJavaScalarLiteralForType(value, expectedType) {
|
|
255
|
+
const normalized = expectedType ? stripGenericType(expectedType) : null;
|
|
256
|
+
if ((normalized === 'long' || normalized === 'Long') && typeof value === 'number' && Number.isInteger(value)) {
|
|
257
|
+
return `${String(value)}L`;
|
|
258
|
+
}
|
|
259
|
+
if ((normalized === 'double' || normalized === 'Double') && typeof value === 'number') {
|
|
260
|
+
return Number.isInteger(value) ? `${String(value)}.0` : String(value);
|
|
261
|
+
}
|
|
262
|
+
if ((normalized === 'float' || normalized === 'Float') && typeof value === 'number') {
|
|
263
|
+
return `${Number.isInteger(value) ? `${String(value)}.0` : String(value)}f`;
|
|
264
|
+
}
|
|
265
|
+
if (normalized === 'char' && typeof value === 'string' && value.length === 1) {
|
|
266
|
+
return `'${value.replace(/\\/g, '\\\\').replace(/'/g, "\\'")}'`;
|
|
267
|
+
}
|
|
268
|
+
return toJavaScalarLiteral(value);
|
|
269
|
+
}
|
|
270
|
+
|
|
180
271
|
function toJavaArrayLiteral(value) {
|
|
181
272
|
if (value.length === 0) return 'new int[] {}';
|
|
182
273
|
if (value.every((entry) => typeof entry === 'number' && Number.isInteger(entry))) {
|
|
@@ -226,6 +317,78 @@ function extractTypeArguments(typeSource) {
|
|
|
226
317
|
return parts.map((part) => part.trim()).filter(Boolean);
|
|
227
318
|
}
|
|
228
319
|
|
|
320
|
+
function splitTopLevelCommaList(source) {
|
|
321
|
+
const parts = [];
|
|
322
|
+
let depth = 0;
|
|
323
|
+
let current = '';
|
|
324
|
+
for (const ch of source) {
|
|
325
|
+
if (ch === '<' || ch === '(' || ch === '[') depth += 1;
|
|
326
|
+
if (ch === '>' || ch === ')' || ch === ']') depth -= 1;
|
|
327
|
+
if (ch === ',' && depth === 0) {
|
|
328
|
+
parts.push(current);
|
|
329
|
+
current = '';
|
|
330
|
+
continue;
|
|
331
|
+
}
|
|
332
|
+
current += ch;
|
|
333
|
+
}
|
|
334
|
+
if (current) parts.push(current);
|
|
335
|
+
return parts.map((part) => part.trim()).filter(Boolean);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
function normalizedJavaInputType(typeSource) {
|
|
339
|
+
return String(typeSource || 'Object')
|
|
340
|
+
.replace(/\bfinal\b/g, '')
|
|
341
|
+
.replace(/\s+/g, '')
|
|
342
|
+
.replace(/\.\.\.$/, '[]');
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
function isDynamicJavaScalarType(typeSource, value) {
|
|
346
|
+
const normalized = normalizedJavaInputType(typeSource);
|
|
347
|
+
if (
|
|
348
|
+
['byte', 'Byte', 'short', 'Short', 'int', 'Integer', 'long', 'Long', 'float', 'Float', 'double', 'Double'].includes(normalized)
|
|
349
|
+
) {
|
|
350
|
+
return typeof value === 'number';
|
|
351
|
+
}
|
|
352
|
+
if (normalized === 'boolean' || normalized === 'Boolean') {
|
|
353
|
+
return typeof value === 'boolean';
|
|
354
|
+
}
|
|
355
|
+
if (normalized === 'String') {
|
|
356
|
+
return typeof value === 'string';
|
|
357
|
+
}
|
|
358
|
+
if (normalized === 'char' || normalized === 'Character') {
|
|
359
|
+
return typeof value === 'string' && value.length === 1;
|
|
360
|
+
}
|
|
361
|
+
return false;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
function isDynamicJavaInputType(typeSource, value) {
|
|
365
|
+
const normalized = normalizedJavaInputType(typeSource);
|
|
366
|
+
if (normalized.endsWith('[]')) {
|
|
367
|
+
if (!Array.isArray(value)) return false;
|
|
368
|
+
const elementType = normalized.slice(0, -2);
|
|
369
|
+
return value.every((entry) => isDynamicJavaInputType(elementType, entry));
|
|
370
|
+
}
|
|
371
|
+
return isDynamicJavaScalarType(normalized, value);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
function dynamicJavaInputExpression(typeSource, inputPath) {
|
|
375
|
+
const normalized = normalizedJavaInputType(typeSource);
|
|
376
|
+
const quotedPath = JSON.stringify(inputPath);
|
|
377
|
+
if (normalized.endsWith('[]')) {
|
|
378
|
+
return `((${normalized}) readJsonInput(${quotedPath}, ${normalized}.class))`;
|
|
379
|
+
}
|
|
380
|
+
if (normalized === 'byte' || normalized === 'Byte') return `((Number) readJsonInput(${quotedPath}, Byte.class)).byteValue()`;
|
|
381
|
+
if (normalized === 'short' || normalized === 'Short') return `((Number) readJsonInput(${quotedPath}, Short.class)).shortValue()`;
|
|
382
|
+
if (normalized === 'int' || normalized === 'Integer') return `((Number) readJsonInput(${quotedPath}, Integer.class)).intValue()`;
|
|
383
|
+
if (normalized === 'long' || normalized === 'Long') return `((Number) readJsonInput(${quotedPath}, Long.class)).longValue()`;
|
|
384
|
+
if (normalized === 'float' || normalized === 'Float') return `((Number) readJsonInput(${quotedPath}, Float.class)).floatValue()`;
|
|
385
|
+
if (normalized === 'double' || normalized === 'Double') return `((Number) readJsonInput(${quotedPath}, Double.class)).doubleValue()`;
|
|
386
|
+
if (normalized === 'boolean' || normalized === 'Boolean') return `((Boolean) readJsonInput(${quotedPath}, Boolean.class)).booleanValue()`;
|
|
387
|
+
if (normalized === 'char' || normalized === 'Character') return `((Character) readJsonInput(${quotedPath}, Character.class)).charValue()`;
|
|
388
|
+
if (normalized === 'String') return `((String) readJsonInput(${quotedPath}, String.class))`;
|
|
389
|
+
return null;
|
|
390
|
+
}
|
|
391
|
+
|
|
229
392
|
function toJavaTypedArrayLiteral(value, expectedType) {
|
|
230
393
|
const normalized = stripGenericType(expectedType);
|
|
231
394
|
if (!normalized.endsWith('[]')) {
|
|
@@ -268,7 +431,81 @@ function toJavaTypedArrayLiteral(value, expectedType) {
|
|
|
268
431
|
|
|
269
432
|
function toJavaListLiteral(value, expectedType) {
|
|
270
433
|
const [elementType = 'Object'] = extractTypeArguments(expectedType);
|
|
271
|
-
return `java.util.
|
|
434
|
+
return `new java.util.ArrayList<${elementType}>(java.util.Arrays.asList(${value.map((entry) => buildJavaExpression(entry, elementType)).join(', ')}))`;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
function toJavaMapLiteral(value, expectedType) {
|
|
438
|
+
const [keyType = 'String', valueType = 'Object'] = extractTypeArguments(expectedType);
|
|
439
|
+
const entries = Object.entries(value)
|
|
440
|
+
.map(([key, child]) => `new Object[] { ${buildJavaExpression(key, keyType)}, ${buildJavaExpression(child, valueType)} }`);
|
|
441
|
+
return `typedMap(new Object[][] { ${entries.join(', ')} })`;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
function toJavaObjectExpression(value) {
|
|
445
|
+
if (Array.isArray(value)) {
|
|
446
|
+
return `new java.util.ArrayList<Object>(java.util.Arrays.asList(${value.map((entry) => toJavaObjectExpression(entry)).join(', ')}))`;
|
|
447
|
+
}
|
|
448
|
+
if (isRecord(value)) {
|
|
449
|
+
return toJavaDynamicObjectExpression(value);
|
|
450
|
+
}
|
|
451
|
+
return toJavaScalarLiteral(value);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
function customObjectTypeName(value) {
|
|
455
|
+
if (!isRecord(value)) return null;
|
|
456
|
+
const typeName = typeof value.__type__ === 'string' ? value.__type__ : typeof value.__class__ === 'string' ? value.__class__ : null;
|
|
457
|
+
if (!typeName || typeName === 'TreeNode' || typeName === 'ListNode' || typeName === 'object') return null;
|
|
458
|
+
return typeName;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
function toJavaObjectFieldsExpression(value) {
|
|
462
|
+
const entries = Object.entries(value)
|
|
463
|
+
.filter(([key]) => key !== '__type__' && key !== '__class__' && key !== '__id__')
|
|
464
|
+
.map(([key, child]) => `new Object[] { ${JSON.stringify(key)}, ${toJavaDynamicObjectExpression(child)} }`);
|
|
465
|
+
return `objectFields(new Object[][] { ${entries.join(', ')} })`;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
function toJavaDynamicObjectExpression(value) {
|
|
469
|
+
if (value === null) return 'null';
|
|
470
|
+
if (Array.isArray(value)) {
|
|
471
|
+
return `new java.util.ArrayList<Object>(java.util.Arrays.asList(${value.map((entry) => toJavaDynamicObjectExpression(entry)).join(', ')}))`;
|
|
472
|
+
}
|
|
473
|
+
if (isRecord(value)) {
|
|
474
|
+
const typeName = customObjectTypeName(value);
|
|
475
|
+
if (typeName) {
|
|
476
|
+
return `materializeObject(${JSON.stringify(typeName)}, ${toJavaObjectFieldsExpression(value)})`;
|
|
477
|
+
}
|
|
478
|
+
const entries = Object.entries(value)
|
|
479
|
+
.filter(([key]) => key !== '__type__' && key !== '__class__' && key !== '__id__')
|
|
480
|
+
.map(([key, child]) => `new Object[] { ${JSON.stringify(key)}, ${toJavaDynamicObjectExpression(child)} }`);
|
|
481
|
+
return `objectFields(new Object[][] { ${entries.join(', ')} })`;
|
|
482
|
+
}
|
|
483
|
+
return toJavaScalarLiteral(value);
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
function inputValueForParameter(input, key, index) {
|
|
487
|
+
if (Object.prototype.hasOwnProperty.call(input, key)) return input[key];
|
|
488
|
+
return Object.values(input)[index];
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
function inputArgumentsForParameters(rawArgs, parameters) {
|
|
492
|
+
if (parameters.length === 0) return [];
|
|
493
|
+
if (Array.isArray(rawArgs)) return rawArgs;
|
|
494
|
+
if (isRecord(rawArgs) && parameters.length > 0) {
|
|
495
|
+
return parameters.map((parameter, index) => inputValueForParameter(rawArgs, parameter.name, index));
|
|
496
|
+
}
|
|
497
|
+
return [];
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
function uniqueJavaIdentifier(baseName, usedNames) {
|
|
501
|
+
let candidate = baseName;
|
|
502
|
+
let suffix = 0;
|
|
503
|
+
while (usedNames.has(candidate)) {
|
|
504
|
+
suffix += 1;
|
|
505
|
+
candidate = `${baseName}${suffix}`;
|
|
506
|
+
}
|
|
507
|
+
usedNames.add(candidate);
|
|
508
|
+
return candidate;
|
|
272
509
|
}
|
|
273
510
|
|
|
274
511
|
function listLiteral(value) {
|
|
@@ -320,17 +557,18 @@ function listGraphExpression(head) {
|
|
|
320
557
|
|
|
321
558
|
const values = nodes.map((node) => {
|
|
322
559
|
const rawVal = node.val ?? node.value ?? 0;
|
|
323
|
-
if (typeof rawVal !== 'number' || !Number.isInteger(rawVal)) {
|
|
324
|
-
throw new Error(`Unsupported list node value: ${JSON.stringify(rawVal)}`);
|
|
325
|
-
}
|
|
326
560
|
return rawVal;
|
|
327
561
|
});
|
|
328
562
|
|
|
329
|
-
return `buildList(new
|
|
563
|
+
return `buildList(new Object[] { ${values.map((value) => toJavaScalarLiteral(value)).join(', ')} }, new int[] { ${nextIndices.join(', ')} })`;
|
|
330
564
|
}
|
|
331
565
|
|
|
332
566
|
function listExpression(value) {
|
|
333
|
-
return
|
|
567
|
+
return listGraphExpression(value);
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
function listArrayExpression(value) {
|
|
571
|
+
return `buildList(new Object[] { ${value.map((entry) => toJavaScalarLiteral(entry)).join(', ')} }, sequentialNextIndices(${value.length}))`;
|
|
334
572
|
}
|
|
335
573
|
|
|
336
574
|
function treeExpression(value) {
|
|
@@ -340,9 +578,29 @@ function treeExpression(value) {
|
|
|
340
578
|
return `tree(${toJavaScalarLiteral(rawVal)}, ${left}, ${right})`;
|
|
341
579
|
}
|
|
342
580
|
|
|
581
|
+
function treeLevelOrderExpression(value) {
|
|
582
|
+
if (!value.every((entry) => entry === null || (typeof entry === 'number' && Number.isInteger(entry)))) {
|
|
583
|
+
throw new Error(`Unsupported tree node value: ${JSON.stringify(value.find((entry) => entry !== null && (typeof entry !== 'number' || !Number.isInteger(entry))))}`);
|
|
584
|
+
}
|
|
585
|
+
const values = value.map((entry) => (entry === null ? 'null' : String(entry))).join(', ');
|
|
586
|
+
return `buildTree(new Integer[] { ${values} })`;
|
|
587
|
+
}
|
|
588
|
+
|
|
343
589
|
function buildJavaExpression(value, expectedType) {
|
|
344
590
|
const normalizedType = expectedType ? stripGenericType(expectedType) : null;
|
|
591
|
+
if (value === null || typeof value !== 'object') {
|
|
592
|
+
return toJavaScalarLiteralForType(value, normalizedType);
|
|
593
|
+
}
|
|
345
594
|
if (Array.isArray(value)) {
|
|
595
|
+
if (normalizedType === 'Object') {
|
|
596
|
+
return toJavaObjectExpression(value);
|
|
597
|
+
}
|
|
598
|
+
if (normalizedType === 'ListNode') {
|
|
599
|
+
return listArrayExpression(value);
|
|
600
|
+
}
|
|
601
|
+
if (normalizedType === 'TreeNode') {
|
|
602
|
+
return treeLevelOrderExpression(value);
|
|
603
|
+
}
|
|
346
604
|
if (normalizedType?.startsWith('List<')) {
|
|
347
605
|
return toJavaListLiteral(value, normalizedType);
|
|
348
606
|
}
|
|
@@ -353,34 +611,299 @@ function buildJavaExpression(value, expectedType) {
|
|
|
353
611
|
}
|
|
354
612
|
if (isRecord(value) && normalizedType === 'ListNode') return listExpression(value);
|
|
355
613
|
if (isRecord(value) && normalizedType === 'TreeNode') return treeExpression(value);
|
|
614
|
+
if (isRecord(value) && normalizedType?.startsWith('Map<')) return toJavaMapLiteral(value, normalizedType);
|
|
615
|
+
if (isRecord(value) && customObjectTypeName(value)) {
|
|
616
|
+
return `((${normalizedType ?? customObjectTypeName(value)}) ${toJavaDynamicObjectExpression(value)})`;
|
|
617
|
+
}
|
|
356
618
|
if (isListNodeShape(value)) return listExpression(value);
|
|
357
619
|
if (isTreeNodeShape(value)) return treeExpression(value);
|
|
358
620
|
return toJavaScalarLiteral(value);
|
|
359
621
|
}
|
|
360
622
|
|
|
623
|
+
function buildDynamicInputHelperMethods() {
|
|
624
|
+
return `
|
|
625
|
+
private static Object readJsonInput(String path, Class<?> targetType) {
|
|
626
|
+
try {
|
|
627
|
+
String source = java.nio.file.Files.readString(java.nio.file.Paths.get(path), java.nio.charset.StandardCharsets.UTF_8);
|
|
628
|
+
return coerceJsonInput(new __TracecodeJsonParser(source).parse(), targetType);
|
|
629
|
+
} catch (java.io.IOException error) {
|
|
630
|
+
throw new RuntimeException("Unable to read TraceCode input " + path, error);
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
private static Object coerceJsonInput(Object value, Class<?> targetType) {
|
|
635
|
+
if (value == null) return null;
|
|
636
|
+
if (targetType.isArray()) {
|
|
637
|
+
java.util.List<?> list = (java.util.List<?>) value;
|
|
638
|
+
Class<?> componentType = targetType.getComponentType();
|
|
639
|
+
Object array = java.lang.reflect.Array.newInstance(componentType, list.size());
|
|
640
|
+
for (int i = 0; i < list.size(); i++) {
|
|
641
|
+
java.lang.reflect.Array.set(array, i, coerceJsonInput(list.get(i), componentType));
|
|
642
|
+
}
|
|
643
|
+
return array;
|
|
644
|
+
}
|
|
645
|
+
if ((targetType == byte.class || targetType == Byte.class) && value instanceof Number) return ((Number) value).byteValue();
|
|
646
|
+
if ((targetType == short.class || targetType == Short.class) && value instanceof Number) return ((Number) value).shortValue();
|
|
647
|
+
if ((targetType == int.class || targetType == Integer.class) && value instanceof Number) return ((Number) value).intValue();
|
|
648
|
+
if ((targetType == long.class || targetType == Long.class) && value instanceof Number) return ((Number) value).longValue();
|
|
649
|
+
if ((targetType == float.class || targetType == Float.class) && value instanceof Number) return ((Number) value).floatValue();
|
|
650
|
+
if ((targetType == double.class || targetType == Double.class) && value instanceof Number) return ((Number) value).doubleValue();
|
|
651
|
+
if ((targetType == boolean.class || targetType == Boolean.class) && value instanceof Boolean) return value;
|
|
652
|
+
if ((targetType == char.class || targetType == Character.class) && value instanceof String && ((String) value).length() == 1) {
|
|
653
|
+
return ((String) value).charAt(0);
|
|
654
|
+
}
|
|
655
|
+
if (targetType == String.class && value instanceof String) return value;
|
|
656
|
+
return value;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
private static final class __TracecodeJsonParser {
|
|
660
|
+
private final String source;
|
|
661
|
+
private int index = 0;
|
|
662
|
+
|
|
663
|
+
__TracecodeJsonParser(String source) {
|
|
664
|
+
this.source = source == null || source.isEmpty() ? "null" : source;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
Object parse() {
|
|
668
|
+
skipWhitespace();
|
|
669
|
+
Object value = parseValue();
|
|
670
|
+
skipWhitespace();
|
|
671
|
+
if (index != source.length()) {
|
|
672
|
+
throw new IllegalArgumentException("Unexpected trailing JSON input");
|
|
673
|
+
}
|
|
674
|
+
return value;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
private Object parseValue() {
|
|
678
|
+
skipWhitespace();
|
|
679
|
+
char ch = peek();
|
|
680
|
+
if (ch == '"') return parseString();
|
|
681
|
+
if (ch == '[') return parseArray();
|
|
682
|
+
if (ch == '{') return parseObject();
|
|
683
|
+
if (ch == '-' || (ch >= '0' && ch <= '9')) return parseNumber();
|
|
684
|
+
if (consume("true")) return Boolean.TRUE;
|
|
685
|
+
if (consume("false")) return Boolean.FALSE;
|
|
686
|
+
if (consume("null")) return null;
|
|
687
|
+
throw new IllegalArgumentException("Invalid JSON input");
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
private java.util.List<Object> parseArray() {
|
|
691
|
+
expect('[');
|
|
692
|
+
java.util.ArrayList<Object> values = new java.util.ArrayList<>();
|
|
693
|
+
skipWhitespace();
|
|
694
|
+
if (peek() == ']') {
|
|
695
|
+
index++;
|
|
696
|
+
return values;
|
|
697
|
+
}
|
|
698
|
+
while (true) {
|
|
699
|
+
values.add(parseValue());
|
|
700
|
+
skipWhitespace();
|
|
701
|
+
char separator = take();
|
|
702
|
+
if (separator == ']') return values;
|
|
703
|
+
if (separator != ',') throw new IllegalArgumentException("Invalid JSON array");
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
private java.util.LinkedHashMap<String, Object> parseObject() {
|
|
708
|
+
expect('{');
|
|
709
|
+
java.util.LinkedHashMap<String, Object> values = new java.util.LinkedHashMap<>();
|
|
710
|
+
skipWhitespace();
|
|
711
|
+
if (peek() == '}') {
|
|
712
|
+
index++;
|
|
713
|
+
return values;
|
|
714
|
+
}
|
|
715
|
+
while (true) {
|
|
716
|
+
skipWhitespace();
|
|
717
|
+
String key = parseString();
|
|
718
|
+
skipWhitespace();
|
|
719
|
+
expect(':');
|
|
720
|
+
values.put(key, parseValue());
|
|
721
|
+
skipWhitespace();
|
|
722
|
+
char separator = take();
|
|
723
|
+
if (separator == '}') return values;
|
|
724
|
+
if (separator != ',') throw new IllegalArgumentException("Invalid JSON object");
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
private String parseString() {
|
|
729
|
+
expect('"');
|
|
730
|
+
StringBuilder out = new StringBuilder();
|
|
731
|
+
while (true) {
|
|
732
|
+
char ch = take();
|
|
733
|
+
if (ch == '"') return out.toString();
|
|
734
|
+
if (ch != '\\\\') {
|
|
735
|
+
out.append(ch);
|
|
736
|
+
continue;
|
|
737
|
+
}
|
|
738
|
+
char escaped = take();
|
|
739
|
+
switch (escaped) {
|
|
740
|
+
case '"': out.append('"'); break;
|
|
741
|
+
case '\\\\': out.append('\\\\'); break;
|
|
742
|
+
case '/': out.append('/'); break;
|
|
743
|
+
case 'b': out.append('\\b'); break;
|
|
744
|
+
case 'f': out.append('\\f'); break;
|
|
745
|
+
case 'n': out.append('\\n'); break;
|
|
746
|
+
case 'r': out.append('\\r'); break;
|
|
747
|
+
case 't': out.append('\\t'); break;
|
|
748
|
+
case 'u':
|
|
749
|
+
int codePoint = 0;
|
|
750
|
+
for (int i = 0; i < 4; i++) {
|
|
751
|
+
codePoint = (codePoint << 4) + Character.digit(take(), 16);
|
|
752
|
+
}
|
|
753
|
+
out.append((char) codePoint);
|
|
754
|
+
break;
|
|
755
|
+
default:
|
|
756
|
+
throw new IllegalArgumentException("Invalid JSON string escape");
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
private Number parseNumber() {
|
|
762
|
+
int start = index;
|
|
763
|
+
if (peek() == '-') index++;
|
|
764
|
+
while (peek() >= '0' && peek() <= '9') index++;
|
|
765
|
+
boolean floating = false;
|
|
766
|
+
if (peek() == '.') {
|
|
767
|
+
floating = true;
|
|
768
|
+
index++;
|
|
769
|
+
while (peek() >= '0' && peek() <= '9') index++;
|
|
770
|
+
}
|
|
771
|
+
if (peek() == 'e' || peek() == 'E') {
|
|
772
|
+
floating = true;
|
|
773
|
+
index++;
|
|
774
|
+
if (peek() == '+' || peek() == '-') index++;
|
|
775
|
+
while (peek() >= '0' && peek() <= '9') index++;
|
|
776
|
+
}
|
|
777
|
+
String raw = source.substring(start, index);
|
|
778
|
+
return floating ? Double.valueOf(raw) : Long.valueOf(raw);
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
private boolean consume(String literal) {
|
|
782
|
+
if (!source.startsWith(literal, index)) return false;
|
|
783
|
+
index += literal.length();
|
|
784
|
+
return true;
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
private void skipWhitespace() {
|
|
788
|
+
while (index < source.length() && Character.isWhitespace(source.charAt(index))) index++;
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
private char peek() {
|
|
792
|
+
return index < source.length() ? source.charAt(index) : '\\0';
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
private char take() {
|
|
796
|
+
if (index >= source.length()) throw new IllegalArgumentException("Unexpected end of JSON input");
|
|
797
|
+
return source.charAt(index++);
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
private void expect(char expected) {
|
|
801
|
+
char actual = take();
|
|
802
|
+
if (actual != expected) throw new IllegalArgumentException("Unexpected JSON character");
|
|
803
|
+
}
|
|
804
|
+
}`;
|
|
805
|
+
}
|
|
806
|
+
|
|
361
807
|
function buildHelperMethods(features) {
|
|
808
|
+
if (features.skipInputMaterializers) {
|
|
809
|
+
return '';
|
|
810
|
+
}
|
|
362
811
|
const members = [];
|
|
812
|
+
if (features.hasDynamicInputs) {
|
|
813
|
+
members.push(buildDynamicInputHelperMethods());
|
|
814
|
+
}
|
|
815
|
+
if (features.hasList || features.hasCustomObject) {
|
|
816
|
+
members.push(`
|
|
817
|
+
private static Object coerceMaterializedValue(Object value, Class<?> targetType) {
|
|
818
|
+
if (value == null) {
|
|
819
|
+
return null;
|
|
820
|
+
}
|
|
821
|
+
if (targetType.isInstance(value)) {
|
|
822
|
+
return value;
|
|
823
|
+
}
|
|
824
|
+
if (targetType.isArray() && value instanceof java.util.List<?>) {
|
|
825
|
+
java.util.List<?> list = (java.util.List<?>) value;
|
|
826
|
+
Class<?> componentType = targetType.getComponentType();
|
|
827
|
+
Object array = java.lang.reflect.Array.newInstance(componentType, list.size());
|
|
828
|
+
for (int i = 0; i < list.size(); i++) {
|
|
829
|
+
java.lang.reflect.Array.set(array, i, coerceMaterializedValue(list.get(i), componentType));
|
|
830
|
+
}
|
|
831
|
+
return array;
|
|
832
|
+
}
|
|
833
|
+
if ((targetType == int.class || targetType == Integer.class) && value instanceof Number) return ((Number) value).intValue();
|
|
834
|
+
if ((targetType == long.class || targetType == Long.class) && value instanceof Number) return ((Number) value).longValue();
|
|
835
|
+
if ((targetType == double.class || targetType == Double.class) && value instanceof Number) return ((Number) value).doubleValue();
|
|
836
|
+
if ((targetType == float.class || targetType == Float.class) && value instanceof Number) return ((Number) value).floatValue();
|
|
837
|
+
if ((targetType == short.class || targetType == Short.class) && value instanceof Number) return ((Number) value).shortValue();
|
|
838
|
+
if ((targetType == byte.class || targetType == Byte.class) && value instanceof Number) return ((Number) value).byteValue();
|
|
839
|
+
if ((targetType == boolean.class || targetType == Boolean.class) && value instanceof Boolean) return value;
|
|
840
|
+
if ((targetType == char.class || targetType == Character.class) && value instanceof String && ((String) value).length() == 1) {
|
|
841
|
+
return ((String) value).charAt(0);
|
|
842
|
+
}
|
|
843
|
+
return value;
|
|
844
|
+
}`);
|
|
845
|
+
}
|
|
363
846
|
if (features.hasList) {
|
|
364
847
|
members.push(`
|
|
365
|
-
private static ListNode list(
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
848
|
+
private static ListNode list(Object val, ListNode next) {
|
|
849
|
+
try {
|
|
850
|
+
for (java.lang.reflect.Constructor<?> ctor : ListNode.class.getDeclaredConstructors()) {
|
|
851
|
+
Class<?>[] parameterTypes = ctor.getParameterTypes();
|
|
852
|
+
if (parameterTypes.length == 2 && parameterTypes[1] == ListNode.class) {
|
|
853
|
+
ctor.setAccessible(true);
|
|
854
|
+
return (ListNode) ctor.newInstance(coerceMaterializedValue(val, parameterTypes[0]), next);
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
for (java.lang.reflect.Constructor<?> ctor : ListNode.class.getDeclaredConstructors()) {
|
|
858
|
+
Class<?>[] parameterTypes = ctor.getParameterTypes();
|
|
859
|
+
if (parameterTypes.length == 1) {
|
|
860
|
+
ctor.setAccessible(true);
|
|
861
|
+
ListNode node = (ListNode) ctor.newInstance(coerceMaterializedValue(val, parameterTypes[0]));
|
|
862
|
+
try {
|
|
863
|
+
java.lang.reflect.Field nextField = ListNode.class.getDeclaredField("next");
|
|
864
|
+
nextField.setAccessible(true);
|
|
865
|
+
nextField.set(node, next);
|
|
866
|
+
} catch (Exception ignored) {
|
|
867
|
+
}
|
|
868
|
+
return node;
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
java.lang.reflect.Constructor<ListNode> ctor = ListNode.class.getDeclaredConstructor();
|
|
872
|
+
ctor.setAccessible(true);
|
|
873
|
+
ListNode node = ctor.newInstance();
|
|
874
|
+
java.lang.reflect.Field valField = ListNode.class.getDeclaredField("val");
|
|
875
|
+
valField.setAccessible(true);
|
|
876
|
+
valField.set(node, coerceMaterializedValue(val, valField.getType()));
|
|
877
|
+
java.lang.reflect.Field nextField = ListNode.class.getDeclaredField("next");
|
|
878
|
+
nextField.setAccessible(true);
|
|
879
|
+
nextField.set(node, next);
|
|
880
|
+
return node;
|
|
881
|
+
} catch (Exception error) {
|
|
882
|
+
throw new RuntimeException("Unable to materialize ListNode", error);
|
|
883
|
+
}
|
|
369
884
|
}
|
|
370
885
|
|
|
371
|
-
private static ListNode buildList(
|
|
886
|
+
private static ListNode buildList(Object[] values, int[] nextIndices) {
|
|
372
887
|
if (values.length == 0) {
|
|
373
888
|
return null;
|
|
374
889
|
}
|
|
375
890
|
ListNode[] nodes = new ListNode[values.length];
|
|
376
891
|
for (int i = 0; i < values.length; i++) {
|
|
377
|
-
nodes[i] =
|
|
892
|
+
nodes[i] = list(values[i], null);
|
|
378
893
|
}
|
|
379
894
|
for (int i = 0; i < values.length; i++) {
|
|
380
895
|
int nextIndex = nextIndices[i];
|
|
381
896
|
nodes[i].next = nextIndex >= 0 ? nodes[nextIndex] : null;
|
|
382
897
|
}
|
|
383
898
|
return nodes[0];
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
private static int[] sequentialNextIndices(int length) {
|
|
902
|
+
int[] indices = new int[length];
|
|
903
|
+
for (int i = 0; i < length; i++) {
|
|
904
|
+
indices[i] = i + 1 < length ? i + 1 : -1;
|
|
905
|
+
}
|
|
906
|
+
return indices;
|
|
384
907
|
}`);
|
|
385
908
|
}
|
|
386
909
|
if (features.hasTree) {
|
|
@@ -390,33 +913,220 @@ function buildHelperMethods(features) {
|
|
|
390
913
|
node.left = left;
|
|
391
914
|
node.right = right;
|
|
392
915
|
return node;
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
private static TreeNode buildTree(Integer[] values) {
|
|
919
|
+
if (values.length == 0 || values[0] == null) {
|
|
920
|
+
return null;
|
|
921
|
+
}
|
|
922
|
+
TreeNode root = new TreeNode(values[0]);
|
|
923
|
+
java.util.Queue<TreeNode> queue = new java.util.ArrayDeque<>();
|
|
924
|
+
queue.add(root);
|
|
925
|
+
int index = 1;
|
|
926
|
+
while (!queue.isEmpty() && index < values.length) {
|
|
927
|
+
TreeNode current = queue.remove();
|
|
928
|
+
if (values[index] != null) {
|
|
929
|
+
current.left = new TreeNode(values[index]);
|
|
930
|
+
queue.add(current.left);
|
|
931
|
+
}
|
|
932
|
+
index++;
|
|
933
|
+
if (index < values.length && values[index] != null) {
|
|
934
|
+
current.right = new TreeNode(values[index]);
|
|
935
|
+
queue.add(current.right);
|
|
936
|
+
}
|
|
937
|
+
index++;
|
|
938
|
+
}
|
|
939
|
+
return root;
|
|
393
940
|
}`);
|
|
941
|
+
}
|
|
942
|
+
if (features.hasMap || features.hasCustomObject) {
|
|
943
|
+
members.push(`
|
|
944
|
+
@SuppressWarnings({"unchecked", "rawtypes"})
|
|
945
|
+
private static <K, V> java.util.LinkedHashMap<K, V> typedMap(Object[][] entries) {
|
|
946
|
+
java.util.LinkedHashMap<K, V> map = new java.util.LinkedHashMap<>();
|
|
947
|
+
for (Object[] entry : entries) {
|
|
948
|
+
map.put((K) entry[0], (V) entry[1]);
|
|
949
|
+
}
|
|
950
|
+
return map;
|
|
951
|
+
}
|
|
952
|
+
`);
|
|
953
|
+
}
|
|
954
|
+
if (features.hasCustomObject) {
|
|
955
|
+
members.push(`
|
|
956
|
+
|
|
957
|
+
private static java.util.LinkedHashMap<String, Object> objectFields(Object[][] entries) {
|
|
958
|
+
java.util.LinkedHashMap<String, Object> fields = new java.util.LinkedHashMap<>();
|
|
959
|
+
for (Object[] entry : entries) {
|
|
960
|
+
fields.put((String) entry[0], entry[1]);
|
|
961
|
+
}
|
|
962
|
+
return fields;
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
private static Object materializeObject(String typeName, java.util.LinkedHashMap<String, Object> fields) {
|
|
966
|
+
try {
|
|
967
|
+
Class<?> cls = Class.forName(new Object() {}.getClass().getPackageName() + "." + typeName);
|
|
968
|
+
Object[] values = fields.values().toArray();
|
|
969
|
+
for (java.lang.reflect.Constructor<?> ctor : cls.getDeclaredConstructors()) {
|
|
970
|
+
if (ctor.getParameterCount() != values.length) {
|
|
971
|
+
continue;
|
|
972
|
+
}
|
|
973
|
+
try {
|
|
974
|
+
Class<?>[] parameterTypes = ctor.getParameterTypes();
|
|
975
|
+
Object[] args = new Object[values.length];
|
|
976
|
+
for (int i = 0; i < values.length; i++) {
|
|
977
|
+
args[i] = coerceMaterializedValue(values[i], parameterTypes[i]);
|
|
978
|
+
}
|
|
979
|
+
ctor.setAccessible(true);
|
|
980
|
+
return ctor.newInstance(args);
|
|
981
|
+
} catch (Exception ignored) {
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
for (java.lang.reflect.Constructor<?> ctor : cls.getDeclaredConstructors()) {
|
|
985
|
+
if (ctor.getParameterCount() != 1 || values.length == 0) {
|
|
986
|
+
continue;
|
|
987
|
+
}
|
|
988
|
+
try {
|
|
989
|
+
Class<?>[] parameterTypes = ctor.getParameterTypes();
|
|
990
|
+
ctor.setAccessible(true);
|
|
991
|
+
Object instance = ctor.newInstance(coerceMaterializedValue(values[0], parameterTypes[0]));
|
|
992
|
+
for (java.util.Map.Entry<String, Object> entry : fields.entrySet()) {
|
|
993
|
+
try {
|
|
994
|
+
java.lang.reflect.Field field = cls.getDeclaredField(entry.getKey());
|
|
995
|
+
field.setAccessible(true);
|
|
996
|
+
field.set(instance, coerceMaterializedValue(entry.getValue(), field.getType()));
|
|
997
|
+
} catch (NoSuchFieldException ignored) {
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
return instance;
|
|
1001
|
+
} catch (Exception ignored) {
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
java.lang.reflect.Constructor<?> noArg = cls.getDeclaredConstructor();
|
|
1005
|
+
noArg.setAccessible(true);
|
|
1006
|
+
Object instance = noArg.newInstance();
|
|
1007
|
+
for (java.util.Map.Entry<String, Object> entry : fields.entrySet()) {
|
|
1008
|
+
java.lang.reflect.Field field = cls.getDeclaredField(entry.getKey());
|
|
1009
|
+
field.setAccessible(true);
|
|
1010
|
+
field.set(instance, coerceMaterializedValue(entry.getValue(), field.getType()));
|
|
1011
|
+
}
|
|
1012
|
+
return instance;
|
|
1013
|
+
} catch (Exception error) {
|
|
1014
|
+
throw new RuntimeException("Unable to materialize " + typeName, error);
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
`);
|
|
394
1019
|
}
|
|
395
1020
|
return members.join('\n');
|
|
396
1021
|
}
|
|
397
1022
|
|
|
1023
|
+
function sourceDeclaresJavaClass(source, className) {
|
|
1024
|
+
const escapedName = String(className).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
1025
|
+
return new RegExp(`\\bclass\\s+${escapedName}\\b`).test(String(source ?? ''));
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
function buildNodePreludeSource(source, options = {}) {
|
|
1029
|
+
if (options.scriptMode === true) {
|
|
1030
|
+
return '';
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
const declarations = [];
|
|
1034
|
+
if (!sourceDeclaresJavaClass(source, 'ListNode')) {
|
|
1035
|
+
declarations.push(`class ListNode {
|
|
1036
|
+
int val;
|
|
1037
|
+
int value;
|
|
1038
|
+
ListNode next;
|
|
1039
|
+
|
|
1040
|
+
ListNode() {
|
|
1041
|
+
this(0, null);
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
ListNode(int val) {
|
|
1045
|
+
this(val, null);
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
ListNode(int val, ListNode next) {
|
|
1049
|
+
this.val = val;
|
|
1050
|
+
this.value = val;
|
|
1051
|
+
this.next = next;
|
|
1052
|
+
}
|
|
1053
|
+
}`);
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
if (!sourceDeclaresJavaClass(source, 'TreeNode')) {
|
|
1057
|
+
declarations.push(`class TreeNode {
|
|
1058
|
+
int val;
|
|
1059
|
+
int value;
|
|
1060
|
+
TreeNode left;
|
|
1061
|
+
TreeNode right;
|
|
1062
|
+
|
|
1063
|
+
TreeNode() {
|
|
1064
|
+
this(0, null, null);
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
TreeNode(int val) {
|
|
1068
|
+
this(val, null, null);
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
TreeNode(int val, TreeNode left, TreeNode right) {
|
|
1072
|
+
this.val = val;
|
|
1073
|
+
this.value = val;
|
|
1074
|
+
this.left = left;
|
|
1075
|
+
this.right = right;
|
|
1076
|
+
}
|
|
1077
|
+
}`);
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
return declarations.length > 0 ? `${declarations.join('\n\n')}\n\n` : '';
|
|
1081
|
+
}
|
|
1082
|
+
|
|
398
1083
|
function extractMethodParameters(source, methodName) {
|
|
1084
|
+
return extractMethodParameterOverloads(source, methodName)[0] ?? [];
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
function extractMethodParameterOverloads(source, methodName) {
|
|
399
1088
|
const compact = source.replace(/\s+/g, ' ');
|
|
400
1089
|
const escapedMethod = methodName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
401
|
-
const
|
|
402
|
-
|
|
403
|
-
|
|
1090
|
+
const overloads = [];
|
|
1091
|
+
const pattern = new RegExp(`\\b${escapedMethod}\\s*\\(([^)]*)\\)`, 'g');
|
|
1092
|
+
for (const match of compact.matchAll(pattern)) {
|
|
1093
|
+
const rawParameters = match[1]?.trim();
|
|
1094
|
+
if (!rawParameters) {
|
|
1095
|
+
overloads.push([]);
|
|
1096
|
+
continue;
|
|
1097
|
+
}
|
|
1098
|
+
overloads.push(
|
|
1099
|
+
splitTopLevelCommaList(rawParameters)
|
|
1100
|
+
.map((segment) => segment.trim())
|
|
1101
|
+
.filter(Boolean)
|
|
1102
|
+
.map((segment) => {
|
|
1103
|
+
const lastSpace = segment.lastIndexOf(' ');
|
|
1104
|
+
if (lastSpace === -1) {
|
|
1105
|
+
return { type: segment, name: segment };
|
|
1106
|
+
}
|
|
1107
|
+
return {
|
|
1108
|
+
type: segment.slice(0, lastSpace).trim(),
|
|
1109
|
+
name: segment.slice(lastSpace + 1).trim(),
|
|
1110
|
+
};
|
|
1111
|
+
})
|
|
1112
|
+
);
|
|
404
1113
|
}
|
|
1114
|
+
return overloads;
|
|
1115
|
+
}
|
|
405
1116
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
});
|
|
1117
|
+
function extractMethodParametersForArguments(source, methodName, rawArgs) {
|
|
1118
|
+
const args = Array.isArray(rawArgs) ? rawArgs : [];
|
|
1119
|
+
const overloads = extractMethodParameterOverloads(source, methodName);
|
|
1120
|
+
return overloads.find((parameters) => parameters.length === args.length) ?? overloads[0] ?? [];
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
function extractMethodReturnType(source, methodName) {
|
|
1124
|
+
const compact = source.replace(/\s+/g, ' ');
|
|
1125
|
+
const escapedMethod = methodName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
1126
|
+
const match = compact.match(
|
|
1127
|
+
new RegExp(`\\b(?:public|private|protected|static|final|synchronized|abstract|native|strictfp|\\s)*([A-Za-z_][A-Za-z0-9_<>,.?\\[\\]\\s]*)\\s+${escapedMethod}\\s*\\(`)
|
|
1128
|
+
);
|
|
1129
|
+
return match?.[1]?.trim() ?? null;
|
|
420
1130
|
}
|
|
421
1131
|
|
|
422
1132
|
function indentBlock(source, spaces = 2) {
|
|
@@ -507,7 +1217,68 @@ function findMatchingParen(source, openIndex) {
|
|
|
507
1217
|
return closeIndex;
|
|
508
1218
|
}
|
|
509
1219
|
|
|
1220
|
+
function findMatchingBrace(source, openIndex) {
|
|
1221
|
+
let depth = 0;
|
|
1222
|
+
let closeIndex = -1;
|
|
1223
|
+
scanJavaCode(source, openIndex, source.length, (index, ch) => {
|
|
1224
|
+
if (ch === '{') depth += 1;
|
|
1225
|
+
if (ch === '}') {
|
|
1226
|
+
depth -= 1;
|
|
1227
|
+
if (depth === 0) {
|
|
1228
|
+
closeIndex = index;
|
|
1229
|
+
return false;
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
return undefined;
|
|
1233
|
+
});
|
|
1234
|
+
return closeIndex;
|
|
1235
|
+
}
|
|
1236
|
+
|
|
510
1237
|
function findSingleStatementEnd(source, bodyStart) {
|
|
1238
|
+
let cursor = bodyStart;
|
|
1239
|
+
while (/\s/.test(source[cursor] ?? '')) cursor += 1;
|
|
1240
|
+
if (startsWithJavaKeyword(source, cursor, 'if')) {
|
|
1241
|
+
let headerStart = cursor + 'if'.length;
|
|
1242
|
+
while (/\s/.test(source[headerStart] ?? '')) headerStart += 1;
|
|
1243
|
+
if (source[headerStart] === '(') {
|
|
1244
|
+
const closeParen = findMatchingParen(source, headerStart);
|
|
1245
|
+
if (closeParen >= 0) {
|
|
1246
|
+
let nestedBodyStart = closeParen + 1;
|
|
1247
|
+
while (/\s/.test(source[nestedBodyStart] ?? '')) nestedBodyStart += 1;
|
|
1248
|
+
if (source[nestedBodyStart] === '{') {
|
|
1249
|
+
const closeBrace = findMatchingBrace(source, nestedBodyStart);
|
|
1250
|
+
if (closeBrace >= 0) return closeBrace;
|
|
1251
|
+
}
|
|
1252
|
+
if (source[nestedBodyStart] && source[nestedBodyStart] !== ';') {
|
|
1253
|
+
return findSingleStatementEnd(source, nestedBodyStart);
|
|
1254
|
+
}
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
const loopKeyword = startsWithJavaKeyword(source, cursor, 'for')
|
|
1259
|
+
? 'for'
|
|
1260
|
+
: startsWithJavaKeyword(source, cursor, 'while')
|
|
1261
|
+
? 'while'
|
|
1262
|
+
: null;
|
|
1263
|
+
if (loopKeyword) {
|
|
1264
|
+
let headerStart = cursor + loopKeyword.length;
|
|
1265
|
+
while (/\s/.test(source[headerStart] ?? '')) headerStart += 1;
|
|
1266
|
+
if (source[headerStart] === '(') {
|
|
1267
|
+
const closeParen = findMatchingParen(source, headerStart);
|
|
1268
|
+
if (closeParen >= 0) {
|
|
1269
|
+
let nestedBodyStart = closeParen + 1;
|
|
1270
|
+
while (/\s/.test(source[nestedBodyStart] ?? '')) nestedBodyStart += 1;
|
|
1271
|
+
if (source[nestedBodyStart] === '{') {
|
|
1272
|
+
const closeBrace = findMatchingBrace(source, nestedBodyStart);
|
|
1273
|
+
if (closeBrace >= 0) return closeBrace;
|
|
1274
|
+
}
|
|
1275
|
+
if (source[nestedBodyStart] && source[nestedBodyStart] !== ';') {
|
|
1276
|
+
return findSingleStatementEnd(source, nestedBodyStart);
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
|
|
511
1282
|
let parenDepth = 0;
|
|
512
1283
|
let bracketDepth = 0;
|
|
513
1284
|
let braceDepth = 0;
|
|
@@ -537,14 +1308,64 @@ function startsWithJavaKeyword(source, index, keyword) {
|
|
|
537
1308
|
return !after || !isJavaIdentifierPart(after);
|
|
538
1309
|
}
|
|
539
1310
|
|
|
540
|
-
function
|
|
541
|
-
|
|
1311
|
+
function braceDeltaForLine(line) {
|
|
1312
|
+
let delta = 0;
|
|
1313
|
+
scanJavaCode(line, 0, line.length, (_index, ch) => {
|
|
1314
|
+
if (ch === '{') delta += 1;
|
|
1315
|
+
if (ch === '}') delta -= 1;
|
|
1316
|
+
return undefined;
|
|
1317
|
+
});
|
|
1318
|
+
return delta;
|
|
1319
|
+
}
|
|
1320
|
+
|
|
1321
|
+
function isUnbracedLoopHeaderLine(line) {
|
|
1322
|
+
const trimmed = line.trim();
|
|
1323
|
+
return /^(?:for|while)\s*\(.*\)\s*$/.test(trimmed) && !trimmed.includes('{') && !trimmed.endsWith(';');
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
function startsBracedLoopLine(line) {
|
|
1327
|
+
const trimmed = line.trim();
|
|
1328
|
+
return /^(?:for|while)\s*\(.*\)\s*\{/.test(trimmed);
|
|
1329
|
+
}
|
|
1330
|
+
|
|
1331
|
+
function wrapNestedBracedLoopBodies(source) {
|
|
1332
|
+
const lines = source.split(/\r?\n/);
|
|
1333
|
+
const output = [];
|
|
1334
|
+
let changed = false;
|
|
1335
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
1336
|
+
const line = lines[index] ?? '';
|
|
1337
|
+
const next = lines[index + 1] ?? '';
|
|
1338
|
+
if (!isUnbracedLoopHeaderLine(line) || !startsBracedLoopLine(next)) {
|
|
1339
|
+
output.push(line);
|
|
1340
|
+
continue;
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1343
|
+
changed = true;
|
|
1344
|
+
output.push(`${line} {`);
|
|
1345
|
+
index += 1;
|
|
1346
|
+
let depth = 0;
|
|
1347
|
+
for (; index < lines.length; index += 1) {
|
|
1348
|
+
const nestedLine = lines[index] ?? '';
|
|
1349
|
+
output.push(nestedLine);
|
|
1350
|
+
depth += braceDeltaForLine(nestedLine);
|
|
1351
|
+
if (depth <= 0) break;
|
|
1352
|
+
}
|
|
1353
|
+
output.push(`${line.match(/^\s*/)?.[0] ?? ''}}`);
|
|
1354
|
+
}
|
|
1355
|
+
return changed ? output.join('\n') : source;
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1358
|
+
function wrapSingleStatementLoopBodies(source) {
|
|
1359
|
+
source = wrapNestedBracedLoopBodies(source);
|
|
1360
|
+
const inserts = [];
|
|
542
1361
|
scanJavaCode(source, 0, source.length, (index) => {
|
|
543
1362
|
const keyword = source.startsWith('for', index)
|
|
544
1363
|
? 'for'
|
|
545
1364
|
: source.startsWith('while', index)
|
|
546
1365
|
? 'while'
|
|
547
|
-
:
|
|
1366
|
+
: source.startsWith('if', index)
|
|
1367
|
+
? 'if'
|
|
1368
|
+
: null;
|
|
548
1369
|
if (!keyword) return undefined;
|
|
549
1370
|
|
|
550
1371
|
const before = index > 0 ? source[index - 1] : '';
|
|
@@ -565,7 +1386,6 @@ function wrapSingleStatementLoopBodies(source) {
|
|
|
565
1386
|
const bodyChar = source[bodyStart];
|
|
566
1387
|
if (!bodyChar || bodyChar === '{' || bodyChar === ';') return closeParen;
|
|
567
1388
|
if (
|
|
568
|
-
startsWithJavaKeyword(source, bodyStart, 'if') ||
|
|
569
1389
|
startsWithJavaKeyword(source, bodyStart, 'switch') ||
|
|
570
1390
|
startsWithJavaKeyword(source, bodyStart, 'synchronized') ||
|
|
571
1391
|
startsWithJavaKeyword(source, bodyStart, 'try')
|
|
@@ -593,7 +1413,7 @@ function wrapSingleStatementLoopBodies(source) {
|
|
|
593
1413
|
output += insertsByIndex.get(index) ?? '';
|
|
594
1414
|
if (index < source.length) output += source[index];
|
|
595
1415
|
}
|
|
596
|
-
return output;
|
|
1416
|
+
return output === source ? output : wrapSingleStatementLoopBodies(output);
|
|
597
1417
|
}
|
|
598
1418
|
|
|
599
1419
|
function splitTopLevelJavaList(value) {
|
|
@@ -675,6 +1495,13 @@ function escapeRegExp(value) {
|
|
|
675
1495
|
return String(value).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
676
1496
|
}
|
|
677
1497
|
|
|
1498
|
+
function parseNativeTraceLine(line) {
|
|
1499
|
+
const match = line.match(/TraceHooks\.emit(?:Line|Call|Return)AtLine\((\d+)\b/);
|
|
1500
|
+
if (!match) return null;
|
|
1501
|
+
const lineNumber = Number.parseInt(match[1], 10);
|
|
1502
|
+
return Number.isFinite(lineNumber) && lineNumber > 0 ? lineNumber : null;
|
|
1503
|
+
}
|
|
1504
|
+
|
|
678
1505
|
function augmentTraceCallArgumentSnapshots(source) {
|
|
679
1506
|
const lines = source.split('\n');
|
|
680
1507
|
const methodStack = [];
|
|
@@ -697,14 +1524,14 @@ function augmentTraceCallArgumentSnapshots(source) {
|
|
|
697
1524
|
let nextLine = line;
|
|
698
1525
|
if (currentMethod && !currentMethod.patchedCall && currentMethod.params.length > 0) {
|
|
699
1526
|
const callPattern = new RegExp(
|
|
700
|
-
`^(\\s*)TraceHooks\\.
|
|
1527
|
+
`^(\\s*)TraceHooks\\.emitCallAtLine\\((\\d+),\\s*"${escapeRegExp(currentMethod.name)}",\\s*([^)]*)\\);\\s*$`
|
|
701
1528
|
);
|
|
702
1529
|
const callMatch = line.match(callPattern);
|
|
703
1530
|
if (callMatch) {
|
|
704
1531
|
const serializedArgs = currentMethod.params
|
|
705
1532
|
.map((paramName) => ` + " ${paramName}=" + TraceHooks.serializeResult(${paramName})`)
|
|
706
1533
|
.join('');
|
|
707
|
-
nextLine = `${callMatch[1]}TraceHooks.
|
|
1534
|
+
nextLine = `${callMatch[1]}TraceHooks.emitCallAtLine(${callMatch[2]}, "${currentMethod.name}", ""${serializedArgs});`;
|
|
708
1535
|
currentMethod.patchedCall = true;
|
|
709
1536
|
}
|
|
710
1537
|
}
|
|
@@ -720,6 +1547,389 @@ function augmentTraceCallArgumentSnapshots(source) {
|
|
|
720
1547
|
}).join('\n');
|
|
721
1548
|
}
|
|
722
1549
|
|
|
1550
|
+
function collectJavaLocalDeclarations(line) {
|
|
1551
|
+
const names = [];
|
|
1552
|
+
const trimmedLine = String(line).trim();
|
|
1553
|
+
if (trimmedLine.startsWith('//') || trimmedLine.startsWith('/*') || trimmedLine.startsWith('*')) {
|
|
1554
|
+
return names;
|
|
1555
|
+
}
|
|
1556
|
+
const declarationPattern =
|
|
1557
|
+
/\b(?:final\s+)?((?:boolean|byte|char|short|int|long|float|double|String|Object|[A-Za-z_][A-Za-z0-9_<>.?]*(?:\s*<[^,;=(){}:]+>)?)\s*(?:\[\s*\])*)\s+([A-Za-z_][A-Za-z0-9_]*)\s*(?==)/g;
|
|
1558
|
+
const skippedNames = new Set(['class', 'interface', 'enum', 'record', 'return', 'new']);
|
|
1559
|
+
for (const match of line.matchAll(declarationPattern)) {
|
|
1560
|
+
const typeSource = match[1] ?? '';
|
|
1561
|
+
const name = match[2];
|
|
1562
|
+
if (name && !skippedNames.has(name) && !name.startsWith('__tracecode')) {
|
|
1563
|
+
names.push(name);
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1566
|
+
const enhancedForMatch = line.match(
|
|
1567
|
+
/\bfor\s*\(\s*(?:final\s+)?((?:boolean|byte|char|short|int|long|float|double|String|Object|[A-Za-z_][A-Za-z0-9_<>.?]*(?:\s*<[^,;=(){}:]+>)?)\s*(?:\[\s*\])*)\s+([A-Za-z_][A-Za-z0-9_]*)\s*:/
|
|
1568
|
+
);
|
|
1569
|
+
const enhancedForType = enhancedForMatch?.[1] ?? '';
|
|
1570
|
+
const enhancedForName = enhancedForMatch?.[2];
|
|
1571
|
+
if (enhancedForName && !skippedNames.has(enhancedForName) && !enhancedForName.startsWith('__tracecode')) {
|
|
1572
|
+
names.push(enhancedForName);
|
|
1573
|
+
}
|
|
1574
|
+
return names;
|
|
1575
|
+
}
|
|
1576
|
+
|
|
1577
|
+
function visibleJavaLocalNames(scopeStack) {
|
|
1578
|
+
const names = [];
|
|
1579
|
+
const seen = new Set();
|
|
1580
|
+
for (const scope of scopeStack) {
|
|
1581
|
+
for (const name of scope.names) {
|
|
1582
|
+
if (!seen.has(name)) {
|
|
1583
|
+
names.push(name);
|
|
1584
|
+
seen.add(name);
|
|
1585
|
+
}
|
|
1586
|
+
}
|
|
1587
|
+
}
|
|
1588
|
+
return names;
|
|
1589
|
+
}
|
|
1590
|
+
|
|
1591
|
+
function isUnbracedForDeclarationLine(line) {
|
|
1592
|
+
return /^\s*for\s*\(/.test(line) && !(line.includes('{'));
|
|
1593
|
+
}
|
|
1594
|
+
|
|
1595
|
+
function isControlHeaderDeclarationLine(line) {
|
|
1596
|
+
return /^\s*(?:for|if|while|switch|catch)\s*\(/.test(line);
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1599
|
+
function traceEmitAlreadyIncludesVariable(emitExpression, name) {
|
|
1600
|
+
return new RegExp(`\\b${escapeRegExp(name)}=`).test(emitExpression);
|
|
1601
|
+
}
|
|
1602
|
+
|
|
1603
|
+
function appendJavaLocalSnapshotsToEmitLine(line, scopeStack) {
|
|
1604
|
+
const visibleNames = visibleJavaLocalNames(scopeStack);
|
|
1605
|
+
if (visibleNames.length === 0 || !line.includes('TraceHooks.emitLineAtLine(')) {
|
|
1606
|
+
return line;
|
|
1607
|
+
}
|
|
1608
|
+
|
|
1609
|
+
return line.replace(/TraceHooks\.emitLineAtLine\((\d+)(?:,\s*([^;]*?))?\);/g, (match, lineNumber, snapshotExpression) => {
|
|
1610
|
+
const emitExpression = snapshotExpression ?? '';
|
|
1611
|
+
const additions = visibleNames
|
|
1612
|
+
.filter((name) => !traceEmitAlreadyIncludesVariable(emitExpression, name))
|
|
1613
|
+
.map((name) => ` + " ${name}=" + TraceHooks.serializeResult(${name})`)
|
|
1614
|
+
.join('');
|
|
1615
|
+
if (!additions) return match;
|
|
1616
|
+
const prefix = emitExpression.trim().length > 0 ? emitExpression.trim() : '""';
|
|
1617
|
+
return `TraceHooks.emitLineAtLine(${Number.parseInt(lineNumber, 10)}, ${prefix}${additions});`;
|
|
1618
|
+
});
|
|
1619
|
+
}
|
|
1620
|
+
|
|
1621
|
+
function appendJavaLocalSnapshotsAfterMutations(line, scopeStack) {
|
|
1622
|
+
const visibleNames = visibleJavaLocalNames(scopeStack);
|
|
1623
|
+
if (visibleNames.length === 0 || !line.includes('TraceHooks.emitMutatingCallAtLine(')) {
|
|
1624
|
+
return line;
|
|
1625
|
+
}
|
|
1626
|
+
|
|
1627
|
+
return line.replace(
|
|
1628
|
+
/(TraceHooks\.emitMutatingCallAtLine\((\d+),[^;]+;\s*)/g,
|
|
1629
|
+
(match, statement, lineNumber) => {
|
|
1630
|
+
const additions = visibleNames
|
|
1631
|
+
.map((name) => ` + " ${name}=" + TraceHooks.serializeResult(${name})`)
|
|
1632
|
+
.join('');
|
|
1633
|
+
return `${statement} TraceHooks.emitLineAtLine(${lineNumber}, ""${additions});`;
|
|
1634
|
+
}
|
|
1635
|
+
);
|
|
1636
|
+
}
|
|
1637
|
+
|
|
1638
|
+
function guardJavaLineEmit(line) {
|
|
1639
|
+
return line.replace(
|
|
1640
|
+
/^(\s*)TraceHooks\.emitLineAtLine\((.+)\);\s*$/,
|
|
1641
|
+
(_match, indent, argsSource) => `${indent}if (!TraceHooks.traceLimitExceeded()) TraceHooks.emitLineAtLine(${argsSource});`
|
|
1642
|
+
);
|
|
1643
|
+
}
|
|
1644
|
+
|
|
1645
|
+
function appendJavaScalarDeclarationWrites(line, lineNumber) {
|
|
1646
|
+
if (line.includes('TraceHooks.emitScalarWriteAtLine(')) return line;
|
|
1647
|
+
if (/TraceHooks\.read[A-Za-z0-9_]*AtLine\(/.test(line)) return line;
|
|
1648
|
+
if (/^\s*(?:for|if|while|switch|catch)\s*\(/.test(line)) return line;
|
|
1649
|
+
if (!/;\s*$/.test(line)) return line;
|
|
1650
|
+
const declarations = collectJavaLocalDeclarations(line);
|
|
1651
|
+
if (declarations.length === 0) return line;
|
|
1652
|
+
const indent = line.match(/^(\s*)/)?.[1] ?? '';
|
|
1653
|
+
const writes = declarations
|
|
1654
|
+
.map((name) => `${indent}TraceHooks.emitScalarWriteAtLine(${lineNumber}, "${name}", ${name});`)
|
|
1655
|
+
.join('\n');
|
|
1656
|
+
return `${line}\n${writes}`;
|
|
1657
|
+
}
|
|
1658
|
+
|
|
1659
|
+
function appendJavaPendingScalarDeclarationWrites(line, lineNumber, declarations) {
|
|
1660
|
+
if (!Array.isArray(declarations) || declarations.length === 0) return line;
|
|
1661
|
+
if (!/;\s*$/.test(line)) return line;
|
|
1662
|
+
const indent = line.match(/^(\s*)/)?.[1] ?? '';
|
|
1663
|
+
const writes = declarations
|
|
1664
|
+
.map((name) => `${indent}TraceHooks.emitScalarWriteAtLine(${lineNumber}, "${name}", ${name});`)
|
|
1665
|
+
.join('\n');
|
|
1666
|
+
return writes ? `${line}\n${writes}` : line;
|
|
1667
|
+
}
|
|
1668
|
+
|
|
1669
|
+
function augmentJavaLocalSnapshots(source) {
|
|
1670
|
+
const lines = source.split('\n');
|
|
1671
|
+
const output = [];
|
|
1672
|
+
const scopeStack = [];
|
|
1673
|
+
let currentTraceLine = null;
|
|
1674
|
+
let pendingScalarDeclarationWrites = null;
|
|
1675
|
+
let methodDepth = 0;
|
|
1676
|
+
const methodStartPattern =
|
|
1677
|
+
/^(\s*)(?:(?:public|private|protected|static|final|synchronized)\s+)*(?:[A-Za-z_][A-Za-z0-9_<>\[\], ?]*\s+)+([A-Za-z_][A-Za-z0-9_]*)\s*\(([^)]*)\)\s*\{\s*$/;
|
|
1678
|
+
|
|
1679
|
+
for (const line of lines) {
|
|
1680
|
+
if (methodDepth <= 0) {
|
|
1681
|
+
const methodMatch = line.match(methodStartPattern);
|
|
1682
|
+
if (methodMatch) {
|
|
1683
|
+
methodDepth = Math.max(0, braceDelta(line));
|
|
1684
|
+
const params = parseJavaParameterNames(methodMatch[3] ?? '');
|
|
1685
|
+
scopeStack.length = 0;
|
|
1686
|
+
scopeStack.push({ names: params });
|
|
1687
|
+
output.push(line);
|
|
1688
|
+
if (methodDepth <= 0) {
|
|
1689
|
+
scopeStack.length = 0;
|
|
1690
|
+
pendingScalarDeclarationWrites = null;
|
|
1691
|
+
}
|
|
1692
|
+
continue;
|
|
1693
|
+
}
|
|
1694
|
+
output.push(line);
|
|
1695
|
+
continue;
|
|
1696
|
+
}
|
|
1697
|
+
|
|
1698
|
+
const leadingClosingCount = line.match(/^\s*}+/)?.[0].replace(/\s/g, '').length ?? 0;
|
|
1699
|
+
for (let index = 0; index < leadingClosingCount; index += 1) {
|
|
1700
|
+
if (scopeStack.length > 0) scopeStack.pop();
|
|
1701
|
+
}
|
|
1702
|
+
|
|
1703
|
+
const transformedLine = guardJavaLineEmit(appendJavaLocalSnapshotsAfterMutations(
|
|
1704
|
+
appendJavaLocalSnapshotsToEmitLine(line, scopeStack),
|
|
1705
|
+
scopeStack
|
|
1706
|
+
));
|
|
1707
|
+
output.push(transformedLine);
|
|
1708
|
+
const emittedTraceLine = parseNativeTraceLine(output[output.length - 1]);
|
|
1709
|
+
if (emittedTraceLine !== null) currentTraceLine = emittedTraceLine;
|
|
1710
|
+
|
|
1711
|
+
const declarations = collectJavaLocalDeclarations(line);
|
|
1712
|
+
if (declarations.length > 0 && currentTraceLine !== null) {
|
|
1713
|
+
const lastIndex = output.length - 1;
|
|
1714
|
+
output[lastIndex] = appendJavaScalarDeclarationWrites(output[lastIndex], currentTraceLine);
|
|
1715
|
+
if (
|
|
1716
|
+
!isControlHeaderDeclarationLine(line) &&
|
|
1717
|
+
line.includes('=') &&
|
|
1718
|
+
!/;\s*$/.test(line)
|
|
1719
|
+
) {
|
|
1720
|
+
pendingScalarDeclarationWrites = {
|
|
1721
|
+
lineNumber: currentTraceLine,
|
|
1722
|
+
declarations: [...declarations],
|
|
1723
|
+
};
|
|
1724
|
+
}
|
|
1725
|
+
} else if (pendingScalarDeclarationWrites && /;\s*$/.test(line)) {
|
|
1726
|
+
const lastIndex = output.length - 1;
|
|
1727
|
+
output[lastIndex] = appendJavaPendingScalarDeclarationWrites(
|
|
1728
|
+
output[lastIndex],
|
|
1729
|
+
pendingScalarDeclarationWrites.lineNumber,
|
|
1730
|
+
pendingScalarDeclarationWrites.declarations
|
|
1731
|
+
);
|
|
1732
|
+
pendingScalarDeclarationWrites = null;
|
|
1733
|
+
}
|
|
1734
|
+
const declarationsBelongToCurrentScope =
|
|
1735
|
+
declarations.length > 0 && !isControlHeaderDeclarationLine(line);
|
|
1736
|
+
if (declarationsBelongToCurrentScope) {
|
|
1737
|
+
const currentScope = scopeStack[scopeStack.length - 1];
|
|
1738
|
+
if (currentScope) {
|
|
1739
|
+
for (const name of declarations) {
|
|
1740
|
+
currentScope.names.push(name);
|
|
1741
|
+
}
|
|
1742
|
+
}
|
|
1743
|
+
}
|
|
1744
|
+
const braceCounts = javaBraceCounts(line);
|
|
1745
|
+
const openingCount = braceCounts.open;
|
|
1746
|
+
const closingCount = Math.max(0, braceCounts.close - leadingClosingCount);
|
|
1747
|
+
for (let index = 0; index < openingCount; index += 1) {
|
|
1748
|
+
scopeStack.push({ names: index === 0 && !declarationsBelongToCurrentScope ? declarations : [] });
|
|
1749
|
+
}
|
|
1750
|
+
if (
|
|
1751
|
+
openingCount === 0 &&
|
|
1752
|
+
declarations.length > 0 &&
|
|
1753
|
+
!declarationsBelongToCurrentScope &&
|
|
1754
|
+
!isUnbracedForDeclarationLine(line)
|
|
1755
|
+
) {
|
|
1756
|
+
const currentScope = scopeStack[scopeStack.length - 1];
|
|
1757
|
+
if (currentScope) {
|
|
1758
|
+
for (const name of declarations) {
|
|
1759
|
+
currentScope.names.push(name);
|
|
1760
|
+
}
|
|
1761
|
+
}
|
|
1762
|
+
}
|
|
1763
|
+
for (let index = 0; index < closingCount; index += 1) {
|
|
1764
|
+
if (scopeStack.length > 0) scopeStack.pop();
|
|
1765
|
+
}
|
|
1766
|
+
methodDepth += braceCounts.delta;
|
|
1767
|
+
if (methodDepth <= 0) {
|
|
1768
|
+
methodDepth = 0;
|
|
1769
|
+
scopeStack.length = 0;
|
|
1770
|
+
pendingScalarDeclarationWrites = null;
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
|
|
1774
|
+
return output.join('\n');
|
|
1775
|
+
}
|
|
1776
|
+
|
|
1777
|
+
function collectJavaObjectDeclarations(line) {
|
|
1778
|
+
const names = [];
|
|
1779
|
+
const declarationPattern =
|
|
1780
|
+
/\b([A-Z][A-Za-z0-9_]*)\s+([A-Za-z_][A-Za-z0-9_]*)\s*=\s*new\s+\1\s*\(/g;
|
|
1781
|
+
for (const match of line.matchAll(declarationPattern)) {
|
|
1782
|
+
if (match[2]) names.push(match[2]);
|
|
1783
|
+
}
|
|
1784
|
+
return names;
|
|
1785
|
+
}
|
|
1786
|
+
|
|
1787
|
+
function rewriteJavaObjectFieldReads(expression, objectNames, lineNumber) {
|
|
1788
|
+
let output = expression;
|
|
1789
|
+
for (const name of objectNames) {
|
|
1790
|
+
const fieldPattern = new RegExp(`\\b${escapeRegExp(name)}\\.([A-Za-z_][A-Za-z0-9_]*)\\b`, 'g');
|
|
1791
|
+
output = output.replace(fieldPattern, (match, field, offset, fullSource) => {
|
|
1792
|
+
const marker = fullSource.lastIndexOf('TraceHooks.', offset);
|
|
1793
|
+
const delimiter = Math.max(fullSource.lastIndexOf(';', offset), fullSource.lastIndexOf('\n', offset));
|
|
1794
|
+
if (marker > delimiter) return match;
|
|
1795
|
+
const nextChar = fullSource[offset + match.length] ?? '';
|
|
1796
|
+
if (nextChar === '(') return match;
|
|
1797
|
+
return `TraceHooks.readObjectFieldAtLine(${lineNumber}, "${name}", "${field}", ${match})`;
|
|
1798
|
+
});
|
|
1799
|
+
}
|
|
1800
|
+
return output;
|
|
1801
|
+
}
|
|
1802
|
+
|
|
1803
|
+
function augmentJavaObjectFieldOperations(source) {
|
|
1804
|
+
const lines = source.split('\n');
|
|
1805
|
+
const methodStack = [];
|
|
1806
|
+
const methodStartPattern =
|
|
1807
|
+
/^(\s*)(?:(?:public|private|protected|static|final|synchronized)\s+)*(?:[A-Za-z_][A-Za-z0-9_<>\[\], ?]*\s+)+([A-Za-z_][A-Za-z0-9_]*)\s*\(([^)]*)\)\s*\{\s*$/;
|
|
1808
|
+
|
|
1809
|
+
return lines.map((line) => {
|
|
1810
|
+
const methodMatch = line.match(methodStartPattern);
|
|
1811
|
+
if (methodMatch) {
|
|
1812
|
+
methodStack.push({
|
|
1813
|
+
depth: 1,
|
|
1814
|
+
currentTraceLine: null,
|
|
1815
|
+
objectNames: new Set(),
|
|
1816
|
+
});
|
|
1817
|
+
return line;
|
|
1818
|
+
}
|
|
1819
|
+
|
|
1820
|
+
const currentMethod = methodStack[methodStack.length - 1];
|
|
1821
|
+
let nextLine = line;
|
|
1822
|
+
if (!currentMethod) return nextLine;
|
|
1823
|
+
|
|
1824
|
+
for (const name of collectJavaObjectDeclarations(line)) {
|
|
1825
|
+
currentMethod.objectNames.add(name);
|
|
1826
|
+
}
|
|
1827
|
+
|
|
1828
|
+
const traceLine = parseNativeTraceLine(line);
|
|
1829
|
+
if (traceLine !== null) currentMethod.currentTraceLine = traceLine;
|
|
1830
|
+
|
|
1831
|
+
const lineNumber = currentMethod.currentTraceLine;
|
|
1832
|
+
if (lineNumber !== null && currentMethod.objectNames.size > 0) {
|
|
1833
|
+
for (const name of currentMethod.objectNames) {
|
|
1834
|
+
const writePattern = new RegExp(`^(\\s*)${escapeRegExp(name)}\\.([A-Za-z_][A-Za-z0-9_]*)\\s*=\\s*(.+);\\s*$`);
|
|
1835
|
+
const writeMatch = nextLine.match(writePattern);
|
|
1836
|
+
if (writeMatch) {
|
|
1837
|
+
const indent = writeMatch[1] ?? '';
|
|
1838
|
+
const field = writeMatch[2];
|
|
1839
|
+
const rhs = writeMatch[3];
|
|
1840
|
+
nextLine = `${indent}{ ${name}.${field} = ${rhs}; TraceHooks.emitFieldWriteAtLine(${lineNumber}, "${name}", "${field}", ${name}.${field}); }`;
|
|
1841
|
+
break;
|
|
1842
|
+
}
|
|
1843
|
+
}
|
|
1844
|
+
|
|
1845
|
+
const returnMatch = nextLine.match(/^(\s*)return\s+(.+);\s*$/);
|
|
1846
|
+
if (returnMatch) {
|
|
1847
|
+
nextLine = `${returnMatch[1]}return ${rewriteJavaObjectFieldReads(returnMatch[2], currentMethod.objectNames, lineNumber)};`;
|
|
1848
|
+
}
|
|
1849
|
+
}
|
|
1850
|
+
|
|
1851
|
+
currentMethod.depth += braceDelta(nextLine);
|
|
1852
|
+
while (methodStack.length > 0 && methodStack[methodStack.length - 1].depth <= 0) {
|
|
1853
|
+
methodStack.pop();
|
|
1854
|
+
}
|
|
1855
|
+
return nextLine;
|
|
1856
|
+
}).join('\n');
|
|
1857
|
+
}
|
|
1858
|
+
|
|
1859
|
+
function augmentJavaThrowEvents(source) {
|
|
1860
|
+
const lines = source.split('\n');
|
|
1861
|
+
const methodStack = [];
|
|
1862
|
+
let thrownIndex = 0;
|
|
1863
|
+
const methodStartPattern =
|
|
1864
|
+
/^(\s*)(?:(?:public|private|protected|static|final|synchronized)\s+)*(?:[A-Za-z_][A-Za-z0-9_<>\[\], ?]*\s+)+([A-Za-z_][A-Za-z0-9_]*)\s*\(([^)]*)\)\s*\{\s*$/;
|
|
1865
|
+
|
|
1866
|
+
return lines.map((line) => {
|
|
1867
|
+
const methodMatch = line.match(methodStartPattern);
|
|
1868
|
+
if (methodMatch) {
|
|
1869
|
+
methodStack.push({ depth: 1, currentTraceLine: null });
|
|
1870
|
+
return line;
|
|
1871
|
+
}
|
|
1872
|
+
|
|
1873
|
+
const currentMethod = methodStack[methodStack.length - 1];
|
|
1874
|
+
let nextLine = line;
|
|
1875
|
+
if (!currentMethod) return nextLine;
|
|
1876
|
+
|
|
1877
|
+
const traceLine = parseNativeTraceLine(line);
|
|
1878
|
+
if (traceLine !== null) currentMethod.currentTraceLine = traceLine;
|
|
1879
|
+
|
|
1880
|
+
const throwMatch = nextLine.match(/^(\s*)throw\s+(.+);\s*$/);
|
|
1881
|
+
if (throwMatch && currentMethod.currentTraceLine !== null) {
|
|
1882
|
+
const indent = throwMatch[1] ?? '';
|
|
1883
|
+
const tempName = `__tracecodeThrown${thrownIndex++}`;
|
|
1884
|
+
const expression = throwMatch[2];
|
|
1885
|
+
nextLine = `${indent}{ var ${tempName} = ${expression}; TraceHooks.emitExceptionAtLine(${currentMethod.currentTraceLine}, String.valueOf(${tempName})); throw ${tempName}; }`;
|
|
1886
|
+
}
|
|
1887
|
+
|
|
1888
|
+
currentMethod.depth += braceDelta(nextLine);
|
|
1889
|
+
while (methodStack.length > 0 && methodStack[methodStack.length - 1].depth <= 0) {
|
|
1890
|
+
methodStack.pop();
|
|
1891
|
+
}
|
|
1892
|
+
return nextLine;
|
|
1893
|
+
}).join('\n');
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1896
|
+
function augmentJavaStdoutEvents(source) {
|
|
1897
|
+
const lines = source.split('\n');
|
|
1898
|
+
const methodStack = [];
|
|
1899
|
+
let stdoutIndex = 0;
|
|
1900
|
+
const methodStartPattern =
|
|
1901
|
+
/^(\s*)(?:(?:public|private|protected|static|final|synchronized)\s+)*(?:[A-Za-z_][A-Za-z0-9_<>\[\], ?]*\s+)+([A-Za-z_][A-Za-z0-9_]*)\s*\(([^)]*)\)\s*\{\s*$/;
|
|
1902
|
+
|
|
1903
|
+
return lines.map((line) => {
|
|
1904
|
+
const methodMatch = line.match(methodStartPattern);
|
|
1905
|
+
if (methodMatch) {
|
|
1906
|
+
methodStack.push({ depth: 1, currentTraceLine: null });
|
|
1907
|
+
return line;
|
|
1908
|
+
}
|
|
1909
|
+
|
|
1910
|
+
const currentMethod = methodStack[methodStack.length - 1];
|
|
1911
|
+
let nextLine = line;
|
|
1912
|
+
if (!currentMethod) return nextLine;
|
|
1913
|
+
|
|
1914
|
+
const traceLine = parseNativeTraceLine(line);
|
|
1915
|
+
if (traceLine !== null) currentMethod.currentTraceLine = traceLine;
|
|
1916
|
+
|
|
1917
|
+
const stdoutMatch = nextLine.match(/^(\s*)System\.out\.println\((.+)\);\s*$/);
|
|
1918
|
+
if (stdoutMatch && currentMethod.currentTraceLine !== null) {
|
|
1919
|
+
const indent = stdoutMatch[1] ?? '';
|
|
1920
|
+
const tempName = `__tracecodeStdout${stdoutIndex++}`;
|
|
1921
|
+
const expression = stdoutMatch[2];
|
|
1922
|
+
nextLine = `${indent}{ var ${tempName} = ${expression}; System.out.println(${tempName}); TraceHooks.emitStdoutAtLine(${currentMethod.currentTraceLine}, String.valueOf(${tempName})); }`;
|
|
1923
|
+
}
|
|
1924
|
+
|
|
1925
|
+
currentMethod.depth += braceDelta(nextLine);
|
|
1926
|
+
while (methodStack.length > 0 && methodStack[methodStack.length - 1].depth <= 0) {
|
|
1927
|
+
methodStack.pop();
|
|
1928
|
+
}
|
|
1929
|
+
return nextLine;
|
|
1930
|
+
}).join('\n');
|
|
1931
|
+
}
|
|
1932
|
+
|
|
723
1933
|
function augmentArrayLengthReads(source) {
|
|
724
1934
|
const lines = source.split('\n');
|
|
725
1935
|
const methodStack = [];
|
|
@@ -747,9 +1957,9 @@ function augmentArrayLengthReads(source) {
|
|
|
747
1957
|
currentMethod.arrayNames.add(name);
|
|
748
1958
|
}
|
|
749
1959
|
|
|
750
|
-
const
|
|
751
|
-
if (
|
|
752
|
-
currentMethod.currentTraceLine =
|
|
1960
|
+
const traceLine = parseNativeTraceLine(line);
|
|
1961
|
+
if (traceLine !== null) {
|
|
1962
|
+
currentMethod.currentTraceLine = traceLine;
|
|
753
1963
|
currentMethod.hasTraceEmit = true;
|
|
754
1964
|
}
|
|
755
1965
|
|
|
@@ -801,7 +2011,7 @@ function augmentTraceReturnValueSnapshots(source) {
|
|
|
801
2011
|
const currentMethod = methodStack[methodStack.length - 1];
|
|
802
2012
|
if (currentMethod && currentMethod.returnType !== 'void') {
|
|
803
2013
|
const returnEmitMatch = line.match(
|
|
804
|
-
/^(\s*)TraceHooks\.
|
|
2014
|
+
/^(\s*)TraceHooks\.emitReturnAtLine\((\d+),\s*"([A-Za-z_][A-Za-z0-9_]*)"\);\s*$/
|
|
805
2015
|
);
|
|
806
2016
|
const nextLine = lines[index + 1] ?? '';
|
|
807
2017
|
const returnMatch = nextLine.match(/^(\s*)return\s+(.+);\s*$/);
|
|
@@ -811,7 +2021,7 @@ function augmentTraceReturnValueSnapshots(source) {
|
|
|
811
2021
|
const returnExpression = returnMatch[2].trim();
|
|
812
2022
|
output.push(`${indent}${currentMethod.returnType} ${tempName} = ${returnExpression};`);
|
|
813
2023
|
output.push(
|
|
814
|
-
`${indent}TraceHooks.
|
|
2024
|
+
`${indent}TraceHooks.emitSerializedReturnAtLine(${returnEmitMatch[2]}, "${currentMethod.name}", TraceHooks.serializeResult(${tempName}));`
|
|
815
2025
|
);
|
|
816
2026
|
output.push(`${returnMatch[1] ?? indent}return ${tempName};`);
|
|
817
2027
|
currentMethod.depth += braceDelta(line) + braceDelta(nextLine);
|
|
@@ -888,24 +2098,54 @@ function isTopLevelMethodStart(line) {
|
|
|
888
2098
|
return /^(?:public\s+|private\s+|protected\s+)?(?:static\s+)?(?:[\w<>\[\], ?]+\s+)+[A-Za-z_][A-Za-z0-9_]*\s*\([^;]*\)\s*\{/.test(trimmed);
|
|
889
2099
|
}
|
|
890
2100
|
|
|
891
|
-
function
|
|
892
|
-
|
|
2101
|
+
function isTopLevelTypeStart(line) {
|
|
2102
|
+
const trimmed = line.trim();
|
|
2103
|
+
return /^(?:public\s+|private\s+|protected\s+)?(?:static\s+)?(?:final\s+|abstract\s+)?(?:class|interface|enum|record)\s+[A-Za-z_][A-Za-z0-9_]*\b/.test(trimmed);
|
|
2104
|
+
}
|
|
2105
|
+
|
|
2106
|
+
function isTopLevelMemberStart(line) {
|
|
2107
|
+
return isTopLevelMethodStart(line) || isTopLevelTypeStart(line);
|
|
2108
|
+
}
|
|
2109
|
+
|
|
2110
|
+
function javaBraceCounts(line) {
|
|
2111
|
+
let open = 0;
|
|
2112
|
+
let close = 0;
|
|
893
2113
|
let quote = null;
|
|
2114
|
+
let escaped = false;
|
|
894
2115
|
for (let index = 0; index < line.length; index += 1) {
|
|
895
2116
|
const ch = line[index];
|
|
896
|
-
const
|
|
2117
|
+
const next = line[index + 1] ?? '';
|
|
2118
|
+
if (escaped) {
|
|
2119
|
+
escaped = false;
|
|
2120
|
+
continue;
|
|
2121
|
+
}
|
|
897
2122
|
if (quote) {
|
|
898
|
-
if (ch ===
|
|
2123
|
+
if (ch === '\\') {
|
|
2124
|
+
escaped = true;
|
|
2125
|
+
continue;
|
|
2126
|
+
}
|
|
2127
|
+
if (ch === quote) quote = null;
|
|
2128
|
+
continue;
|
|
2129
|
+
}
|
|
2130
|
+
if (ch === '/' && next === '/') break;
|
|
2131
|
+
if (ch === '/' && next === '*') {
|
|
2132
|
+
const end = line.indexOf('*/', index + 2);
|
|
2133
|
+
if (end === -1) break;
|
|
2134
|
+
index = end + 1;
|
|
899
2135
|
continue;
|
|
900
2136
|
}
|
|
901
2137
|
if (ch === '"' || ch === "'") {
|
|
902
2138
|
quote = ch;
|
|
903
2139
|
continue;
|
|
904
2140
|
}
|
|
905
|
-
if (ch === '{')
|
|
906
|
-
if (ch === '}')
|
|
2141
|
+
if (ch === '{') open += 1;
|
|
2142
|
+
if (ch === '}') close += 1;
|
|
907
2143
|
}
|
|
908
|
-
return delta;
|
|
2144
|
+
return { open, close, delta: open - close };
|
|
2145
|
+
}
|
|
2146
|
+
|
|
2147
|
+
function braceDelta(line) {
|
|
2148
|
+
return javaBraceCounts(line).delta;
|
|
909
2149
|
}
|
|
910
2150
|
|
|
911
2151
|
function splitScriptMembersAndStatements(lines) {
|
|
@@ -915,7 +2155,7 @@ function splitScriptMembersAndStatements(lines) {
|
|
|
915
2155
|
for (let index = 0; index < lines.length; index += 1) {
|
|
916
2156
|
const entry = lines[index];
|
|
917
2157
|
const line = typeof entry === 'string' ? entry : entry.line;
|
|
918
|
-
if (statementDepth !== 0 || !
|
|
2158
|
+
if (statementDepth !== 0 || !isTopLevelMemberStart(line)) {
|
|
919
2159
|
statementLines.push(entry);
|
|
920
2160
|
statementDepth += braceDelta(line);
|
|
921
2161
|
if (statementDepth < 0) statementDepth = 0;
|
|
@@ -1040,65 +2280,226 @@ function normalizeJavaRequest(payload) {
|
|
|
1040
2280
|
};
|
|
1041
2281
|
}
|
|
1042
2282
|
|
|
2283
|
+
if (payload.executionStyle === 'solution-method') {
|
|
2284
|
+
return {
|
|
2285
|
+
...payload,
|
|
2286
|
+
sourceText: payload.code,
|
|
2287
|
+
code: wrapSingleStatementLoopBodies(payload.code),
|
|
2288
|
+
};
|
|
2289
|
+
}
|
|
2290
|
+
|
|
2291
|
+
if (payload.executionStyle === 'ops-class') {
|
|
2292
|
+
return {
|
|
2293
|
+
...payload,
|
|
2294
|
+
sourceText: payload.code,
|
|
2295
|
+
code: wrapSingleStatementLoopBodies(payload.code),
|
|
2296
|
+
};
|
|
2297
|
+
}
|
|
2298
|
+
|
|
1043
2299
|
if (payload.executionStyle !== 'function') {
|
|
1044
2300
|
return payload;
|
|
1045
2301
|
}
|
|
1046
2302
|
|
|
1047
2303
|
return {
|
|
1048
2304
|
...payload,
|
|
2305
|
+
sourceText: payload.code,
|
|
1049
2306
|
code: normalizeFunctionSource(payload.code),
|
|
1050
2307
|
executionStyle: 'solution-method',
|
|
1051
2308
|
};
|
|
1052
2309
|
}
|
|
1053
2310
|
|
|
1054
|
-
function
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
2311
|
+
function stableJson(value) {
|
|
2312
|
+
if (Array.isArray(value)) return `[${value.map(stableJson).join(',')}]`;
|
|
2313
|
+
if (value && typeof value === 'object') {
|
|
2314
|
+
return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${stableJson(value[key])}`).join(',')}}`;
|
|
2315
|
+
}
|
|
2316
|
+
return JSON.stringify(value);
|
|
2317
|
+
}
|
|
2318
|
+
|
|
2319
|
+
function stableHash(value) {
|
|
2320
|
+
const source = typeof value === 'string' ? value : stableJson(value);
|
|
2321
|
+
let hashA = 0x811c9dc5;
|
|
2322
|
+
let hashB = 0x9e3779b9;
|
|
2323
|
+
for (let index = 0; index < source.length; index += 1) {
|
|
2324
|
+
const code = source.charCodeAt(index);
|
|
2325
|
+
hashA ^= code;
|
|
2326
|
+
hashA = Math.imul(hashA, 0x01000193) >>> 0;
|
|
2327
|
+
hashB ^= code + index;
|
|
2328
|
+
hashB = Math.imul(hashB, 0x85ebca6b) >>> 0;
|
|
2329
|
+
}
|
|
2330
|
+
return `${hashA.toString(36)}${hashB.toString(36)}`;
|
|
2331
|
+
}
|
|
2332
|
+
|
|
2333
|
+
function dynamicInputEntriesForPayload(payload, compileId) {
|
|
2334
|
+
if (payload.executionStyle === 'ops-class') return [];
|
|
2335
|
+
const parameters = extractMethodParameters(payload.code, payload.functionName);
|
|
2336
|
+
const invocationKeys = parameters.length > 0 ? parameters.map((parameter) => parameter.name) : Object.keys(payload.inputs ?? {});
|
|
2337
|
+
const entries = [];
|
|
2338
|
+
for (let index = 0; index < invocationKeys.length; index += 1) {
|
|
2339
|
+
const key = invocationKeys[index];
|
|
2340
|
+
const parameter = parameters[index];
|
|
2341
|
+
if (!parameter) continue;
|
|
2342
|
+
const value = inputValueForParameter(payload.inputs ?? {}, key, index);
|
|
2343
|
+
if (!isDynamicJavaInputType(parameter.type, value)) continue;
|
|
2344
|
+
const safeName = String(key).replace(/[^A-Za-z0-9_$-]/g, '_');
|
|
2345
|
+
entries.push({
|
|
2346
|
+
key,
|
|
2347
|
+
index,
|
|
2348
|
+
type: parameter.type,
|
|
2349
|
+
value,
|
|
2350
|
+
path: `${DYNAMIC_INPUT_PREFIX}-${compileId}-${index}-${safeName}.json`,
|
|
1074
2351
|
});
|
|
1075
|
-
|
|
1076
|
-
return `public class Exports {
|
|
1077
|
-
${helperMethods}
|
|
1078
|
-
|
|
1079
|
-
public static String run() {
|
|
1080
|
-
${lines.join('\n')}
|
|
1081
|
-
return TraceHooks.serializeResult(out);
|
|
1082
2352
|
}
|
|
2353
|
+
return entries;
|
|
1083
2354
|
}
|
|
1084
|
-
`;
|
|
1085
|
-
}
|
|
1086
2355
|
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
2356
|
+
function buildJavaCompileSeed(payload, compileMode = 'trace') {
|
|
2357
|
+
if (payload.executionStyle === 'ops-class') {
|
|
2358
|
+
return {
|
|
2359
|
+
compileMode,
|
|
2360
|
+
code: payload.code,
|
|
2361
|
+
functionName: payload.functionName,
|
|
2362
|
+
executionStyle: payload.executionStyle,
|
|
2363
|
+
inputs: payload.inputs ?? {},
|
|
2364
|
+
};
|
|
2365
|
+
}
|
|
1094
2366
|
|
|
1095
|
-
|
|
1096
|
-
|
|
2367
|
+
const parameters = extractMethodParameters(payload.code, payload.functionName);
|
|
2368
|
+
const invocationKeys = parameters.length > 0 ? parameters.map((parameter) => parameter.name) : Object.keys(payload.inputs ?? {});
|
|
2369
|
+
const inputs = {};
|
|
2370
|
+
for (let index = 0; index < invocationKeys.length; index += 1) {
|
|
2371
|
+
const key = invocationKeys[index];
|
|
2372
|
+
const parameter = parameters[index];
|
|
2373
|
+
const value = inputValueForParameter(payload.inputs ?? {}, key, index);
|
|
2374
|
+
inputs[key] = parameter && isDynamicJavaInputType(parameter.type, value)
|
|
2375
|
+
? { mode: 'dynamic-json-file', type: normalizedJavaInputType(parameter.type) }
|
|
2376
|
+
: { mode: 'literal', value };
|
|
2377
|
+
}
|
|
2378
|
+
|
|
2379
|
+
return {
|
|
2380
|
+
compileMode,
|
|
2381
|
+
code: payload.code,
|
|
2382
|
+
functionName: payload.functionName,
|
|
2383
|
+
executionStyle: payload.executionStyle,
|
|
2384
|
+
scriptMode: payload.scriptMode === true,
|
|
2385
|
+
inputs,
|
|
2386
|
+
};
|
|
2387
|
+
}
|
|
2388
|
+
|
|
2389
|
+
function buildJavaCompileId(payload, compileMode = 'trace') {
|
|
2390
|
+
return stableHash(buildJavaCompileSeed(payload, compileMode));
|
|
2391
|
+
}
|
|
2392
|
+
|
|
2393
|
+
function buildJavaBatchCompileId(payload, inputBatch) {
|
|
2394
|
+
return stableHash({
|
|
2395
|
+
compileMode: 'execute-batch',
|
|
2396
|
+
cases: inputBatch.map((inputs) => buildJavaCompileSeed({ ...payload, inputs }, 'execute-batch-case')),
|
|
2397
|
+
});
|
|
2398
|
+
}
|
|
2399
|
+
|
|
2400
|
+
async function writeDynamicInputFiles(dynamicInputs) {
|
|
2401
|
+
for (const input of dynamicInputs) {
|
|
2402
|
+
await self.cheerpOSAddStringFile(input.path, JSON.stringify(input.value));
|
|
2403
|
+
}
|
|
2404
|
+
}
|
|
2405
|
+
|
|
2406
|
+
function dynamicInputByKey(dynamicInputs) {
|
|
2407
|
+
const out = new Map();
|
|
2408
|
+
for (const input of dynamicInputs) out.set(input.key, input);
|
|
2409
|
+
return out;
|
|
2410
|
+
}
|
|
2411
|
+
|
|
2412
|
+
function buildExportsSource(source, functionName, executionStyle, input, options = {}) {
|
|
2413
|
+
const features = {
|
|
2414
|
+
...detectFeatures(source, input, options),
|
|
2415
|
+
skipInputMaterializers: options.scriptMode === true,
|
|
2416
|
+
};
|
|
2417
|
+
const helperMethods = buildHelperMethods(features);
|
|
2418
|
+
const nodePreludeSource = buildNodePreludeSource(source, options);
|
|
2419
|
+
const dynamicInputsByKey = dynamicInputByKey(options.dynamicInputs ?? []);
|
|
2420
|
+
|
|
2421
|
+
if (executionStyle === 'ops-class') {
|
|
2422
|
+
const operations = Array.isArray(input.operations) ? input.operations : [];
|
|
2423
|
+
const argumentsList = Array.isArray(input.arguments) ? input.arguments : [];
|
|
2424
|
+
const lines = [' java.util.List<Object> out = new java.util.ArrayList<>();'];
|
|
2425
|
+
const firstOperation = operations.length > 0 ? String(operations[0]) : null;
|
|
2426
|
+
const hasConstructorOperation =
|
|
2427
|
+
firstOperation === functionName ||
|
|
2428
|
+
firstOperation === '__init__' ||
|
|
2429
|
+
firstOperation === 'init' ||
|
|
2430
|
+
(firstOperation !== null && extractMethodReturnType(source, firstOperation) === null);
|
|
2431
|
+
const constructorParameters = extractMethodParametersForArguments(source, functionName, argumentsList[0]);
|
|
2432
|
+
const constructorArgs = hasConstructorOperation
|
|
2433
|
+
? inputArgumentsForParameters(argumentsList[0], constructorParameters)
|
|
2434
|
+
: [];
|
|
2435
|
+
const constructorInvocationArgs = constructorArgs
|
|
2436
|
+
.map((arg, argIndex) => buildJavaExpression(arg, constructorParameters[argIndex]?.type))
|
|
2437
|
+
.join(', ');
|
|
2438
|
+
lines.push(` ${functionName} instance = new ${functionName}(${constructorInvocationArgs});`);
|
|
2439
|
+
if (hasConstructorOperation) {
|
|
2440
|
+
lines.push(' out.add(null);');
|
|
2441
|
+
}
|
|
2442
|
+
|
|
2443
|
+
operations.forEach((operation, index) => {
|
|
2444
|
+
if (hasConstructorOperation && index === 0) {
|
|
2445
|
+
return;
|
|
2446
|
+
}
|
|
2447
|
+
const operationName = String(operation);
|
|
2448
|
+
const parameters = extractMethodParametersForArguments(source, operationName, argumentsList[index]);
|
|
2449
|
+
const args = inputArgumentsForParameters(argumentsList[index], parameters);
|
|
2450
|
+
const invocationArgs = args.map((arg, argIndex) => buildJavaExpression(arg, parameters[argIndex]?.type)).join(', ');
|
|
2451
|
+
const returnType = extractMethodReturnType(source, operationName);
|
|
2452
|
+
if (returnType === 'void') {
|
|
2453
|
+
lines.push(` instance.${operationName}(${invocationArgs});`);
|
|
2454
|
+
lines.push(' out.add(null);');
|
|
2455
|
+
} else {
|
|
2456
|
+
lines.push(` out.add(instance.${operationName}(${invocationArgs}));`);
|
|
2457
|
+
}
|
|
2458
|
+
});
|
|
2459
|
+
|
|
2460
|
+
return `${nodePreludeSource}public class Exports {
|
|
2461
|
+
${helperMethods}
|
|
2462
|
+
|
|
2463
|
+
public static String run() {
|
|
2464
|
+
${lines.join('\n')}
|
|
2465
|
+
return TraceHooks.serializeOutputResult(out);
|
|
2466
|
+
}
|
|
2467
|
+
}
|
|
2468
|
+
`;
|
|
2469
|
+
}
|
|
2470
|
+
|
|
2471
|
+
const parameters = extractMethodParameters(source, functionName);
|
|
2472
|
+
const returnType = extractMethodReturnType(source, functionName);
|
|
2473
|
+
const invocationKeys = parameters.length > 0 ? parameters.map((parameter) => parameter.name) : Object.keys(input);
|
|
2474
|
+
const usedLocalNames = new Set(['solution', ...invocationKeys]);
|
|
2475
|
+
const resultLocalName = uniqueJavaIdentifier('__tracecode_result', usedLocalNames);
|
|
2476
|
+
const materializedArgs = [];
|
|
2477
|
+
for (let index = 0; index < invocationKeys.length; index += 1) {
|
|
2478
|
+
const key = invocationKeys[index];
|
|
2479
|
+
const parameter = parameters[index];
|
|
2480
|
+
const type = parameter ? parameter.type : 'Object';
|
|
2481
|
+
const value = inputValueForParameter(input, key, index);
|
|
2482
|
+
const dynamicInput = dynamicInputsByKey.get(key);
|
|
2483
|
+
const expression = dynamicInput
|
|
2484
|
+
? dynamicJavaInputExpression(type, dynamicInput.path)
|
|
2485
|
+
: buildJavaExpression(value, type);
|
|
2486
|
+
if (dynamicInput && !expression) {
|
|
2487
|
+
throw new Error(`Unsupported dynamic Java input type: ${type}`);
|
|
2488
|
+
}
|
|
2489
|
+
materializedArgs.push(` ${type} ${key} = ${expression};`);
|
|
2490
|
+
}
|
|
2491
|
+
const invocationArgs = invocationKeys.join(', ');
|
|
2492
|
+
const invocationLine = returnType === 'void'
|
|
2493
|
+
? ` solution.${functionName}(${invocationArgs});\n return TraceHooks.serializeOutputResult(null);`
|
|
2494
|
+
: ` ${returnType || 'Object'} ${resultLocalName} = solution.${functionName}(${invocationArgs});\n return TraceHooks.serializeOutputResult(${resultLocalName});`;
|
|
2495
|
+
|
|
2496
|
+
return `${nodePreludeSource}public class Exports {
|
|
2497
|
+
${helperMethods}
|
|
1097
2498
|
|
|
1098
2499
|
public static String run() {
|
|
1099
2500
|
Solution solution = new Solution();
|
|
1100
|
-
|
|
1101
|
-
|
|
2501
|
+
${materializedArgs.join('\n')}
|
|
2502
|
+
${invocationLine}
|
|
1102
2503
|
}
|
|
1103
2504
|
}
|
|
1104
2505
|
`;
|
|
@@ -1112,6 +2513,20 @@ function buildExportsClassName(messageId) {
|
|
|
1112
2513
|
return `Exports${String(messageId).replace(/[^A-Za-z0-9]/g, '')}`;
|
|
1113
2514
|
}
|
|
1114
2515
|
|
|
2516
|
+
function normalizeJavaSerializedOutput(value) {
|
|
2517
|
+
if (Array.isArray(value)) {
|
|
2518
|
+
return value.map((item) => normalizeJavaSerializedOutput(item));
|
|
2519
|
+
}
|
|
2520
|
+
if (!value || typeof value !== 'object') return value;
|
|
2521
|
+
const output = {};
|
|
2522
|
+
for (const [key, child] of Object.entries(value)) {
|
|
2523
|
+
if (key === '__class__') continue;
|
|
2524
|
+
if (value.__type__ === 'NestedInteger' && key === 'value' && child == null) continue;
|
|
2525
|
+
output[key] = normalizeJavaSerializedOutput(child);
|
|
2526
|
+
}
|
|
2527
|
+
return output;
|
|
2528
|
+
}
|
|
2529
|
+
|
|
1115
2530
|
async function ensureReady() {
|
|
1116
2531
|
if (!workerReadyPromise) {
|
|
1117
2532
|
workerReadyPromise = (async () => {
|
|
@@ -1131,7 +2546,6 @@ async function ensureReady() {
|
|
|
1131
2546
|
})();
|
|
1132
2547
|
}
|
|
1133
2548
|
await workerReadyPromise;
|
|
1134
|
-
resetIdleTimer();
|
|
1135
2549
|
}
|
|
1136
2550
|
|
|
1137
2551
|
async function getHelperLibrary() {
|
|
@@ -1145,7 +2559,7 @@ async function getCompileLibraryClass() {
|
|
|
1145
2559
|
if (!compileLibraryClassPromise) {
|
|
1146
2560
|
compileLibraryClassPromise = (async () => {
|
|
1147
2561
|
const library = await getHelperLibrary();
|
|
1148
|
-
return library.
|
|
2562
|
+
return library.tracecode.browser.BrowserCompileAndTraceLibrary;
|
|
1149
2563
|
})();
|
|
1150
2564
|
}
|
|
1151
2565
|
return compileLibraryClassPromise;
|
|
@@ -1161,45 +2575,87 @@ async function getRewriteLibraryClass() {
|
|
|
1161
2575
|
return rewriteLibraryClassPromise;
|
|
1162
2576
|
}
|
|
1163
2577
|
|
|
1164
|
-
async function
|
|
1165
|
-
if (!
|
|
1166
|
-
|
|
2578
|
+
async function warmRunHost() {
|
|
2579
|
+
if (!runWarmupPromise) {
|
|
2580
|
+
runWarmupPromise = (async () => {
|
|
2581
|
+
const totalStart = performance.now();
|
|
1167
2582
|
const libraryClass = await getCompileLibraryClass();
|
|
1168
|
-
const
|
|
1169
|
-
const
|
|
1170
|
-
const
|
|
2583
|
+
const runSourcePath = '/str/ExportsTracecodeRunWarmup.java';
|
|
2584
|
+
const runClassesDir = '/files/java-worker/__warm_run__/classes';
|
|
2585
|
+
const runWarmupSource = `
|
|
1171
2586
|
package harness.user.warmup;
|
|
1172
2587
|
|
|
1173
|
-
|
|
2588
|
+
import tracecode.user.TraceHooks;
|
|
2589
|
+
|
|
2590
|
+
class Solution {
|
|
2591
|
+
int add(int a, int b) {
|
|
2592
|
+
return a + b;
|
|
2593
|
+
}
|
|
2594
|
+
}
|
|
2595
|
+
|
|
2596
|
+
public class ExportsTracecodeRunWarmup {
|
|
1174
2597
|
public static String run() {
|
|
1175
|
-
|
|
2598
|
+
Solution solution = new Solution();
|
|
2599
|
+
int a = 1;
|
|
2600
|
+
int b = 2;
|
|
2601
|
+
int result = solution.add(a, b);
|
|
2602
|
+
return TraceHooks.serializeOutputResult(result);
|
|
1176
2603
|
}
|
|
1177
2604
|
}
|
|
1178
2605
|
`;
|
|
1179
|
-
await self.cheerpOSAddStringFile(
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
2606
|
+
await self.cheerpOSAddStringFile(runSourcePath, runWarmupSource);
|
|
2607
|
+
const hostCallStart = performance.now();
|
|
2608
|
+
const reportText = await libraryClass.compileAndRun(
|
|
2609
|
+
runSourcePath,
|
|
2610
|
+
runClassesDir,
|
|
2611
|
+
'harness.user.warmup.ExportsTracecodeRunWarmup',
|
|
1184
2612
|
HELPER_JAR_PATH,
|
|
1185
|
-
|
|
2613
|
+
DEFAULT_EXECUTE_COMPILER_DEBUG_PROFILE
|
|
1186
2614
|
);
|
|
2615
|
+
const hostCallEnd = performance.now();
|
|
2616
|
+
const report = JSON.parse(reportText);
|
|
2617
|
+
const totalEnd = performance.now();
|
|
2618
|
+
if (report.success !== true) {
|
|
2619
|
+
throw new Error(report.runtimeError || report.compilerStderr || report.compilerStdout || 'Java warmup failed');
|
|
2620
|
+
}
|
|
2621
|
+
return {
|
|
2622
|
+
success: true,
|
|
2623
|
+
loadTimeMs: Math.round(totalEnd - totalStart),
|
|
2624
|
+
timings: {
|
|
2625
|
+
totalMs: totalEnd - totalStart,
|
|
2626
|
+
hostCallMs: hostCallEnd - hostCallStart,
|
|
2627
|
+
compileMs: report.compileTimeMs ?? 0,
|
|
2628
|
+
classLoadMs: report.classLoadTimeMs ?? 0,
|
|
2629
|
+
runMs: report.runTimeMs ?? 0,
|
|
2630
|
+
compileCacheHit: report.compileCacheHit ?? false,
|
|
2631
|
+
},
|
|
2632
|
+
};
|
|
1187
2633
|
})();
|
|
1188
2634
|
}
|
|
1189
|
-
|
|
2635
|
+
try {
|
|
2636
|
+
return await runWarmupPromise;
|
|
2637
|
+
} catch (error) {
|
|
2638
|
+
runWarmupPromise = null;
|
|
2639
|
+
throw error;
|
|
2640
|
+
}
|
|
1190
2641
|
}
|
|
1191
2642
|
|
|
1192
|
-
async function rewriteSource(payload,
|
|
2643
|
+
async function rewriteSource(payload, compileId, dynamicInputs) {
|
|
1193
2644
|
const rewriteLibraryClass = await getRewriteLibraryClass();
|
|
1194
|
-
const exportsClassName = buildExportsClassName(
|
|
1195
|
-
const packageName = buildPackageName(
|
|
2645
|
+
const exportsClassName = buildExportsClassName(compileId);
|
|
2646
|
+
const packageName = buildPackageName(compileId);
|
|
1196
2647
|
const exportsSource = buildExportsSource(
|
|
1197
2648
|
payload.code,
|
|
1198
2649
|
payload.functionName,
|
|
1199
2650
|
payload.executionStyle,
|
|
1200
|
-
payload.inputs ?? {}
|
|
2651
|
+
payload.inputs ?? {},
|
|
2652
|
+
{
|
|
2653
|
+
dynamicInputs,
|
|
2654
|
+
hasDynamicInputs: dynamicInputs.length > 0,
|
|
2655
|
+
scriptMode: payload.scriptMode === true,
|
|
2656
|
+
}
|
|
1201
2657
|
);
|
|
1202
|
-
|
|
2658
|
+
const rewrittenSource = await rewriteLibraryClass.rewriteSource(
|
|
1203
2659
|
payload.code,
|
|
1204
2660
|
payload.executionStyle,
|
|
1205
2661
|
payload.functionName,
|
|
@@ -1207,13 +2663,106 @@ async function rewriteSource(payload, requestId) {
|
|
|
1207
2663
|
exportsClassName,
|
|
1208
2664
|
packageName
|
|
1209
2665
|
);
|
|
2666
|
+
return addJavaDefaultImportsToPackagedSource(rewrittenSource);
|
|
1210
2667
|
}
|
|
1211
2668
|
|
|
1212
2669
|
function normalizePublicClassDeclarations(source) {
|
|
1213
|
-
return String(source).replace(
|
|
2670
|
+
return String(source).replace(/^([ \t]*)public\s+class\s+/gm, '$1class ');
|
|
1214
2671
|
}
|
|
1215
2672
|
|
|
1216
|
-
|
|
2673
|
+
function buildPlainRunnableSource(payload, compileId, dynamicInputs) {
|
|
2674
|
+
const exportsClassName = buildExportsClassName(compileId);
|
|
2675
|
+
const packageName = buildPackageName(compileId);
|
|
2676
|
+
const exportsSource = buildExportsSource(
|
|
2677
|
+
payload.code,
|
|
2678
|
+
payload.functionName,
|
|
2679
|
+
payload.executionStyle,
|
|
2680
|
+
payload.inputs ?? {},
|
|
2681
|
+
{
|
|
2682
|
+
dynamicInputs,
|
|
2683
|
+
hasDynamicInputs: dynamicInputs.length > 0,
|
|
2684
|
+
scriptMode: payload.scriptMode === true,
|
|
2685
|
+
}
|
|
2686
|
+
).replaceAll(/\bpublic class Exports\b/g, `public class ${exportsClassName}`);
|
|
2687
|
+
|
|
2688
|
+
return [
|
|
2689
|
+
`package ${packageName};`,
|
|
2690
|
+
'',
|
|
2691
|
+
'import tracecode.user.TraceHooks;',
|
|
2692
|
+
javaDefaultImportsBlock(),
|
|
2693
|
+
'',
|
|
2694
|
+
normalizePublicClassDeclarations(payload.code).trim(),
|
|
2695
|
+
'',
|
|
2696
|
+
exportsSource.trim(),
|
|
2697
|
+
'',
|
|
2698
|
+
].join('\n');
|
|
2699
|
+
}
|
|
2700
|
+
|
|
2701
|
+
function buildBatchRunnableSource(payload, compileId, inputBatch, dynamicInputBatch) {
|
|
2702
|
+
const exportsClassName = buildExportsClassName(compileId);
|
|
2703
|
+
const packageName = buildPackageName(compileId);
|
|
2704
|
+
const entryClasses = [];
|
|
2705
|
+
const sourceParts = [
|
|
2706
|
+
`package ${packageName};`,
|
|
2707
|
+
'',
|
|
2708
|
+
'import tracecode.user.TraceHooks;',
|
|
2709
|
+
javaDefaultImportsBlock(),
|
|
2710
|
+
'',
|
|
2711
|
+
normalizePublicClassDeclarations(payload.code).trim(),
|
|
2712
|
+
'',
|
|
2713
|
+
];
|
|
2714
|
+
|
|
2715
|
+
for (let index = 0; index < inputBatch.length; index += 1) {
|
|
2716
|
+
const className = index === 0 ? exportsClassName : `${exportsClassName}Case${index}`;
|
|
2717
|
+
const dynamicInputs = dynamicInputBatch[index] ?? [];
|
|
2718
|
+
const exportsSource = buildExportsSource(
|
|
2719
|
+
payload.code,
|
|
2720
|
+
payload.functionName,
|
|
2721
|
+
payload.executionStyle,
|
|
2722
|
+
inputBatch[index] ?? {},
|
|
2723
|
+
{
|
|
2724
|
+
dynamicInputs,
|
|
2725
|
+
hasDynamicInputs: dynamicInputs.length > 0,
|
|
2726
|
+
scriptMode: payload.scriptMode === true,
|
|
2727
|
+
}
|
|
2728
|
+
).replaceAll(
|
|
2729
|
+
/\bpublic class Exports\b/g,
|
|
2730
|
+
`${index === 0 ? 'public class' : 'class'} ${className}`
|
|
2731
|
+
);
|
|
2732
|
+
entryClasses.push(`${packageName}.${className}`);
|
|
2733
|
+
sourceParts.push(exportsSource.trim(), '');
|
|
2734
|
+
}
|
|
2735
|
+
|
|
2736
|
+
return {
|
|
2737
|
+
source: sourceParts.join('\n'),
|
|
2738
|
+
entryClasses,
|
|
2739
|
+
};
|
|
2740
|
+
}
|
|
2741
|
+
|
|
2742
|
+
function buildCompileProbeSource(payload, requestId, probeClassName, probePackageName) {
|
|
2743
|
+
const exportsSource = buildExportsSource(
|
|
2744
|
+
payload.code,
|
|
2745
|
+
payload.functionName,
|
|
2746
|
+
payload.executionStyle,
|
|
2747
|
+
payload.inputs ?? {},
|
|
2748
|
+
{
|
|
2749
|
+
scriptMode: payload.scriptMode === true,
|
|
2750
|
+
}
|
|
2751
|
+
).replaceAll(/\bpublic class Exports\b/g, `public class ${probeClassName}`);
|
|
2752
|
+
return [
|
|
2753
|
+
`package ${probePackageName};`,
|
|
2754
|
+
'',
|
|
2755
|
+
'import tracecode.user.TraceHooks;',
|
|
2756
|
+
javaDefaultImportsBlock(),
|
|
2757
|
+
'',
|
|
2758
|
+
normalizePublicClassDeclarations(payload.code).trim(),
|
|
2759
|
+
'',
|
|
2760
|
+
exportsSource.trim(),
|
|
2761
|
+
'',
|
|
2762
|
+
].join('\n');
|
|
2763
|
+
}
|
|
2764
|
+
|
|
2765
|
+
async function collectCompileProbeDiagnostics(payload, requestId, options) {
|
|
1217
2766
|
const probeClassName = buildExportsClassName(`${requestId}RewriteProbe`);
|
|
1218
2767
|
const probePackageName = buildPackageName(`${requestId}RewriteProbe`);
|
|
1219
2768
|
const sourcePath = `/str/${probeClassName}.java`;
|
|
@@ -1232,7 +2781,10 @@ async function collectCompileProbeDiagnostics(source, requestId, options) {
|
|
|
1232
2781
|
}
|
|
1233
2782
|
|
|
1234
2783
|
try {
|
|
1235
|
-
await self.cheerpOSAddStringFile(
|
|
2784
|
+
await self.cheerpOSAddStringFile(
|
|
2785
|
+
sourcePath,
|
|
2786
|
+
buildCompileProbeSource(payload, requestId, probeClassName, probePackageName)
|
|
2787
|
+
);
|
|
1236
2788
|
} catch (error) {
|
|
1237
2789
|
return {
|
|
1238
2790
|
consoleOutput: [],
|
|
@@ -1294,79 +2846,194 @@ async function collectCompileProbeDiagnostics(source, requestId, options) {
|
|
|
1294
2846
|
function normalizeScriptTraceEvents(events, scriptMode, userCodeLineCount, sourceLineMap) {
|
|
1295
2847
|
if (!scriptMode || !Array.isArray(events)) return events;
|
|
1296
2848
|
return events.map((event) => {
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
2849
|
+
if (String(event).startsWith('trace:')) {
|
|
2850
|
+
try {
|
|
2851
|
+
const parsed = JSON.parse(String(event).slice('trace:'.length));
|
|
2852
|
+
if (parsed.function === SCRIPT_METHOD_NAME) parsed.function = '<module>';
|
|
2853
|
+
if (parsed.kind === 'call' && parsed.function === SCRIPT_METHOD_NAME) parsed.function = '<module>';
|
|
2854
|
+
if (parsed.kind === 'return' && parsed.function === SCRIPT_METHOD_NAME) parsed.function = '<module>';
|
|
2855
|
+
if (
|
|
2856
|
+
typeof parsed.line === 'number' &&
|
|
2857
|
+
sourceLineMap &&
|
|
2858
|
+
Object.prototype.hasOwnProperty.call(sourceLineMap, String(parsed.line))
|
|
2859
|
+
) {
|
|
2860
|
+
const mappedLine = Number(sourceLineMap[String(parsed.line)]);
|
|
2861
|
+
if (Number.isFinite(mappedLine) && mappedLine > 0) parsed.line = mappedLine;
|
|
2862
|
+
}
|
|
2863
|
+
if (
|
|
2864
|
+
parsed.kind === 'return' &&
|
|
2865
|
+
parsed.function === '<module>' &&
|
|
2866
|
+
Number.isFinite(userCodeLineCount) &&
|
|
2867
|
+
userCodeLineCount > 0 &&
|
|
2868
|
+
parsed.line > userCodeLineCount
|
|
2869
|
+
) {
|
|
2870
|
+
parsed.line = userCodeLineCount;
|
|
2871
|
+
}
|
|
2872
|
+
return `trace:${JSON.stringify(parsed)}`;
|
|
2873
|
+
} catch {
|
|
2874
|
+
return event;
|
|
1306
2875
|
}
|
|
1307
2876
|
}
|
|
1308
|
-
|
|
1309
|
-
const match = normalizedEvent.match(/^line=(\d+)\s+return\s+<module>$/);
|
|
1310
|
-
if (!match || !Number.isFinite(userCodeLineCount) || userCodeLineCount <= 0) {
|
|
1311
|
-
return normalizedEvent;
|
|
1312
|
-
}
|
|
1313
|
-
const line = Number.parseInt(match[1], 10);
|
|
1314
|
-
if (line <= userCodeLineCount) return normalizedEvent;
|
|
1315
|
-
return `line=${userCodeLineCount} return <module>`;
|
|
2877
|
+
return event;
|
|
1316
2878
|
});
|
|
1317
2879
|
}
|
|
1318
2880
|
|
|
1319
2881
|
function parseTraceLineNumber(event) {
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
2882
|
+
if (String(event).startsWith('trace:')) {
|
|
2883
|
+
try {
|
|
2884
|
+
const parsed = JSON.parse(String(event).slice('trace:'.length));
|
|
2885
|
+
const line = Number(parsed.line);
|
|
2886
|
+
return Number.isFinite(line) && line > 0 ? line : null;
|
|
2887
|
+
} catch {
|
|
2888
|
+
return null;
|
|
2889
|
+
}
|
|
2890
|
+
}
|
|
2891
|
+
return null;
|
|
1324
2892
|
}
|
|
1325
2893
|
|
|
1326
2894
|
function isBareTraceLineEvent(event) {
|
|
1327
|
-
|
|
2895
|
+
if (String(event).startsWith('trace:')) {
|
|
2896
|
+
try {
|
|
2897
|
+
const parsed = JSON.parse(String(event).slice('trace:'.length));
|
|
2898
|
+
return parsed.kind === 'line';
|
|
2899
|
+
} catch {
|
|
2900
|
+
return false;
|
|
2901
|
+
}
|
|
2902
|
+
}
|
|
2903
|
+
return false;
|
|
2904
|
+
}
|
|
2905
|
+
|
|
2906
|
+
function buildBareTraceLineEvent(line, templateEvent) {
|
|
2907
|
+
if (String(templateEvent).startsWith('trace:')) {
|
|
2908
|
+
return `trace:${JSON.stringify({ kind: 'line', line })}`;
|
|
2909
|
+
}
|
|
2910
|
+
return `trace:${JSON.stringify({ kind: 'line', line })}`;
|
|
2911
|
+
}
|
|
2912
|
+
|
|
2913
|
+
function cloneNativeSnapshotEventAtLine(event, line) {
|
|
2914
|
+
if (!String(event).startsWith('trace:')) return null;
|
|
2915
|
+
try {
|
|
2916
|
+
const parsed = JSON.parse(String(event).slice('trace:'.length));
|
|
2917
|
+
if (parsed.kind !== 'snapshot') return null;
|
|
2918
|
+
return `trace:${JSON.stringify({ ...parsed, line })}`;
|
|
2919
|
+
} catch {
|
|
2920
|
+
return null;
|
|
2921
|
+
}
|
|
2922
|
+
}
|
|
2923
|
+
|
|
2924
|
+
function parseNativeSnapshotVariable(event) {
|
|
2925
|
+
if (!String(event).startsWith('trace:')) return null;
|
|
2926
|
+
try {
|
|
2927
|
+
const parsed = JSON.parse(String(event).slice('trace:'.length));
|
|
2928
|
+
if (parsed.kind !== 'snapshot') return null;
|
|
2929
|
+
const variable = parsed.target && typeof parsed.target.variable === 'string'
|
|
2930
|
+
? parsed.target.variable
|
|
2931
|
+
: null;
|
|
2932
|
+
return variable;
|
|
2933
|
+
} catch {
|
|
2934
|
+
return null;
|
|
2935
|
+
}
|
|
2936
|
+
}
|
|
2937
|
+
|
|
2938
|
+
function collectJavaLineDeclarationsForHeaderExpansion(line) {
|
|
2939
|
+
const names = [];
|
|
2940
|
+
const declarationPattern =
|
|
2941
|
+
/\b(?:final\s+)?((?:boolean|byte|char|short|int|long|float|double|String|Object|[A-Za-z_][A-Za-z0-9_<>.?]*(?:\s*<[^,;=(){}:]+>)?)\s*(?:\[\s*\])*)\s+([A-Za-z_][A-Za-z0-9_]*)\s*(?==)/g;
|
|
2942
|
+
const skippedNames = new Set(['class', 'interface', 'enum', 'record', 'return', 'new']);
|
|
2943
|
+
for (const match of line.matchAll(declarationPattern)) {
|
|
2944
|
+
const typeSource = match[1] ?? '';
|
|
2945
|
+
const name = match[2];
|
|
2946
|
+
if (!name || skippedNames.has(name) || name.startsWith('__tracecode')) continue;
|
|
2947
|
+
if (typeSource.includes('[')) continue;
|
|
2948
|
+
names.push(name);
|
|
2949
|
+
}
|
|
2950
|
+
return names;
|
|
2951
|
+
}
|
|
2952
|
+
|
|
2953
|
+
function collectJavaControlHeaderDeclarations(line) {
|
|
2954
|
+
const forMatch = /\bfor\s*\(\s*(?:final\s+)?(?:[A-Za-z_][A-Za-z0-9_<>.?]*(?:\s*<[^;=(){}:]+>)?|\w+(?:\s*\[\s*\])*)\s+([A-Za-z_][A-Za-z0-9_]*)\s*(?:=|:)/.exec(line);
|
|
2955
|
+
return forMatch?.[1] ? [forMatch[1]] : [];
|
|
1328
2956
|
}
|
|
1329
2957
|
|
|
1330
|
-
function
|
|
2958
|
+
function buildControlHeaderInfo(sourceText) {
|
|
1331
2959
|
if (typeof sourceText !== 'string' || sourceText.length === 0) return null;
|
|
1332
2960
|
const lines = sourceText.split(/\r?\n/);
|
|
1333
|
-
const
|
|
2961
|
+
const loopBodyLineToHeader = new Map();
|
|
2962
|
+
const headerLineToExcludedVariables = new Map();
|
|
1334
2963
|
|
|
1335
2964
|
for (let index = 0; index < lines.length; index += 1) {
|
|
1336
2965
|
const line = lines[index];
|
|
1337
|
-
|
|
2966
|
+
const isLoopHeader = /\b(?:for|while)\s*\(/.test(line);
|
|
2967
|
+
const isControlHeader = /\b(?:for|while|if|else\s+if)\s*\(/.test(line);
|
|
2968
|
+
if (!isControlHeader || !line.includes('{')) continue;
|
|
1338
2969
|
|
|
1339
2970
|
for (let bodyIndex = index + 1; bodyIndex < lines.length; bodyIndex += 1) {
|
|
1340
2971
|
const trimmed = lines[bodyIndex].trim();
|
|
1341
2972
|
if (trimmed.length === 0) continue;
|
|
1342
2973
|
if (trimmed.startsWith('}')) break;
|
|
1343
|
-
|
|
2974
|
+
const headerInfo = {
|
|
2975
|
+
line: index + 1,
|
|
2976
|
+
excludedVariables: new Set(collectJavaLineDeclarationsForHeaderExpansion(lines[bodyIndex])),
|
|
2977
|
+
headerVariables: new Set(collectJavaControlHeaderDeclarations(line)),
|
|
2978
|
+
};
|
|
2979
|
+
if (isLoopHeader) loopBodyLineToHeader.set(bodyIndex + 1, headerInfo);
|
|
2980
|
+
headerLineToExcludedVariables.set(index + 1, headerInfo.excludedVariables);
|
|
1344
2981
|
break;
|
|
1345
2982
|
}
|
|
1346
2983
|
}
|
|
1347
2984
|
|
|
1348
|
-
|
|
2985
|
+
if (loopBodyLineToHeader.size === 0 && headerLineToExcludedVariables.size === 0) return null;
|
|
2986
|
+
return { loopBodyLineToHeader, headerLineToExcludedVariables };
|
|
1349
2987
|
}
|
|
1350
2988
|
|
|
1351
2989
|
function expandLoopHeaderTraceEvents(events, sourceText) {
|
|
1352
2990
|
if (!Array.isArray(events) || events.length === 0) return events;
|
|
1353
|
-
const
|
|
1354
|
-
if (!
|
|
2991
|
+
const controlHeaderInfo = buildControlHeaderInfo(sourceText);
|
|
2992
|
+
if (!controlHeaderInfo) return events;
|
|
2993
|
+
const { loopBodyLineToHeader, headerLineToExcludedVariables } = controlHeaderInfo;
|
|
1355
2994
|
|
|
1356
2995
|
const expanded = [];
|
|
1357
|
-
|
|
2996
|
+
const latestSnapshotByVariable = new Map();
|
|
2997
|
+
for (let index = 0; index < events.length; index += 1) {
|
|
2998
|
+
const event = events[index];
|
|
1358
2999
|
const line = parseTraceLineNumber(event);
|
|
1359
|
-
const
|
|
3000
|
+
const snapshotVariable = parseNativeSnapshotVariable(event);
|
|
3001
|
+
if (
|
|
3002
|
+
line !== null &&
|
|
3003
|
+
snapshotVariable &&
|
|
3004
|
+
headerLineToExcludedVariables.get(line)?.has(snapshotVariable)
|
|
3005
|
+
) {
|
|
3006
|
+
continue;
|
|
3007
|
+
}
|
|
3008
|
+
const headerInfo = line === null ? undefined : loopBodyLineToHeader.get(line);
|
|
3009
|
+
const headerLine = headerInfo?.line;
|
|
1360
3010
|
const previousLine = expanded.length > 0 ? parseTraceLineNumber(expanded[expanded.length - 1]) : null;
|
|
1361
3011
|
if (headerLine !== undefined && isBareTraceLineEvent(event) && previousLine !== headerLine) {
|
|
1362
|
-
expanded.push(
|
|
3012
|
+
expanded.push(buildBareTraceLineEvent(headerLine, event));
|
|
3013
|
+
for (const [variable, snapshotEvent] of latestSnapshotByVariable) {
|
|
3014
|
+
if (headerInfo.excludedVariables.has(variable)) continue;
|
|
3015
|
+
const clonedSnapshot = cloneNativeSnapshotEventAtLine(snapshotEvent, headerLine);
|
|
3016
|
+
if (clonedSnapshot) expanded.push(clonedSnapshot);
|
|
3017
|
+
}
|
|
3018
|
+
}
|
|
3019
|
+
if (headerLine !== undefined && isBareTraceLineEvent(event)) {
|
|
3020
|
+
for (let lookahead = index + 1; lookahead < events.length; lookahead += 1) {
|
|
3021
|
+
if (parseTraceLineNumber(events[lookahead]) !== line) break;
|
|
3022
|
+
const variable = parseNativeSnapshotVariable(events[lookahead]);
|
|
3023
|
+
if (!variable || !headerInfo.headerVariables.has(variable)) continue;
|
|
3024
|
+
const clonedSnapshot = cloneNativeSnapshotEventAtLine(events[lookahead], headerLine);
|
|
3025
|
+
if (clonedSnapshot) expanded.push(clonedSnapshot);
|
|
3026
|
+
}
|
|
1363
3027
|
}
|
|
1364
3028
|
expanded.push(event);
|
|
3029
|
+
if (snapshotVariable) {
|
|
3030
|
+
latestSnapshotByVariable.set(snapshotVariable, event);
|
|
3031
|
+
}
|
|
1365
3032
|
}
|
|
1366
3033
|
return expanded;
|
|
1367
3034
|
}
|
|
1368
3035
|
|
|
1369
|
-
|
|
3036
|
+
function normalizeJavaExecutionPayload(payload) {
|
|
1370
3037
|
assertSupportedExecutionStyle(payload.executionStyle);
|
|
1371
3038
|
if (typeof payload.code !== 'string') {
|
|
1372
3039
|
throw new Error('`code` must be a string');
|
|
@@ -1376,32 +3043,58 @@ async function runJavaRequest(payload, requestId) {
|
|
|
1376
3043
|
throw new Error('Java execution requires a non-empty functionName or class entry name.');
|
|
1377
3044
|
}
|
|
1378
3045
|
|
|
1379
|
-
const totalStart = performance.now();
|
|
1380
|
-
const rewriteStart = performance.now();
|
|
1381
|
-
let normalizedPayload;
|
|
1382
3046
|
try {
|
|
1383
|
-
|
|
3047
|
+
return normalizeJavaRequest(payload);
|
|
1384
3048
|
} catch (error) {
|
|
1385
3049
|
throw makeWorkerStageError('request normalization', error);
|
|
1386
3050
|
}
|
|
3051
|
+
}
|
|
3052
|
+
|
|
3053
|
+
function javaReportConsoleOutput(report) {
|
|
3054
|
+
return [report.compilerStdout, report.compilerStderr].filter(
|
|
3055
|
+
(entry) => typeof entry === 'string' && entry.trim().length > 0
|
|
3056
|
+
);
|
|
3057
|
+
}
|
|
3058
|
+
|
|
3059
|
+
function parseJavaReportOutput(output) {
|
|
3060
|
+
return output ? normalizeJavaSerializedOutput(JSON.parse(output)) : undefined;
|
|
3061
|
+
}
|
|
3062
|
+
|
|
3063
|
+
async function runJavaTraceRequest(payload, requestId) {
|
|
3064
|
+
const totalStart = performance.now();
|
|
3065
|
+
const rewriteStart = performance.now();
|
|
3066
|
+
const normalizedPayload = normalizeJavaExecutionPayload(payload);
|
|
3067
|
+
|
|
3068
|
+
const compileId = buildJavaCompileId(normalizedPayload, 'trace');
|
|
3069
|
+
const dynamicInputs = dynamicInputEntriesForPayload(normalizedPayload, compileId);
|
|
1387
3070
|
|
|
1388
3071
|
let rewrittenSource;
|
|
1389
3072
|
try {
|
|
1390
|
-
rewrittenSource = await rewriteSource(normalizedPayload,
|
|
3073
|
+
rewrittenSource = await rewriteSource(normalizedPayload, compileId, dynamicInputs);
|
|
1391
3074
|
rewrittenSource = augmentTraceCallArgumentSnapshots(rewrittenSource);
|
|
1392
3075
|
rewrittenSource = augmentArrayLengthReads(rewrittenSource);
|
|
1393
|
-
rewrittenSource = self.TraceCodeJavaSourceAugmentations.augmentJavaCollectionOperations(
|
|
3076
|
+
rewrittenSource = self.TraceCodeJavaSourceAugmentations.augmentJavaCollectionOperations(
|
|
3077
|
+
rewrittenSource,
|
|
3078
|
+
normalizedPayload.sourceText
|
|
3079
|
+
);
|
|
3080
|
+
rewrittenSource = augmentJavaObjectFieldOperations(rewrittenSource);
|
|
3081
|
+
rewrittenSource = augmentJavaStdoutEvents(rewrittenSource);
|
|
3082
|
+
rewrittenSource = augmentJavaThrowEvents(rewrittenSource);
|
|
3083
|
+
rewrittenSource = augmentJavaLocalSnapshots(rewrittenSource);
|
|
1394
3084
|
rewrittenSource = augmentTraceReturnValueSnapshots(rewrittenSource);
|
|
1395
3085
|
} catch (error) {
|
|
1396
3086
|
const rewriteError = formatWorkerErrorMessage(error);
|
|
1397
|
-
const
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
3087
|
+
const skipDiagnosticProbe = rewriteError.includes('unsupported legacy line= TraceHooks hooks');
|
|
3088
|
+
const diagnosticProbe = skipDiagnosticProbe
|
|
3089
|
+
? { consoleOutput: [], error: null, hostCallMs: 0, diagnosticError: null }
|
|
3090
|
+
: await collectCompileProbeDiagnostics(
|
|
3091
|
+
normalizedPayload,
|
|
3092
|
+
requestId,
|
|
3093
|
+
payload.options
|
|
3094
|
+
);
|
|
1402
3095
|
const totalEnd = performance.now();
|
|
1403
3096
|
const surfacedError =
|
|
1404
|
-
diagnosticProbe.error ??
|
|
3097
|
+
(skipDiagnosticProbe ? null : diagnosticProbe.error) ??
|
|
1405
3098
|
(rewriteError === 'Java syntax error.'
|
|
1406
3099
|
? 'Java syntax error. Check Code Assist for parser details.'
|
|
1407
3100
|
: `Java source rewrite failed: ${rewriteError}`);
|
|
@@ -1421,10 +3114,16 @@ async function runJavaRequest(payload, requestId) {
|
|
|
1421
3114
|
}
|
|
1422
3115
|
const rewriteEnd = performance.now();
|
|
1423
3116
|
|
|
1424
|
-
const exportsClassName = buildExportsClassName(
|
|
1425
|
-
const packageName = buildPackageName(
|
|
3117
|
+
const exportsClassName = buildExportsClassName(compileId);
|
|
3118
|
+
const packageName = buildPackageName(compileId);
|
|
1426
3119
|
const sourcePath = `/str/${exportsClassName}.java`;
|
|
1427
|
-
const classesDir = `/files/java-worker/${
|
|
3120
|
+
const classesDir = `/files/java-worker/${compileId}/classes`;
|
|
3121
|
+
|
|
3122
|
+
try {
|
|
3123
|
+
await writeDynamicInputFiles(dynamicInputs);
|
|
3124
|
+
} catch (error) {
|
|
3125
|
+
throw makeWorkerStageError('dynamic input write', error);
|
|
3126
|
+
}
|
|
1428
3127
|
|
|
1429
3128
|
try {
|
|
1430
3129
|
await self.cheerpOSAddStringFile(sourcePath, rewrittenSource);
|
|
@@ -1462,9 +3161,7 @@ async function runJavaRequest(payload, requestId) {
|
|
|
1462
3161
|
throw makeWorkerStageError('trace report parse', error);
|
|
1463
3162
|
}
|
|
1464
3163
|
const totalEnd = performance.now();
|
|
1465
|
-
const consoleOutput =
|
|
1466
|
-
(entry) => typeof entry === 'string' && entry.trim().length > 0
|
|
1467
|
-
);
|
|
3164
|
+
const consoleOutput = javaReportConsoleOutput(report);
|
|
1468
3165
|
|
|
1469
3166
|
if (report.success !== true) {
|
|
1470
3167
|
return {
|
|
@@ -1503,7 +3200,7 @@ async function runJavaRequest(payload, requestId) {
|
|
|
1503
3200
|
|
|
1504
3201
|
return {
|
|
1505
3202
|
success: true,
|
|
1506
|
-
output:
|
|
3203
|
+
output: parseJavaReportOutput(report.output),
|
|
1507
3204
|
events: expandLoopHeaderTraceEvents(
|
|
1508
3205
|
normalizeScriptTraceEvents(
|
|
1509
3206
|
Array.isArray(report.events) ? report.events : [],
|
|
@@ -1535,6 +3232,226 @@ async function runJavaRequest(payload, requestId) {
|
|
|
1535
3232
|
};
|
|
1536
3233
|
}
|
|
1537
3234
|
|
|
3235
|
+
async function runJavaCodeRequest(payload) {
|
|
3236
|
+
const totalStart = performance.now();
|
|
3237
|
+
const normalizedPayload = normalizeJavaExecutionPayload(payload);
|
|
3238
|
+
const compileId = buildJavaCompileId(normalizedPayload, 'execute');
|
|
3239
|
+
const dynamicInputs = dynamicInputEntriesForPayload(normalizedPayload, compileId);
|
|
3240
|
+
const exportsClassName = buildExportsClassName(compileId);
|
|
3241
|
+
const packageName = buildPackageName(compileId);
|
|
3242
|
+
const sourcePath = `/str/${exportsClassName}.java`;
|
|
3243
|
+
const classesDir = `/files/java-worker/${compileId}/classes`;
|
|
3244
|
+
|
|
3245
|
+
let runnableSource;
|
|
3246
|
+
try {
|
|
3247
|
+
runnableSource = buildPlainRunnableSource(normalizedPayload, compileId, dynamicInputs);
|
|
3248
|
+
} catch (error) {
|
|
3249
|
+
throw makeWorkerStageError('source generation', error);
|
|
3250
|
+
}
|
|
3251
|
+
|
|
3252
|
+
try {
|
|
3253
|
+
await writeDynamicInputFiles(dynamicInputs);
|
|
3254
|
+
} catch (error) {
|
|
3255
|
+
throw makeWorkerStageError('dynamic input write', error);
|
|
3256
|
+
}
|
|
3257
|
+
|
|
3258
|
+
try {
|
|
3259
|
+
await self.cheerpOSAddStringFile(sourcePath, runnableSource);
|
|
3260
|
+
} catch (error) {
|
|
3261
|
+
throw makeWorkerStageError('source file write', error);
|
|
3262
|
+
}
|
|
3263
|
+
|
|
3264
|
+
let compileLibraryClass;
|
|
3265
|
+
try {
|
|
3266
|
+
compileLibraryClass = await getCompileLibraryClass();
|
|
3267
|
+
} catch (error) {
|
|
3268
|
+
throw makeWorkerStageError('compiler bridge load', error);
|
|
3269
|
+
}
|
|
3270
|
+
|
|
3271
|
+
const libraryCallStart = performance.now();
|
|
3272
|
+
let reportText;
|
|
3273
|
+
try {
|
|
3274
|
+
reportText = await compileLibraryClass.compileAndRun(
|
|
3275
|
+
sourcePath,
|
|
3276
|
+
classesDir,
|
|
3277
|
+
`${packageName}.${exportsClassName}`,
|
|
3278
|
+
HELPER_JAR_PATH,
|
|
3279
|
+
DEFAULT_EXECUTE_COMPILER_DEBUG_PROFILE
|
|
3280
|
+
);
|
|
3281
|
+
} catch (error) {
|
|
3282
|
+
throw makeWorkerStageError('compile and run', error);
|
|
3283
|
+
}
|
|
3284
|
+
const libraryCallEnd = performance.now();
|
|
3285
|
+
|
|
3286
|
+
let report;
|
|
3287
|
+
try {
|
|
3288
|
+
report = JSON.parse(reportText);
|
|
3289
|
+
} catch (error) {
|
|
3290
|
+
throw makeWorkerStageError('execution report parse', error);
|
|
3291
|
+
}
|
|
3292
|
+
|
|
3293
|
+
const totalEnd = performance.now();
|
|
3294
|
+
const consoleOutput = javaReportConsoleOutput(report);
|
|
3295
|
+
const timings = {
|
|
3296
|
+
hostCallMs: libraryCallEnd - libraryCallStart,
|
|
3297
|
+
totalMs: totalEnd - totalStart,
|
|
3298
|
+
compileMs: report.compileTimeMs ?? 0,
|
|
3299
|
+
classLoadMs: report.classLoadTimeMs ?? 0,
|
|
3300
|
+
runMs: report.runTimeMs ?? 0,
|
|
3301
|
+
compileCacheHit: report.compileCacheHit ?? false,
|
|
3302
|
+
};
|
|
3303
|
+
|
|
3304
|
+
if (report.success !== true) {
|
|
3305
|
+
return {
|
|
3306
|
+
success: false,
|
|
3307
|
+
output: null,
|
|
3308
|
+
executionTimeMs: totalEnd - totalStart,
|
|
3309
|
+
consoleOutput,
|
|
3310
|
+
error:
|
|
3311
|
+
report.runtimeError ||
|
|
3312
|
+
report.compilerStderr ||
|
|
3313
|
+
report.compilerStdout ||
|
|
3314
|
+
'Java execution failed',
|
|
3315
|
+
timings,
|
|
3316
|
+
};
|
|
3317
|
+
}
|
|
3318
|
+
|
|
3319
|
+
return {
|
|
3320
|
+
success: true,
|
|
3321
|
+
output: parseJavaReportOutput(report.output),
|
|
3322
|
+
executionTimeMs: totalEnd - totalStart,
|
|
3323
|
+
consoleOutput,
|
|
3324
|
+
timings,
|
|
3325
|
+
};
|
|
3326
|
+
}
|
|
3327
|
+
|
|
3328
|
+
async function runJavaCodeBatchRequest(payload) {
|
|
3329
|
+
const totalStart = performance.now();
|
|
3330
|
+
const inputBatch = Array.isArray(payload.inputBatch)
|
|
3331
|
+
? payload.inputBatch.map((inputs) => inputs && typeof inputs === 'object' ? inputs : {})
|
|
3332
|
+
: [];
|
|
3333
|
+
if (inputBatch.length === 0) {
|
|
3334
|
+
throw new Error('Java batch execution requires a non-empty inputBatch array.');
|
|
3335
|
+
}
|
|
3336
|
+
|
|
3337
|
+
const normalizedPayload = normalizeJavaExecutionPayload({
|
|
3338
|
+
...payload,
|
|
3339
|
+
inputs: inputBatch[0] ?? {},
|
|
3340
|
+
});
|
|
3341
|
+
const compileId = buildJavaBatchCompileId(normalizedPayload, inputBatch);
|
|
3342
|
+
const dynamicInputBatch = inputBatch.map((inputs, index) =>
|
|
3343
|
+
dynamicInputEntriesForPayload(
|
|
3344
|
+
{ ...normalizedPayload, inputs },
|
|
3345
|
+
`${compileId}-${index}`
|
|
3346
|
+
)
|
|
3347
|
+
);
|
|
3348
|
+
const dynamicInputs = dynamicInputBatch.flat();
|
|
3349
|
+
const exportsClassName = buildExportsClassName(compileId);
|
|
3350
|
+
const sourcePath = `/str/${exportsClassName}.java`;
|
|
3351
|
+
const classesDir = `/files/java-worker/${compileId}/classes`;
|
|
3352
|
+
|
|
3353
|
+
let runnableSource;
|
|
3354
|
+
let entryClasses;
|
|
3355
|
+
try {
|
|
3356
|
+
const batchSource = buildBatchRunnableSource(normalizedPayload, compileId, inputBatch, dynamicInputBatch);
|
|
3357
|
+
runnableSource = batchSource.source;
|
|
3358
|
+
entryClasses = batchSource.entryClasses;
|
|
3359
|
+
} catch (error) {
|
|
3360
|
+
throw makeWorkerStageError('batch source generation', error);
|
|
3361
|
+
}
|
|
3362
|
+
|
|
3363
|
+
try {
|
|
3364
|
+
await writeDynamicInputFiles(dynamicInputs);
|
|
3365
|
+
} catch (error) {
|
|
3366
|
+
throw makeWorkerStageError('dynamic input write', error);
|
|
3367
|
+
}
|
|
3368
|
+
|
|
3369
|
+
try {
|
|
3370
|
+
await self.cheerpOSAddStringFile(sourcePath, runnableSource);
|
|
3371
|
+
} catch (error) {
|
|
3372
|
+
throw makeWorkerStageError('source file write', error);
|
|
3373
|
+
}
|
|
3374
|
+
|
|
3375
|
+
let compileLibraryClass;
|
|
3376
|
+
try {
|
|
3377
|
+
compileLibraryClass = await getCompileLibraryClass();
|
|
3378
|
+
} catch (error) {
|
|
3379
|
+
throw makeWorkerStageError('compiler bridge load', error);
|
|
3380
|
+
}
|
|
3381
|
+
|
|
3382
|
+
const libraryCallStart = performance.now();
|
|
3383
|
+
let reportText;
|
|
3384
|
+
try {
|
|
3385
|
+
reportText = await compileLibraryClass.compileAndRunBatch(
|
|
3386
|
+
sourcePath,
|
|
3387
|
+
classesDir,
|
|
3388
|
+
entryClasses.join('\n'),
|
|
3389
|
+
HELPER_JAR_PATH,
|
|
3390
|
+
DEFAULT_EXECUTE_COMPILER_DEBUG_PROFILE
|
|
3391
|
+
);
|
|
3392
|
+
} catch (error) {
|
|
3393
|
+
throw makeWorkerStageError('compile and run batch', error);
|
|
3394
|
+
}
|
|
3395
|
+
const libraryCallEnd = performance.now();
|
|
3396
|
+
|
|
3397
|
+
let report;
|
|
3398
|
+
try {
|
|
3399
|
+
report = JSON.parse(reportText);
|
|
3400
|
+
} catch (error) {
|
|
3401
|
+
throw makeWorkerStageError('batch execution report parse', error);
|
|
3402
|
+
}
|
|
3403
|
+
|
|
3404
|
+
const totalEnd = performance.now();
|
|
3405
|
+
const consoleOutput = javaReportConsoleOutput(report);
|
|
3406
|
+
const compileMs = report.compileTimeMs ?? 0;
|
|
3407
|
+
const compileCacheHit = report.compileCacheHit ?? false;
|
|
3408
|
+
const rawResults = Array.isArray(report.results) ? report.results : [];
|
|
3409
|
+
const results = rawResults.map((entry) => {
|
|
3410
|
+
const success = entry?.success === true;
|
|
3411
|
+
const classLoadMs = entry?.classLoadTimeMs ?? 0;
|
|
3412
|
+
const runMs = entry?.runTimeMs ?? 0;
|
|
3413
|
+
return {
|
|
3414
|
+
success,
|
|
3415
|
+
output: success ? parseJavaReportOutput(entry.output) : null,
|
|
3416
|
+
consoleOutput,
|
|
3417
|
+
...(success ? {} : { error: entry?.runtimeError || report.runtimeError || 'Java execution failed' }),
|
|
3418
|
+
timings: {
|
|
3419
|
+
compileMs: 0,
|
|
3420
|
+
classLoadMs,
|
|
3421
|
+
runMs,
|
|
3422
|
+
hostCallMs: 0,
|
|
3423
|
+
totalMs: classLoadMs + runMs,
|
|
3424
|
+
compileCacheHit,
|
|
3425
|
+
},
|
|
3426
|
+
};
|
|
3427
|
+
});
|
|
3428
|
+
|
|
3429
|
+
if (results.length > 0) {
|
|
3430
|
+
results[0].timings = {
|
|
3431
|
+
...results[0].timings,
|
|
3432
|
+
compileMs,
|
|
3433
|
+
hostCallMs: libraryCallEnd - libraryCallStart,
|
|
3434
|
+
totalMs: totalEnd - totalStart,
|
|
3435
|
+
};
|
|
3436
|
+
}
|
|
3437
|
+
|
|
3438
|
+
return {
|
|
3439
|
+
success: report.success === true,
|
|
3440
|
+
results,
|
|
3441
|
+
executionTimeMs: totalEnd - totalStart,
|
|
3442
|
+
consoleOutput,
|
|
3443
|
+
...(report.success === true ? {} : { error: report.runtimeError || 'Java batch execution failed' }),
|
|
3444
|
+
timings: {
|
|
3445
|
+
hostCallMs: libraryCallEnd - libraryCallStart,
|
|
3446
|
+
totalMs: totalEnd - totalStart,
|
|
3447
|
+
compileMs,
|
|
3448
|
+
classLoadMs: rawResults.reduce((sum, entry) => sum + (entry?.classLoadTimeMs ?? 0), 0),
|
|
3449
|
+
runMs: rawResults.reduce((sum, entry) => sum + (entry?.runTimeMs ?? 0), 0),
|
|
3450
|
+
compileCacheHit,
|
|
3451
|
+
},
|
|
3452
|
+
};
|
|
3453
|
+
}
|
|
3454
|
+
|
|
1538
3455
|
self.onmessage = (event) => {
|
|
1539
3456
|
const message = event.data;
|
|
1540
3457
|
if (!message || typeof message !== 'object') {
|
|
@@ -1555,22 +3472,63 @@ self.onmessage = (event) => {
|
|
|
1555
3472
|
if (message.type === 'init') {
|
|
1556
3473
|
queue = queue.then(async () => {
|
|
1557
3474
|
try {
|
|
3475
|
+
applyWorkerOptions(message.payload);
|
|
3476
|
+
const startedAt = performance.now();
|
|
1558
3477
|
await ensureReady();
|
|
1559
|
-
|
|
3478
|
+
const totalMs = performance.now() - startedAt;
|
|
1560
3479
|
postMessageResponse({
|
|
1561
3480
|
id: message.id,
|
|
1562
3481
|
type: 'init',
|
|
1563
3482
|
payload: {
|
|
1564
3483
|
success: true,
|
|
1565
|
-
loadTimeMs: Math.round(
|
|
3484
|
+
loadTimeMs: Math.round(totalMs),
|
|
3485
|
+
timings: {
|
|
3486
|
+
totalMs,
|
|
3487
|
+
initMs: initLoadTimeMs ?? 0,
|
|
3488
|
+
warmupMs: 0,
|
|
3489
|
+
},
|
|
1566
3490
|
},
|
|
1567
3491
|
});
|
|
1568
3492
|
} catch (error) {
|
|
3493
|
+
emitRuntimeDiagnostic('error', 'worker-request-failed', 'Java worker init request failed.', {
|
|
3494
|
+
type: message.type,
|
|
3495
|
+
message: formatWorkerErrorMessage(error),
|
|
3496
|
+
});
|
|
3497
|
+
postMessageResponse({
|
|
3498
|
+
id: message.id,
|
|
3499
|
+
type: 'error',
|
|
3500
|
+
payload: { error: formatWorkerErrorMessage(error) },
|
|
3501
|
+
});
|
|
3502
|
+
} finally {
|
|
3503
|
+
resetIdleTimer();
|
|
3504
|
+
}
|
|
3505
|
+
});
|
|
3506
|
+
return;
|
|
3507
|
+
}
|
|
3508
|
+
|
|
3509
|
+
if (message.type === 'warmup') {
|
|
3510
|
+
queue = queue.then(async () => {
|
|
3511
|
+
try {
|
|
3512
|
+
applyWorkerOptions(message.payload);
|
|
3513
|
+
await ensureReady();
|
|
3514
|
+
const result = await warmRunHost();
|
|
3515
|
+
postMessageResponse({
|
|
3516
|
+
id: message.id,
|
|
3517
|
+
type: 'warmup',
|
|
3518
|
+
payload: result,
|
|
3519
|
+
});
|
|
3520
|
+
} catch (error) {
|
|
3521
|
+
emitRuntimeDiagnostic('error', 'worker-request-failed', 'Java worker warmup request failed.', {
|
|
3522
|
+
type: message.type,
|
|
3523
|
+
message: formatWorkerErrorMessage(error),
|
|
3524
|
+
});
|
|
1569
3525
|
postMessageResponse({
|
|
1570
3526
|
id: message.id,
|
|
1571
3527
|
type: 'error',
|
|
1572
3528
|
payload: { error: formatWorkerErrorMessage(error) },
|
|
1573
3529
|
});
|
|
3530
|
+
} finally {
|
|
3531
|
+
resetIdleTimer();
|
|
1574
3532
|
}
|
|
1575
3533
|
});
|
|
1576
3534
|
return;
|
|
@@ -1579,23 +3537,35 @@ self.onmessage = (event) => {
|
|
|
1579
3537
|
if (
|
|
1580
3538
|
message.type === 'execute-with-tracing' ||
|
|
1581
3539
|
message.type === 'execute-code' ||
|
|
3540
|
+
message.type === 'execute-code-batch' ||
|
|
1582
3541
|
message.type === 'execute-code-interview'
|
|
1583
3542
|
) {
|
|
1584
3543
|
queue = queue.then(async () => {
|
|
1585
3544
|
try {
|
|
3545
|
+
applyWorkerOptions(message.payload);
|
|
1586
3546
|
await ensureReady();
|
|
1587
|
-
const result =
|
|
3547
|
+
const result = message.type === 'execute-with-tracing'
|
|
3548
|
+
? await runJavaTraceRequest(message.payload, message.id)
|
|
3549
|
+
: message.type === 'execute-code-batch'
|
|
3550
|
+
? await runJavaCodeBatchRequest(message.payload)
|
|
3551
|
+
: await runJavaCodeRequest(message.payload);
|
|
1588
3552
|
postMessageResponse({
|
|
1589
3553
|
id: message.id,
|
|
1590
3554
|
type: message.type,
|
|
1591
3555
|
payload: result,
|
|
1592
3556
|
});
|
|
1593
3557
|
} catch (error) {
|
|
3558
|
+
emitRuntimeDiagnostic('error', 'worker-request-failed', 'Java worker execution request failed.', {
|
|
3559
|
+
type: message.type,
|
|
3560
|
+
message: formatWorkerErrorMessage(error),
|
|
3561
|
+
});
|
|
1594
3562
|
postMessageResponse({
|
|
1595
3563
|
id: message.id,
|
|
1596
3564
|
type: 'error',
|
|
1597
3565
|
payload: { error: formatWorkerErrorMessage(error) },
|
|
1598
3566
|
});
|
|
3567
|
+
} finally {
|
|
3568
|
+
resetIdleTimer();
|
|
1599
3569
|
}
|
|
1600
3570
|
});
|
|
1601
3571
|
return;
|
|
@@ -1603,5 +3573,6 @@ self.onmessage = (event) => {
|
|
|
1603
3573
|
};
|
|
1604
3574
|
|
|
1605
3575
|
queueMicrotask(() => {
|
|
3576
|
+
emitRuntimeDiagnostic('info', 'worker-ready', 'Java worker is ready.');
|
|
1606
3577
|
postMessageResponse({ type: 'worker-ready' });
|
|
1607
3578
|
});
|