@tracecode/harness 0.6.5 → 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 +55 -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 +2256 -170
- 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;
|
|
@@ -68,13 +109,19 @@ function formatWorkerErrorMessage(error) {
|
|
|
68
109
|
} catch {}
|
|
69
110
|
try {
|
|
70
111
|
const tag = Object.prototype.toString.call(error);
|
|
71
|
-
if (tag && tag
|
|
112
|
+
if (tag && tag.includes('ParseProblemException')) {
|
|
113
|
+
return 'Java syntax error.';
|
|
114
|
+
}
|
|
115
|
+
if (tag && tag !== '[object Object]' && !tag.startsWith('[object ')) {
|
|
72
116
|
return tag;
|
|
73
117
|
}
|
|
74
118
|
} catch {}
|
|
75
119
|
try {
|
|
76
120
|
if (typeof error.toString === 'function' && error.toString !== Object.prototype.toString) {
|
|
77
121
|
const value = error.toString();
|
|
122
|
+
if (value.includes('ParseProblemException')) {
|
|
123
|
+
return 'Java syntax error.';
|
|
124
|
+
}
|
|
78
125
|
if (typeof value === 'string' && value.length > 0 && value !== '[object Object]') {
|
|
79
126
|
return value;
|
|
80
127
|
}
|
|
@@ -83,6 +130,9 @@ function formatWorkerErrorMessage(error) {
|
|
|
83
130
|
}
|
|
84
131
|
try {
|
|
85
132
|
const stringified = String(error);
|
|
133
|
+
if (stringified.includes('ParseProblemException')) {
|
|
134
|
+
return 'Java syntax error.';
|
|
135
|
+
}
|
|
86
136
|
if (stringified && stringified !== '[object Object]') {
|
|
87
137
|
return stringified;
|
|
88
138
|
}
|
|
@@ -110,7 +160,14 @@ function resetIdleTimer() {
|
|
|
110
160
|
if (generation !== idleGeneration) return;
|
|
111
161
|
postMessageResponse({ type: 'idle-timeout' });
|
|
112
162
|
self.close();
|
|
113
|
-
},
|
|
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
|
+
}
|
|
114
171
|
}
|
|
115
172
|
|
|
116
173
|
function assertSupportedExecutionStyle(executionStyle) {
|
|
@@ -141,6 +198,8 @@ function isRecord(value) {
|
|
|
141
198
|
|
|
142
199
|
function isListNodeShape(value) {
|
|
143
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;
|
|
144
203
|
if (!('val' in value || 'value' in value)) return false;
|
|
145
204
|
if ('next' in value) return true;
|
|
146
205
|
return typeof value.__id__ === 'string' && value.__id__.startsWith('list-');
|
|
@@ -148,19 +207,43 @@ function isListNodeShape(value) {
|
|
|
148
207
|
|
|
149
208
|
function isTreeNodeShape(value) {
|
|
150
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;
|
|
151
212
|
if (!('val' in value || 'value' in value)) return false;
|
|
152
213
|
if ('left' in value || 'right' in value) return true;
|
|
153
214
|
return typeof value.__id__ === 'string' && value.__id__.startsWith('tree-');
|
|
154
215
|
}
|
|
155
216
|
|
|
156
|
-
function detectFeatures(source, input) {
|
|
217
|
+
function detectFeatures(source, input, options = {}) {
|
|
157
218
|
const values = Object.values(input ?? {});
|
|
158
219
|
return {
|
|
159
220
|
hasList: /\bListNode\b/.test(source) || values.some((value) => isListNodeShape(value)),
|
|
160
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,
|
|
161
225
|
};
|
|
162
226
|
}
|
|
163
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
|
+
|
|
164
247
|
function toJavaScalarLiteral(value) {
|
|
165
248
|
if (value === null) return 'null';
|
|
166
249
|
if (typeof value === 'number' || typeof value === 'boolean') return String(value);
|
|
@@ -168,6 +251,23 @@ function toJavaScalarLiteral(value) {
|
|
|
168
251
|
throw new Error(`Unsupported scalar literal: ${JSON.stringify(value)}`);
|
|
169
252
|
}
|
|
170
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
|
+
|
|
171
271
|
function toJavaArrayLiteral(value) {
|
|
172
272
|
if (value.length === 0) return 'new int[] {}';
|
|
173
273
|
if (value.every((entry) => typeof entry === 'number' && Number.isInteger(entry))) {
|
|
@@ -217,6 +317,78 @@ function extractTypeArguments(typeSource) {
|
|
|
217
317
|
return parts.map((part) => part.trim()).filter(Boolean);
|
|
218
318
|
}
|
|
219
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
|
+
|
|
220
392
|
function toJavaTypedArrayLiteral(value, expectedType) {
|
|
221
393
|
const normalized = stripGenericType(expectedType);
|
|
222
394
|
if (!normalized.endsWith('[]')) {
|
|
@@ -259,7 +431,81 @@ function toJavaTypedArrayLiteral(value, expectedType) {
|
|
|
259
431
|
|
|
260
432
|
function toJavaListLiteral(value, expectedType) {
|
|
261
433
|
const [elementType = 'Object'] = extractTypeArguments(expectedType);
|
|
262
|
-
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;
|
|
263
509
|
}
|
|
264
510
|
|
|
265
511
|
function listLiteral(value) {
|
|
@@ -311,17 +557,18 @@ function listGraphExpression(head) {
|
|
|
311
557
|
|
|
312
558
|
const values = nodes.map((node) => {
|
|
313
559
|
const rawVal = node.val ?? node.value ?? 0;
|
|
314
|
-
if (typeof rawVal !== 'number' || !Number.isInteger(rawVal)) {
|
|
315
|
-
throw new Error(`Unsupported list node value: ${JSON.stringify(rawVal)}`);
|
|
316
|
-
}
|
|
317
560
|
return rawVal;
|
|
318
561
|
});
|
|
319
562
|
|
|
320
|
-
return `buildList(new
|
|
563
|
+
return `buildList(new Object[] { ${values.map((value) => toJavaScalarLiteral(value)).join(', ')} }, new int[] { ${nextIndices.join(', ')} })`;
|
|
321
564
|
}
|
|
322
565
|
|
|
323
566
|
function listExpression(value) {
|
|
324
|
-
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}))`;
|
|
325
572
|
}
|
|
326
573
|
|
|
327
574
|
function treeExpression(value) {
|
|
@@ -331,9 +578,29 @@ function treeExpression(value) {
|
|
|
331
578
|
return `tree(${toJavaScalarLiteral(rawVal)}, ${left}, ${right})`;
|
|
332
579
|
}
|
|
333
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
|
+
|
|
334
589
|
function buildJavaExpression(value, expectedType) {
|
|
335
590
|
const normalizedType = expectedType ? stripGenericType(expectedType) : null;
|
|
591
|
+
if (value === null || typeof value !== 'object') {
|
|
592
|
+
return toJavaScalarLiteralForType(value, normalizedType);
|
|
593
|
+
}
|
|
336
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
|
+
}
|
|
337
604
|
if (normalizedType?.startsWith('List<')) {
|
|
338
605
|
return toJavaListLiteral(value, normalizedType);
|
|
339
606
|
}
|
|
@@ -344,34 +611,299 @@ function buildJavaExpression(value, expectedType) {
|
|
|
344
611
|
}
|
|
345
612
|
if (isRecord(value) && normalizedType === 'ListNode') return listExpression(value);
|
|
346
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
|
+
}
|
|
347
618
|
if (isListNodeShape(value)) return listExpression(value);
|
|
348
619
|
if (isTreeNodeShape(value)) return treeExpression(value);
|
|
349
620
|
return toJavaScalarLiteral(value);
|
|
350
621
|
}
|
|
351
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
|
+
|
|
352
807
|
function buildHelperMethods(features) {
|
|
808
|
+
if (features.skipInputMaterializers) {
|
|
809
|
+
return '';
|
|
810
|
+
}
|
|
353
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
|
+
}
|
|
354
846
|
if (features.hasList) {
|
|
355
847
|
members.push(`
|
|
356
|
-
private static ListNode list(
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
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
|
+
}
|
|
360
884
|
}
|
|
361
885
|
|
|
362
|
-
private static ListNode buildList(
|
|
886
|
+
private static ListNode buildList(Object[] values, int[] nextIndices) {
|
|
363
887
|
if (values.length == 0) {
|
|
364
888
|
return null;
|
|
365
889
|
}
|
|
366
890
|
ListNode[] nodes = new ListNode[values.length];
|
|
367
891
|
for (int i = 0; i < values.length; i++) {
|
|
368
|
-
nodes[i] =
|
|
892
|
+
nodes[i] = list(values[i], null);
|
|
369
893
|
}
|
|
370
894
|
for (int i = 0; i < values.length; i++) {
|
|
371
895
|
int nextIndex = nextIndices[i];
|
|
372
896
|
nodes[i].next = nextIndex >= 0 ? nodes[nextIndex] : null;
|
|
373
897
|
}
|
|
374
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;
|
|
375
907
|
}`);
|
|
376
908
|
}
|
|
377
909
|
if (features.hasTree) {
|
|
@@ -381,33 +913,220 @@ function buildHelperMethods(features) {
|
|
|
381
913
|
node.left = left;
|
|
382
914
|
node.right = right;
|
|
383
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;
|
|
384
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
|
+
`);
|
|
385
1019
|
}
|
|
386
1020
|
return members.join('\n');
|
|
387
1021
|
}
|
|
388
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
|
+
|
|
389
1083
|
function extractMethodParameters(source, methodName) {
|
|
1084
|
+
return extractMethodParameterOverloads(source, methodName)[0] ?? [];
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
function extractMethodParameterOverloads(source, methodName) {
|
|
390
1088
|
const compact = source.replace(/\s+/g, ' ');
|
|
391
1089
|
const escapedMethod = methodName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
392
|
-
const
|
|
393
|
-
|
|
394
|
-
|
|
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
|
+
);
|
|
395
1113
|
}
|
|
1114
|
+
return overloads;
|
|
1115
|
+
}
|
|
396
1116
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
});
|
|
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;
|
|
411
1130
|
}
|
|
412
1131
|
|
|
413
1132
|
function indentBlock(source, spaces = 2) {
|
|
@@ -498,24 +1217,85 @@ function findMatchingParen(source, openIndex) {
|
|
|
498
1217
|
return closeIndex;
|
|
499
1218
|
}
|
|
500
1219
|
|
|
501
|
-
function
|
|
502
|
-
let
|
|
503
|
-
let
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
scanJavaCode(source, bodyStart, source.length, (index, ch) => {
|
|
507
|
-
if (ch === '(') parenDepth += 1;
|
|
508
|
-
if (ch === ')') parenDepth = Math.max(0, parenDepth - 1);
|
|
509
|
-
if (ch === '[') bracketDepth += 1;
|
|
510
|
-
if (ch === ']') bracketDepth = Math.max(0, bracketDepth - 1);
|
|
511
|
-
if (ch === '{') braceDepth += 1;
|
|
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;
|
|
512
1225
|
if (ch === '}') {
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
1226
|
+
depth -= 1;
|
|
1227
|
+
if (depth === 0) {
|
|
1228
|
+
closeIndex = index;
|
|
1229
|
+
return false;
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
return undefined;
|
|
1233
|
+
});
|
|
1234
|
+
return closeIndex;
|
|
1235
|
+
}
|
|
1236
|
+
|
|
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
|
+
|
|
1282
|
+
let parenDepth = 0;
|
|
1283
|
+
let bracketDepth = 0;
|
|
1284
|
+
let braceDepth = 0;
|
|
1285
|
+
let statementEnd = -1;
|
|
1286
|
+
scanJavaCode(source, bodyStart, source.length, (index, ch) => {
|
|
1287
|
+
if (ch === '(') parenDepth += 1;
|
|
1288
|
+
if (ch === ')') parenDepth = Math.max(0, parenDepth - 1);
|
|
1289
|
+
if (ch === '[') bracketDepth += 1;
|
|
1290
|
+
if (ch === ']') bracketDepth = Math.max(0, bracketDepth - 1);
|
|
1291
|
+
if (ch === '{') braceDepth += 1;
|
|
1292
|
+
if (ch === '}') {
|
|
1293
|
+
if (braceDepth === 0) return false;
|
|
1294
|
+
braceDepth -= 1;
|
|
1295
|
+
}
|
|
1296
|
+
if (ch === ';' && parenDepth === 0 && bracketDepth === 0 && braceDepth === 0) {
|
|
1297
|
+
statementEnd = index;
|
|
1298
|
+
return false;
|
|
519
1299
|
}
|
|
520
1300
|
return undefined;
|
|
521
1301
|
});
|
|
@@ -528,14 +1308,64 @@ function startsWithJavaKeyword(source, index, keyword) {
|
|
|
528
1308
|
return !after || !isJavaIdentifierPart(after);
|
|
529
1309
|
}
|
|
530
1310
|
|
|
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
|
+
|
|
531
1358
|
function wrapSingleStatementLoopBodies(source) {
|
|
1359
|
+
source = wrapNestedBracedLoopBodies(source);
|
|
532
1360
|
const inserts = [];
|
|
533
1361
|
scanJavaCode(source, 0, source.length, (index) => {
|
|
534
1362
|
const keyword = source.startsWith('for', index)
|
|
535
1363
|
? 'for'
|
|
536
1364
|
: source.startsWith('while', index)
|
|
537
1365
|
? 'while'
|
|
538
|
-
:
|
|
1366
|
+
: source.startsWith('if', index)
|
|
1367
|
+
? 'if'
|
|
1368
|
+
: null;
|
|
539
1369
|
if (!keyword) return undefined;
|
|
540
1370
|
|
|
541
1371
|
const before = index > 0 ? source[index - 1] : '';
|
|
@@ -556,7 +1386,6 @@ function wrapSingleStatementLoopBodies(source) {
|
|
|
556
1386
|
const bodyChar = source[bodyStart];
|
|
557
1387
|
if (!bodyChar || bodyChar === '{' || bodyChar === ';') return closeParen;
|
|
558
1388
|
if (
|
|
559
|
-
startsWithJavaKeyword(source, bodyStart, 'if') ||
|
|
560
1389
|
startsWithJavaKeyword(source, bodyStart, 'switch') ||
|
|
561
1390
|
startsWithJavaKeyword(source, bodyStart, 'synchronized') ||
|
|
562
1391
|
startsWithJavaKeyword(source, bodyStart, 'try')
|
|
@@ -584,7 +1413,7 @@ function wrapSingleStatementLoopBodies(source) {
|
|
|
584
1413
|
output += insertsByIndex.get(index) ?? '';
|
|
585
1414
|
if (index < source.length) output += source[index];
|
|
586
1415
|
}
|
|
587
|
-
return output;
|
|
1416
|
+
return output === source ? output : wrapSingleStatementLoopBodies(output);
|
|
588
1417
|
}
|
|
589
1418
|
|
|
590
1419
|
function splitTopLevelJavaList(value) {
|
|
@@ -666,6 +1495,13 @@ function escapeRegExp(value) {
|
|
|
666
1495
|
return String(value).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
667
1496
|
}
|
|
668
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
|
+
|
|
669
1505
|
function augmentTraceCallArgumentSnapshots(source) {
|
|
670
1506
|
const lines = source.split('\n');
|
|
671
1507
|
const methodStack = [];
|
|
@@ -688,14 +1524,14 @@ function augmentTraceCallArgumentSnapshots(source) {
|
|
|
688
1524
|
let nextLine = line;
|
|
689
1525
|
if (currentMethod && !currentMethod.patchedCall && currentMethod.params.length > 0) {
|
|
690
1526
|
const callPattern = new RegExp(
|
|
691
|
-
`^(\\s*)TraceHooks\\.
|
|
1527
|
+
`^(\\s*)TraceHooks\\.emitCallAtLine\\((\\d+),\\s*"${escapeRegExp(currentMethod.name)}",\\s*([^)]*)\\);\\s*$`
|
|
692
1528
|
);
|
|
693
1529
|
const callMatch = line.match(callPattern);
|
|
694
1530
|
if (callMatch) {
|
|
695
1531
|
const serializedArgs = currentMethod.params
|
|
696
1532
|
.map((paramName) => ` + " ${paramName}=" + TraceHooks.serializeResult(${paramName})`)
|
|
697
1533
|
.join('');
|
|
698
|
-
nextLine = `${callMatch[1]}TraceHooks.
|
|
1534
|
+
nextLine = `${callMatch[1]}TraceHooks.emitCallAtLine(${callMatch[2]}, "${currentMethod.name}", ""${serializedArgs});`;
|
|
699
1535
|
currentMethod.patchedCall = true;
|
|
700
1536
|
}
|
|
701
1537
|
}
|
|
@@ -711,6 +1547,389 @@ function augmentTraceCallArgumentSnapshots(source) {
|
|
|
711
1547
|
}).join('\n');
|
|
712
1548
|
}
|
|
713
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
|
+
|
|
714
1933
|
function augmentArrayLengthReads(source) {
|
|
715
1934
|
const lines = source.split('\n');
|
|
716
1935
|
const methodStack = [];
|
|
@@ -738,9 +1957,9 @@ function augmentArrayLengthReads(source) {
|
|
|
738
1957
|
currentMethod.arrayNames.add(name);
|
|
739
1958
|
}
|
|
740
1959
|
|
|
741
|
-
const
|
|
742
|
-
if (
|
|
743
|
-
currentMethod.currentTraceLine =
|
|
1960
|
+
const traceLine = parseNativeTraceLine(line);
|
|
1961
|
+
if (traceLine !== null) {
|
|
1962
|
+
currentMethod.currentTraceLine = traceLine;
|
|
744
1963
|
currentMethod.hasTraceEmit = true;
|
|
745
1964
|
}
|
|
746
1965
|
|
|
@@ -792,7 +2011,7 @@ function augmentTraceReturnValueSnapshots(source) {
|
|
|
792
2011
|
const currentMethod = methodStack[methodStack.length - 1];
|
|
793
2012
|
if (currentMethod && currentMethod.returnType !== 'void') {
|
|
794
2013
|
const returnEmitMatch = line.match(
|
|
795
|
-
/^(\s*)TraceHooks\.
|
|
2014
|
+
/^(\s*)TraceHooks\.emitReturnAtLine\((\d+),\s*"([A-Za-z_][A-Za-z0-9_]*)"\);\s*$/
|
|
796
2015
|
);
|
|
797
2016
|
const nextLine = lines[index + 1] ?? '';
|
|
798
2017
|
const returnMatch = nextLine.match(/^(\s*)return\s+(.+);\s*$/);
|
|
@@ -802,7 +2021,7 @@ function augmentTraceReturnValueSnapshots(source) {
|
|
|
802
2021
|
const returnExpression = returnMatch[2].trim();
|
|
803
2022
|
output.push(`${indent}${currentMethod.returnType} ${tempName} = ${returnExpression};`);
|
|
804
2023
|
output.push(
|
|
805
|
-
`${indent}TraceHooks.
|
|
2024
|
+
`${indent}TraceHooks.emitSerializedReturnAtLine(${returnEmitMatch[2]}, "${currentMethod.name}", TraceHooks.serializeResult(${tempName}));`
|
|
806
2025
|
);
|
|
807
2026
|
output.push(`${returnMatch[1] ?? indent}return ${tempName};`);
|
|
808
2027
|
currentMethod.depth += braceDelta(line) + braceDelta(nextLine);
|
|
@@ -879,24 +2098,54 @@ function isTopLevelMethodStart(line) {
|
|
|
879
2098
|
return /^(?:public\s+|private\s+|protected\s+)?(?:static\s+)?(?:[\w<>\[\], ?]+\s+)+[A-Za-z_][A-Za-z0-9_]*\s*\([^;]*\)\s*\{/.test(trimmed);
|
|
880
2099
|
}
|
|
881
2100
|
|
|
882
|
-
function
|
|
883
|
-
|
|
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;
|
|
884
2113
|
let quote = null;
|
|
2114
|
+
let escaped = false;
|
|
885
2115
|
for (let index = 0; index < line.length; index += 1) {
|
|
886
2116
|
const ch = line[index];
|
|
887
|
-
const
|
|
2117
|
+
const next = line[index + 1] ?? '';
|
|
2118
|
+
if (escaped) {
|
|
2119
|
+
escaped = false;
|
|
2120
|
+
continue;
|
|
2121
|
+
}
|
|
888
2122
|
if (quote) {
|
|
889
|
-
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;
|
|
890
2135
|
continue;
|
|
891
2136
|
}
|
|
892
2137
|
if (ch === '"' || ch === "'") {
|
|
893
2138
|
quote = ch;
|
|
894
2139
|
continue;
|
|
895
2140
|
}
|
|
896
|
-
if (ch === '{')
|
|
897
|
-
if (ch === '}')
|
|
2141
|
+
if (ch === '{') open += 1;
|
|
2142
|
+
if (ch === '}') close += 1;
|
|
898
2143
|
}
|
|
899
|
-
return delta;
|
|
2144
|
+
return { open, close, delta: open - close };
|
|
2145
|
+
}
|
|
2146
|
+
|
|
2147
|
+
function braceDelta(line) {
|
|
2148
|
+
return javaBraceCounts(line).delta;
|
|
900
2149
|
}
|
|
901
2150
|
|
|
902
2151
|
function splitScriptMembersAndStatements(lines) {
|
|
@@ -906,7 +2155,7 @@ function splitScriptMembersAndStatements(lines) {
|
|
|
906
2155
|
for (let index = 0; index < lines.length; index += 1) {
|
|
907
2156
|
const entry = lines[index];
|
|
908
2157
|
const line = typeof entry === 'string' ? entry : entry.line;
|
|
909
|
-
if (statementDepth !== 0 || !
|
|
2158
|
+
if (statementDepth !== 0 || !isTopLevelMemberStart(line)) {
|
|
910
2159
|
statementLines.push(entry);
|
|
911
2160
|
statementDepth += braceDelta(line);
|
|
912
2161
|
if (statementDepth < 0) statementDepth = 0;
|
|
@@ -1031,65 +2280,226 @@ function normalizeJavaRequest(payload) {
|
|
|
1031
2280
|
};
|
|
1032
2281
|
}
|
|
1033
2282
|
|
|
1034
|
-
if (payload.executionStyle
|
|
1035
|
-
return
|
|
1036
|
-
|
|
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
|
+
|
|
2299
|
+
if (payload.executionStyle !== 'function') {
|
|
2300
|
+
return payload;
|
|
2301
|
+
}
|
|
1037
2302
|
|
|
1038
2303
|
return {
|
|
1039
2304
|
...payload,
|
|
2305
|
+
sourceText: payload.code,
|
|
1040
2306
|
code: normalizeFunctionSource(payload.code),
|
|
1041
2307
|
executionStyle: 'solution-method',
|
|
1042
2308
|
};
|
|
1043
2309
|
}
|
|
1044
2310
|
|
|
1045
|
-
function
|
|
1046
|
-
|
|
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`,
|
|
2351
|
+
});
|
|
2352
|
+
}
|
|
2353
|
+
return entries;
|
|
2354
|
+
}
|
|
2355
|
+
|
|
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
|
+
}
|
|
2366
|
+
|
|
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
|
+
};
|
|
1047
2417
|
const helperMethods = buildHelperMethods(features);
|
|
2418
|
+
const nodePreludeSource = buildNodePreludeSource(source, options);
|
|
2419
|
+
const dynamicInputsByKey = dynamicInputByKey(options.dynamicInputs ?? []);
|
|
1048
2420
|
|
|
1049
2421
|
if (executionStyle === 'ops-class') {
|
|
1050
2422
|
const operations = Array.isArray(input.operations) ? input.operations : [];
|
|
1051
2423
|
const argumentsList = Array.isArray(input.arguments) ? input.arguments : [];
|
|
1052
|
-
const lines = [
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
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
|
+
}
|
|
1056
2442
|
|
|
1057
2443
|
operations.forEach((operation, index) => {
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
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});`);
|
|
1061
2454
|
lines.push(' out.add(null);');
|
|
1062
2455
|
} else {
|
|
1063
|
-
lines.push(` out.add(instance.${
|
|
2456
|
+
lines.push(` out.add(instance.${operationName}(${invocationArgs}));`);
|
|
1064
2457
|
}
|
|
1065
2458
|
});
|
|
1066
2459
|
|
|
1067
|
-
return
|
|
2460
|
+
return `${nodePreludeSource}public class Exports {
|
|
1068
2461
|
${helperMethods}
|
|
1069
2462
|
|
|
1070
2463
|
public static String run() {
|
|
1071
2464
|
${lines.join('\n')}
|
|
1072
|
-
return TraceHooks.
|
|
2465
|
+
return TraceHooks.serializeOutputResult(out);
|
|
1073
2466
|
}
|
|
1074
2467
|
}
|
|
1075
2468
|
`;
|
|
1076
2469
|
}
|
|
1077
2470
|
|
|
1078
2471
|
const parameters = extractMethodParameters(source, functionName);
|
|
1079
|
-
const
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
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});`;
|
|
1085
2495
|
|
|
1086
|
-
return
|
|
2496
|
+
return `${nodePreludeSource}public class Exports {
|
|
1087
2497
|
${helperMethods}
|
|
1088
2498
|
|
|
1089
2499
|
public static String run() {
|
|
1090
2500
|
Solution solution = new Solution();
|
|
1091
|
-
|
|
1092
|
-
|
|
2501
|
+
${materializedArgs.join('\n')}
|
|
2502
|
+
${invocationLine}
|
|
1093
2503
|
}
|
|
1094
2504
|
}
|
|
1095
2505
|
`;
|
|
@@ -1103,6 +2513,20 @@ function buildExportsClassName(messageId) {
|
|
|
1103
2513
|
return `Exports${String(messageId).replace(/[^A-Za-z0-9]/g, '')}`;
|
|
1104
2514
|
}
|
|
1105
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
|
+
|
|
1106
2530
|
async function ensureReady() {
|
|
1107
2531
|
if (!workerReadyPromise) {
|
|
1108
2532
|
workerReadyPromise = (async () => {
|
|
@@ -1122,7 +2546,6 @@ async function ensureReady() {
|
|
|
1122
2546
|
})();
|
|
1123
2547
|
}
|
|
1124
2548
|
await workerReadyPromise;
|
|
1125
|
-
resetIdleTimer();
|
|
1126
2549
|
}
|
|
1127
2550
|
|
|
1128
2551
|
async function getHelperLibrary() {
|
|
@@ -1136,7 +2559,7 @@ async function getCompileLibraryClass() {
|
|
|
1136
2559
|
if (!compileLibraryClassPromise) {
|
|
1137
2560
|
compileLibraryClassPromise = (async () => {
|
|
1138
2561
|
const library = await getHelperLibrary();
|
|
1139
|
-
return library.
|
|
2562
|
+
return library.tracecode.browser.BrowserCompileAndTraceLibrary;
|
|
1140
2563
|
})();
|
|
1141
2564
|
}
|
|
1142
2565
|
return compileLibraryClassPromise;
|
|
@@ -1152,45 +2575,87 @@ async function getRewriteLibraryClass() {
|
|
|
1152
2575
|
return rewriteLibraryClassPromise;
|
|
1153
2576
|
}
|
|
1154
2577
|
|
|
1155
|
-
async function
|
|
1156
|
-
if (!
|
|
1157
|
-
|
|
2578
|
+
async function warmRunHost() {
|
|
2579
|
+
if (!runWarmupPromise) {
|
|
2580
|
+
runWarmupPromise = (async () => {
|
|
2581
|
+
const totalStart = performance.now();
|
|
1158
2582
|
const libraryClass = await getCompileLibraryClass();
|
|
1159
|
-
const
|
|
1160
|
-
const
|
|
1161
|
-
const
|
|
2583
|
+
const runSourcePath = '/str/ExportsTracecodeRunWarmup.java';
|
|
2584
|
+
const runClassesDir = '/files/java-worker/__warm_run__/classes';
|
|
2585
|
+
const runWarmupSource = `
|
|
1162
2586
|
package harness.user.warmup;
|
|
1163
2587
|
|
|
1164
|
-
|
|
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 {
|
|
1165
2597
|
public static String run() {
|
|
1166
|
-
|
|
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);
|
|
1167
2603
|
}
|
|
1168
2604
|
}
|
|
1169
2605
|
`;
|
|
1170
|
-
await self.cheerpOSAddStringFile(
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
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',
|
|
1175
2612
|
HELPER_JAR_PATH,
|
|
1176
|
-
|
|
2613
|
+
DEFAULT_EXECUTE_COMPILER_DEBUG_PROFILE
|
|
1177
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
|
+
};
|
|
1178
2633
|
})();
|
|
1179
2634
|
}
|
|
1180
|
-
|
|
2635
|
+
try {
|
|
2636
|
+
return await runWarmupPromise;
|
|
2637
|
+
} catch (error) {
|
|
2638
|
+
runWarmupPromise = null;
|
|
2639
|
+
throw error;
|
|
2640
|
+
}
|
|
1181
2641
|
}
|
|
1182
2642
|
|
|
1183
|
-
async function rewriteSource(payload,
|
|
2643
|
+
async function rewriteSource(payload, compileId, dynamicInputs) {
|
|
1184
2644
|
const rewriteLibraryClass = await getRewriteLibraryClass();
|
|
1185
|
-
const exportsClassName = buildExportsClassName(
|
|
1186
|
-
const packageName = buildPackageName(
|
|
2645
|
+
const exportsClassName = buildExportsClassName(compileId);
|
|
2646
|
+
const packageName = buildPackageName(compileId);
|
|
1187
2647
|
const exportsSource = buildExportsSource(
|
|
1188
2648
|
payload.code,
|
|
1189
2649
|
payload.functionName,
|
|
1190
2650
|
payload.executionStyle,
|
|
1191
|
-
payload.inputs ?? {}
|
|
2651
|
+
payload.inputs ?? {},
|
|
2652
|
+
{
|
|
2653
|
+
dynamicInputs,
|
|
2654
|
+
hasDynamicInputs: dynamicInputs.length > 0,
|
|
2655
|
+
scriptMode: payload.scriptMode === true,
|
|
2656
|
+
}
|
|
1192
2657
|
);
|
|
1193
|
-
|
|
2658
|
+
const rewrittenSource = await rewriteLibraryClass.rewriteSource(
|
|
1194
2659
|
payload.code,
|
|
1195
2660
|
payload.executionStyle,
|
|
1196
2661
|
payload.functionName,
|
|
@@ -1198,84 +2663,377 @@ async function rewriteSource(payload, requestId) {
|
|
|
1198
2663
|
exportsClassName,
|
|
1199
2664
|
packageName
|
|
1200
2665
|
);
|
|
2666
|
+
return addJavaDefaultImportsToPackagedSource(rewrittenSource);
|
|
2667
|
+
}
|
|
2668
|
+
|
|
2669
|
+
function normalizePublicClassDeclarations(source) {
|
|
2670
|
+
return String(source).replace(/^([ \t]*)public\s+class\s+/gm, '$1class ');
|
|
2671
|
+
}
|
|
2672
|
+
|
|
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) {
|
|
2766
|
+
const probeClassName = buildExportsClassName(`${requestId}RewriteProbe`);
|
|
2767
|
+
const probePackageName = buildPackageName(`${requestId}RewriteProbe`);
|
|
2768
|
+
const sourcePath = `/str/${probeClassName}.java`;
|
|
2769
|
+
const classesDir = `/files/java-worker/${requestId}/rewrite-probe/classes`;
|
|
2770
|
+
|
|
2771
|
+
let compileLibraryClass;
|
|
2772
|
+
try {
|
|
2773
|
+
compileLibraryClass = await getCompileLibraryClass();
|
|
2774
|
+
} catch (error) {
|
|
2775
|
+
return {
|
|
2776
|
+
consoleOutput: [],
|
|
2777
|
+
error: null,
|
|
2778
|
+
hostCallMs: 0,
|
|
2779
|
+
diagnosticError: formatWorkerErrorMessage(error),
|
|
2780
|
+
};
|
|
2781
|
+
}
|
|
2782
|
+
|
|
2783
|
+
try {
|
|
2784
|
+
await self.cheerpOSAddStringFile(
|
|
2785
|
+
sourcePath,
|
|
2786
|
+
buildCompileProbeSource(payload, requestId, probeClassName, probePackageName)
|
|
2787
|
+
);
|
|
2788
|
+
} catch (error) {
|
|
2789
|
+
return {
|
|
2790
|
+
consoleOutput: [],
|
|
2791
|
+
error: null,
|
|
2792
|
+
hostCallMs: 0,
|
|
2793
|
+
diagnosticError: formatWorkerErrorMessage(error),
|
|
2794
|
+
};
|
|
2795
|
+
}
|
|
2796
|
+
|
|
2797
|
+
const startedAt = performance.now();
|
|
2798
|
+
let reportText;
|
|
2799
|
+
try {
|
|
2800
|
+
reportText = await compileLibraryClass.compileAndTrace(
|
|
2801
|
+
sourcePath,
|
|
2802
|
+
classesDir,
|
|
2803
|
+
`${probePackageName}.${probeClassName}`,
|
|
2804
|
+
HELPER_JAR_PATH,
|
|
2805
|
+
DEFAULT_COMPILER_DEBUG_PROFILE,
|
|
2806
|
+
String(resolveMaxStoredEvents(options))
|
|
2807
|
+
);
|
|
2808
|
+
} catch (error) {
|
|
2809
|
+
return {
|
|
2810
|
+
consoleOutput: [],
|
|
2811
|
+
error: null,
|
|
2812
|
+
hostCallMs: performance.now() - startedAt,
|
|
2813
|
+
diagnosticError: formatWorkerErrorMessage(error),
|
|
2814
|
+
};
|
|
2815
|
+
}
|
|
2816
|
+
|
|
2817
|
+
let report;
|
|
2818
|
+
try {
|
|
2819
|
+
report = JSON.parse(reportText);
|
|
2820
|
+
} catch (error) {
|
|
2821
|
+
return {
|
|
2822
|
+
consoleOutput: [],
|
|
2823
|
+
error: null,
|
|
2824
|
+
hostCallMs: performance.now() - startedAt,
|
|
2825
|
+
diagnosticError: `Invalid compile probe report: ${formatWorkerErrorMessage(error)}`,
|
|
2826
|
+
};
|
|
2827
|
+
}
|
|
2828
|
+
|
|
2829
|
+
const consoleOutput = [report.compilerStdout, report.compilerStderr].filter(
|
|
2830
|
+
(entry) => typeof entry === 'string' && entry.trim().length > 0
|
|
2831
|
+
);
|
|
2832
|
+
const surfacedError =
|
|
2833
|
+
report.runtimeError ||
|
|
2834
|
+
report.compilerStderr ||
|
|
2835
|
+
report.compilerStdout ||
|
|
2836
|
+
null;
|
|
2837
|
+
|
|
2838
|
+
return {
|
|
2839
|
+
consoleOutput,
|
|
2840
|
+
error: surfacedError,
|
|
2841
|
+
hostCallMs: performance.now() - startedAt,
|
|
2842
|
+
diagnosticError: null,
|
|
2843
|
+
};
|
|
1201
2844
|
}
|
|
1202
2845
|
|
|
1203
2846
|
function normalizeScriptTraceEvents(events, scriptMode, userCodeLineCount, sourceLineMap) {
|
|
1204
2847
|
if (!scriptMode || !Array.isArray(events)) return events;
|
|
1205
2848
|
return events.map((event) => {
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
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;
|
|
1215
2875
|
}
|
|
1216
2876
|
}
|
|
1217
|
-
|
|
1218
|
-
const match = normalizedEvent.match(/^line=(\d+)\s+return\s+<module>$/);
|
|
1219
|
-
if (!match || !Number.isFinite(userCodeLineCount) || userCodeLineCount <= 0) {
|
|
1220
|
-
return normalizedEvent;
|
|
1221
|
-
}
|
|
1222
|
-
const line = Number.parseInt(match[1], 10);
|
|
1223
|
-
if (line <= userCodeLineCount) return normalizedEvent;
|
|
1224
|
-
return `line=${userCodeLineCount} return <module>`;
|
|
2877
|
+
return event;
|
|
1225
2878
|
});
|
|
1226
2879
|
}
|
|
1227
2880
|
|
|
1228
2881
|
function parseTraceLineNumber(event) {
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
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;
|
|
1233
2892
|
}
|
|
1234
2893
|
|
|
1235
2894
|
function isBareTraceLineEvent(event) {
|
|
1236
|
-
|
|
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 })}`;
|
|
1237
2911
|
}
|
|
1238
2912
|
|
|
1239
|
-
function
|
|
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]] : [];
|
|
2956
|
+
}
|
|
2957
|
+
|
|
2958
|
+
function buildControlHeaderInfo(sourceText) {
|
|
1240
2959
|
if (typeof sourceText !== 'string' || sourceText.length === 0) return null;
|
|
1241
2960
|
const lines = sourceText.split(/\r?\n/);
|
|
1242
|
-
const
|
|
2961
|
+
const loopBodyLineToHeader = new Map();
|
|
2962
|
+
const headerLineToExcludedVariables = new Map();
|
|
1243
2963
|
|
|
1244
2964
|
for (let index = 0; index < lines.length; index += 1) {
|
|
1245
2965
|
const line = lines[index];
|
|
1246
|
-
|
|
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;
|
|
1247
2969
|
|
|
1248
2970
|
for (let bodyIndex = index + 1; bodyIndex < lines.length; bodyIndex += 1) {
|
|
1249
2971
|
const trimmed = lines[bodyIndex].trim();
|
|
1250
2972
|
if (trimmed.length === 0) continue;
|
|
1251
2973
|
if (trimmed.startsWith('}')) break;
|
|
1252
|
-
|
|
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);
|
|
1253
2981
|
break;
|
|
1254
2982
|
}
|
|
1255
2983
|
}
|
|
1256
2984
|
|
|
1257
|
-
|
|
2985
|
+
if (loopBodyLineToHeader.size === 0 && headerLineToExcludedVariables.size === 0) return null;
|
|
2986
|
+
return { loopBodyLineToHeader, headerLineToExcludedVariables };
|
|
1258
2987
|
}
|
|
1259
2988
|
|
|
1260
2989
|
function expandLoopHeaderTraceEvents(events, sourceText) {
|
|
1261
2990
|
if (!Array.isArray(events) || events.length === 0) return events;
|
|
1262
|
-
const
|
|
1263
|
-
if (!
|
|
2991
|
+
const controlHeaderInfo = buildControlHeaderInfo(sourceText);
|
|
2992
|
+
if (!controlHeaderInfo) return events;
|
|
2993
|
+
const { loopBodyLineToHeader, headerLineToExcludedVariables } = controlHeaderInfo;
|
|
1264
2994
|
|
|
1265
2995
|
const expanded = [];
|
|
1266
|
-
|
|
2996
|
+
const latestSnapshotByVariable = new Map();
|
|
2997
|
+
for (let index = 0; index < events.length; index += 1) {
|
|
2998
|
+
const event = events[index];
|
|
1267
2999
|
const line = parseTraceLineNumber(event);
|
|
1268
|
-
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;
|
|
1269
3010
|
const previousLine = expanded.length > 0 ? parseTraceLineNumber(expanded[expanded.length - 1]) : null;
|
|
1270
3011
|
if (headerLine !== undefined && isBareTraceLineEvent(event) && previousLine !== headerLine) {
|
|
1271
|
-
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
|
+
}
|
|
1272
3027
|
}
|
|
1273
3028
|
expanded.push(event);
|
|
3029
|
+
if (snapshotVariable) {
|
|
3030
|
+
latestSnapshotByVariable.set(snapshotVariable, event);
|
|
3031
|
+
}
|
|
1274
3032
|
}
|
|
1275
3033
|
return expanded;
|
|
1276
3034
|
}
|
|
1277
3035
|
|
|
1278
|
-
|
|
3036
|
+
function normalizeJavaExecutionPayload(payload) {
|
|
1279
3037
|
assertSupportedExecutionStyle(payload.executionStyle);
|
|
1280
3038
|
if (typeof payload.code !== 'string') {
|
|
1281
3039
|
throw new Error('`code` must be a string');
|
|
@@ -1285,31 +3043,87 @@ async function runJavaRequest(payload, requestId) {
|
|
|
1285
3043
|
throw new Error('Java execution requires a non-empty functionName or class entry name.');
|
|
1286
3044
|
}
|
|
1287
3045
|
|
|
1288
|
-
const totalStart = performance.now();
|
|
1289
|
-
const rewriteStart = performance.now();
|
|
1290
|
-
let normalizedPayload;
|
|
1291
3046
|
try {
|
|
1292
|
-
|
|
3047
|
+
return normalizeJavaRequest(payload);
|
|
1293
3048
|
} catch (error) {
|
|
1294
3049
|
throw makeWorkerStageError('request normalization', error);
|
|
1295
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);
|
|
1296
3070
|
|
|
1297
3071
|
let rewrittenSource;
|
|
1298
3072
|
try {
|
|
1299
|
-
rewrittenSource = await rewriteSource(normalizedPayload,
|
|
3073
|
+
rewrittenSource = await rewriteSource(normalizedPayload, compileId, dynamicInputs);
|
|
1300
3074
|
rewrittenSource = augmentTraceCallArgumentSnapshots(rewrittenSource);
|
|
1301
3075
|
rewrittenSource = augmentArrayLengthReads(rewrittenSource);
|
|
1302
|
-
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);
|
|
1303
3084
|
rewrittenSource = augmentTraceReturnValueSnapshots(rewrittenSource);
|
|
1304
3085
|
} catch (error) {
|
|
1305
|
-
|
|
3086
|
+
const rewriteError = formatWorkerErrorMessage(error);
|
|
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
|
+
);
|
|
3095
|
+
const totalEnd = performance.now();
|
|
3096
|
+
const surfacedError =
|
|
3097
|
+
(skipDiagnosticProbe ? null : diagnosticProbe.error) ??
|
|
3098
|
+
(rewriteError === 'Java syntax error.'
|
|
3099
|
+
? 'Java syntax error. Check Code Assist for parser details.'
|
|
3100
|
+
: `Java source rewrite failed: ${rewriteError}`);
|
|
3101
|
+
return {
|
|
3102
|
+
success: false,
|
|
3103
|
+
events: [],
|
|
3104
|
+
...(normalizedPayload.sourceText ? { sourceText: normalizedPayload.sourceText } : {}),
|
|
3105
|
+
executionTimeMs: totalEnd - totalStart,
|
|
3106
|
+
consoleOutput: diagnosticProbe.consoleOutput,
|
|
3107
|
+
error: surfacedError,
|
|
3108
|
+
timings: {
|
|
3109
|
+
rewriteMs: totalEnd - rewriteStart,
|
|
3110
|
+
hostCallMs: diagnosticProbe.hostCallMs,
|
|
3111
|
+
totalMs: totalEnd - totalStart,
|
|
3112
|
+
},
|
|
3113
|
+
};
|
|
1306
3114
|
}
|
|
1307
3115
|
const rewriteEnd = performance.now();
|
|
1308
3116
|
|
|
1309
|
-
const exportsClassName = buildExportsClassName(
|
|
1310
|
-
const packageName = buildPackageName(
|
|
3117
|
+
const exportsClassName = buildExportsClassName(compileId);
|
|
3118
|
+
const packageName = buildPackageName(compileId);
|
|
1311
3119
|
const sourcePath = `/str/${exportsClassName}.java`;
|
|
1312
|
-
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
|
+
}
|
|
1313
3127
|
|
|
1314
3128
|
try {
|
|
1315
3129
|
await self.cheerpOSAddStringFile(sourcePath, rewrittenSource);
|
|
@@ -1347,9 +3161,7 @@ async function runJavaRequest(payload, requestId) {
|
|
|
1347
3161
|
throw makeWorkerStageError('trace report parse', error);
|
|
1348
3162
|
}
|
|
1349
3163
|
const totalEnd = performance.now();
|
|
1350
|
-
const consoleOutput =
|
|
1351
|
-
(entry) => typeof entry === 'string' && entry.trim().length > 0
|
|
1352
|
-
);
|
|
3164
|
+
const consoleOutput = javaReportConsoleOutput(report);
|
|
1353
3165
|
|
|
1354
3166
|
if (report.success !== true) {
|
|
1355
3167
|
return {
|
|
@@ -1388,7 +3200,7 @@ async function runJavaRequest(payload, requestId) {
|
|
|
1388
3200
|
|
|
1389
3201
|
return {
|
|
1390
3202
|
success: true,
|
|
1391
|
-
output:
|
|
3203
|
+
output: parseJavaReportOutput(report.output),
|
|
1392
3204
|
events: expandLoopHeaderTraceEvents(
|
|
1393
3205
|
normalizeScriptTraceEvents(
|
|
1394
3206
|
Array.isArray(report.events) ? report.events : [],
|
|
@@ -1420,6 +3232,226 @@ async function runJavaRequest(payload, requestId) {
|
|
|
1420
3232
|
};
|
|
1421
3233
|
}
|
|
1422
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
|
+
|
|
1423
3455
|
self.onmessage = (event) => {
|
|
1424
3456
|
const message = event.data;
|
|
1425
3457
|
if (!message || typeof message !== 'object') {
|
|
@@ -1440,22 +3472,63 @@ self.onmessage = (event) => {
|
|
|
1440
3472
|
if (message.type === 'init') {
|
|
1441
3473
|
queue = queue.then(async () => {
|
|
1442
3474
|
try {
|
|
3475
|
+
applyWorkerOptions(message.payload);
|
|
3476
|
+
const startedAt = performance.now();
|
|
1443
3477
|
await ensureReady();
|
|
1444
|
-
|
|
3478
|
+
const totalMs = performance.now() - startedAt;
|
|
1445
3479
|
postMessageResponse({
|
|
1446
3480
|
id: message.id,
|
|
1447
3481
|
type: 'init',
|
|
1448
3482
|
payload: {
|
|
1449
3483
|
success: true,
|
|
1450
|
-
loadTimeMs: Math.round(
|
|
3484
|
+
loadTimeMs: Math.round(totalMs),
|
|
3485
|
+
timings: {
|
|
3486
|
+
totalMs,
|
|
3487
|
+
initMs: initLoadTimeMs ?? 0,
|
|
3488
|
+
warmupMs: 0,
|
|
3489
|
+
},
|
|
1451
3490
|
},
|
|
1452
3491
|
});
|
|
1453
3492
|
} catch (error) {
|
|
3493
|
+
emitRuntimeDiagnostic('error', 'worker-request-failed', 'Java worker init request failed.', {
|
|
3494
|
+
type: message.type,
|
|
3495
|
+
message: formatWorkerErrorMessage(error),
|
|
3496
|
+
});
|
|
1454
3497
|
postMessageResponse({
|
|
1455
3498
|
id: message.id,
|
|
1456
3499
|
type: 'error',
|
|
1457
3500
|
payload: { error: formatWorkerErrorMessage(error) },
|
|
1458
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
|
+
});
|
|
3525
|
+
postMessageResponse({
|
|
3526
|
+
id: message.id,
|
|
3527
|
+
type: 'error',
|
|
3528
|
+
payload: { error: formatWorkerErrorMessage(error) },
|
|
3529
|
+
});
|
|
3530
|
+
} finally {
|
|
3531
|
+
resetIdleTimer();
|
|
1459
3532
|
}
|
|
1460
3533
|
});
|
|
1461
3534
|
return;
|
|
@@ -1464,23 +3537,35 @@ self.onmessage = (event) => {
|
|
|
1464
3537
|
if (
|
|
1465
3538
|
message.type === 'execute-with-tracing' ||
|
|
1466
3539
|
message.type === 'execute-code' ||
|
|
3540
|
+
message.type === 'execute-code-batch' ||
|
|
1467
3541
|
message.type === 'execute-code-interview'
|
|
1468
3542
|
) {
|
|
1469
3543
|
queue = queue.then(async () => {
|
|
1470
3544
|
try {
|
|
3545
|
+
applyWorkerOptions(message.payload);
|
|
1471
3546
|
await ensureReady();
|
|
1472
|
-
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);
|
|
1473
3552
|
postMessageResponse({
|
|
1474
3553
|
id: message.id,
|
|
1475
3554
|
type: message.type,
|
|
1476
3555
|
payload: result,
|
|
1477
3556
|
});
|
|
1478
3557
|
} catch (error) {
|
|
3558
|
+
emitRuntimeDiagnostic('error', 'worker-request-failed', 'Java worker execution request failed.', {
|
|
3559
|
+
type: message.type,
|
|
3560
|
+
message: formatWorkerErrorMessage(error),
|
|
3561
|
+
});
|
|
1479
3562
|
postMessageResponse({
|
|
1480
3563
|
id: message.id,
|
|
1481
3564
|
type: 'error',
|
|
1482
3565
|
payload: { error: formatWorkerErrorMessage(error) },
|
|
1483
3566
|
});
|
|
3567
|
+
} finally {
|
|
3568
|
+
resetIdleTimer();
|
|
1484
3569
|
}
|
|
1485
3570
|
});
|
|
1486
3571
|
return;
|
|
@@ -1488,5 +3573,6 @@ self.onmessage = (event) => {
|
|
|
1488
3573
|
};
|
|
1489
3574
|
|
|
1490
3575
|
queueMicrotask(() => {
|
|
3576
|
+
emitRuntimeDiagnostic('info', 'worker-ready', 'Java worker is ready.');
|
|
1491
3577
|
postMessageResponse({ type: 'worker-ready' });
|
|
1492
3578
|
});
|