frida 16.2.0 → 16.2.2

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.
Files changed (386) hide show
  1. package/BSDmakefile +6 -0
  2. package/Makefile +16 -0
  3. package/README.md +14 -11
  4. package/configure +18 -0
  5. package/configure.bat +22 -0
  6. package/dist/native.js +0 -8
  7. package/lib/application.ts +98 -0
  8. package/lib/authentication.ts +3 -0
  9. package/lib/build.py +50 -0
  10. package/lib/bus.ts +30 -0
  11. package/lib/cancellable.ts +33 -0
  12. package/lib/child.ts +15 -0
  13. package/lib/crash.ts +11 -0
  14. package/lib/device.ts +329 -0
  15. package/lib/device_manager.ts +69 -0
  16. package/lib/endpoint_parameters.ts +56 -0
  17. package/lib/icon.ts +15 -0
  18. package/lib/index.ts +311 -0
  19. package/lib/iostream.ts +78 -0
  20. package/lib/meson.build +53 -0
  21. package/lib/native.ts +9 -0
  22. package/lib/portal_membership.ts +10 -0
  23. package/lib/portal_service.ts +105 -0
  24. package/lib/process.ts +57 -0
  25. package/lib/relay.ts +44 -0
  26. package/lib/script.ts +352 -0
  27. package/lib/session.ts +113 -0
  28. package/lib/signals.ts +45 -0
  29. package/lib/socket_address.ts +35 -0
  30. package/lib/spawn.ts +4 -0
  31. package/lib/system_parameters.ts +78 -0
  32. package/make.bat +23 -0
  33. package/meson.build +160 -0
  34. package/meson.options +11 -0
  35. package/package.json +27 -6
  36. package/releng/deps.py +1133 -0
  37. package/releng/deps.toml +391 -0
  38. package/releng/devkit-assets/frida-core-example-unix.c +188 -0
  39. package/releng/devkit-assets/frida-core-example-windows.c +197 -0
  40. package/releng/devkit-assets/frida-core-example.sln +28 -0
  41. package/releng/devkit-assets/frida-core-example.vcxproj +157 -0
  42. package/releng/devkit-assets/frida-core-example.vcxproj.filters +27 -0
  43. package/releng/devkit-assets/frida-gum-example-unix.c +122 -0
  44. package/releng/devkit-assets/frida-gum-example-windows.c +132 -0
  45. package/releng/devkit-assets/frida-gum-example.sln +28 -0
  46. package/releng/devkit-assets/frida-gum-example.vcxproj +157 -0
  47. package/releng/devkit-assets/frida-gum-example.vcxproj.filters +27 -0
  48. package/releng/devkit-assets/frida-gumjs-example-unix.c +84 -0
  49. package/releng/devkit-assets/frida-gumjs-example-windows.c +91 -0
  50. package/releng/devkit-assets/frida-gumjs-example.sln +28 -0
  51. package/releng/devkit-assets/frida-gumjs-example.vcxproj +157 -0
  52. package/releng/devkit-assets/frida-gumjs-example.vcxproj.filters +27 -0
  53. package/releng/devkit.py +535 -0
  54. package/releng/env.py +420 -0
  55. package/releng/env_android.py +150 -0
  56. package/releng/env_apple.py +176 -0
  57. package/releng/env_generic.py +373 -0
  58. package/releng/frida_version.py +69 -0
  59. package/releng/machine_file.py +44 -0
  60. package/releng/machine_spec.py +290 -0
  61. package/releng/meson/meson.py +27 -0
  62. package/releng/meson/mesonbuild/__init__.py +0 -0
  63. package/releng/meson/mesonbuild/_pathlib.py +63 -0
  64. package/releng/meson/mesonbuild/_typing.py +69 -0
  65. package/releng/meson/mesonbuild/arglist.py +321 -0
  66. package/releng/meson/mesonbuild/ast/__init__.py +23 -0
  67. package/releng/meson/mesonbuild/ast/interpreter.py +441 -0
  68. package/releng/meson/mesonbuild/ast/introspection.py +374 -0
  69. package/releng/meson/mesonbuild/ast/postprocess.py +109 -0
  70. package/releng/meson/mesonbuild/ast/printer.py +620 -0
  71. package/releng/meson/mesonbuild/ast/visitor.py +161 -0
  72. package/releng/meson/mesonbuild/backend/__init__.py +0 -0
  73. package/releng/meson/mesonbuild/backend/backends.py +2047 -0
  74. package/releng/meson/mesonbuild/backend/ninjabackend.py +3808 -0
  75. package/releng/meson/mesonbuild/backend/nonebackend.py +26 -0
  76. package/releng/meson/mesonbuild/backend/vs2010backend.py +2078 -0
  77. package/releng/meson/mesonbuild/backend/vs2012backend.py +35 -0
  78. package/releng/meson/mesonbuild/backend/vs2013backend.py +34 -0
  79. package/releng/meson/mesonbuild/backend/vs2015backend.py +35 -0
  80. package/releng/meson/mesonbuild/backend/vs2017backend.py +59 -0
  81. package/releng/meson/mesonbuild/backend/vs2019backend.py +54 -0
  82. package/releng/meson/mesonbuild/backend/vs2022backend.py +54 -0
  83. package/releng/meson/mesonbuild/backend/xcodebackend.py +1781 -0
  84. package/releng/meson/mesonbuild/build.py +3249 -0
  85. package/releng/meson/mesonbuild/cargo/__init__.py +5 -0
  86. package/releng/meson/mesonbuild/cargo/builder.py +238 -0
  87. package/releng/meson/mesonbuild/cargo/cfg.py +274 -0
  88. package/releng/meson/mesonbuild/cargo/interpreter.py +733 -0
  89. package/releng/meson/mesonbuild/cargo/manifest.py +227 -0
  90. package/releng/meson/mesonbuild/cargo/version.py +95 -0
  91. package/releng/meson/mesonbuild/cmake/__init__.py +28 -0
  92. package/releng/meson/mesonbuild/cmake/common.py +331 -0
  93. package/releng/meson/mesonbuild/cmake/data/__init__.py +0 -0
  94. package/releng/meson/mesonbuild/cmake/data/preload.cmake +82 -0
  95. package/releng/meson/mesonbuild/cmake/executor.py +241 -0
  96. package/releng/meson/mesonbuild/cmake/fileapi.py +324 -0
  97. package/releng/meson/mesonbuild/cmake/generator.py +186 -0
  98. package/releng/meson/mesonbuild/cmake/interpreter.py +1267 -0
  99. package/releng/meson/mesonbuild/cmake/toolchain.py +248 -0
  100. package/releng/meson/mesonbuild/cmake/traceparser.py +814 -0
  101. package/releng/meson/mesonbuild/cmake/tracetargets.py +161 -0
  102. package/releng/meson/mesonbuild/compilers/__init__.py +86 -0
  103. package/releng/meson/mesonbuild/compilers/asm.py +307 -0
  104. package/releng/meson/mesonbuild/compilers/c.py +788 -0
  105. package/releng/meson/mesonbuild/compilers/c_function_attributes.py +143 -0
  106. package/releng/meson/mesonbuild/compilers/compilers.py +1388 -0
  107. package/releng/meson/mesonbuild/compilers/cpp.py +1035 -0
  108. package/releng/meson/mesonbuild/compilers/cs.py +136 -0
  109. package/releng/meson/mesonbuild/compilers/cuda.py +806 -0
  110. package/releng/meson/mesonbuild/compilers/cython.py +91 -0
  111. package/releng/meson/mesonbuild/compilers/d.py +861 -0
  112. package/releng/meson/mesonbuild/compilers/detect.py +1396 -0
  113. package/releng/meson/mesonbuild/compilers/fortran.py +523 -0
  114. package/releng/meson/mesonbuild/compilers/java.py +113 -0
  115. package/releng/meson/mesonbuild/compilers/mixins/__init__.py +0 -0
  116. package/releng/meson/mesonbuild/compilers/mixins/arm.py +167 -0
  117. package/releng/meson/mesonbuild/compilers/mixins/ccrx.py +113 -0
  118. package/releng/meson/mesonbuild/compilers/mixins/clang.py +170 -0
  119. package/releng/meson/mesonbuild/compilers/mixins/clike.py +1330 -0
  120. package/releng/meson/mesonbuild/compilers/mixins/compcert.py +117 -0
  121. package/releng/meson/mesonbuild/compilers/mixins/elbrus.py +93 -0
  122. package/releng/meson/mesonbuild/compilers/mixins/emscripten.py +89 -0
  123. package/releng/meson/mesonbuild/compilers/mixins/gnu.py +629 -0
  124. package/releng/meson/mesonbuild/compilers/mixins/intel.py +167 -0
  125. package/releng/meson/mesonbuild/compilers/mixins/islinker.py +120 -0
  126. package/releng/meson/mesonbuild/compilers/mixins/metrowerks.py +279 -0
  127. package/releng/meson/mesonbuild/compilers/mixins/pgi.py +88 -0
  128. package/releng/meson/mesonbuild/compilers/mixins/ti.py +130 -0
  129. package/releng/meson/mesonbuild/compilers/mixins/visualstudio.py +458 -0
  130. package/releng/meson/mesonbuild/compilers/mixins/xc16.py +111 -0
  131. package/releng/meson/mesonbuild/compilers/objc.py +120 -0
  132. package/releng/meson/mesonbuild/compilers/objcpp.py +102 -0
  133. package/releng/meson/mesonbuild/compilers/rust.py +230 -0
  134. package/releng/meson/mesonbuild/compilers/swift.py +131 -0
  135. package/releng/meson/mesonbuild/compilers/vala.py +121 -0
  136. package/releng/meson/mesonbuild/coredata.py +1532 -0
  137. package/releng/meson/mesonbuild/dependencies/__init__.py +252 -0
  138. package/releng/meson/mesonbuild/dependencies/base.py +663 -0
  139. package/releng/meson/mesonbuild/dependencies/boost.py +1083 -0
  140. package/releng/meson/mesonbuild/dependencies/cmake.py +656 -0
  141. package/releng/meson/mesonbuild/dependencies/coarrays.py +80 -0
  142. package/releng/meson/mesonbuild/dependencies/configtool.py +163 -0
  143. package/releng/meson/mesonbuild/dependencies/cuda.py +295 -0
  144. package/releng/meson/mesonbuild/dependencies/data/CMakeLists.txt +102 -0
  145. package/releng/meson/mesonbuild/dependencies/data/CMakeListsLLVM.txt +204 -0
  146. package/releng/meson/mesonbuild/dependencies/data/CMakePathInfo.txt +31 -0
  147. package/releng/meson/mesonbuild/dependencies/data/__init__.py +0 -0
  148. package/releng/meson/mesonbuild/dependencies/detect.py +225 -0
  149. package/releng/meson/mesonbuild/dependencies/dev.py +707 -0
  150. package/releng/meson/mesonbuild/dependencies/dub.py +424 -0
  151. package/releng/meson/mesonbuild/dependencies/factory.py +146 -0
  152. package/releng/meson/mesonbuild/dependencies/framework.py +111 -0
  153. package/releng/meson/mesonbuild/dependencies/hdf5.py +168 -0
  154. package/releng/meson/mesonbuild/dependencies/misc.py +618 -0
  155. package/releng/meson/mesonbuild/dependencies/mpi.py +231 -0
  156. package/releng/meson/mesonbuild/dependencies/pkgconfig.py +570 -0
  157. package/releng/meson/mesonbuild/dependencies/platform.py +52 -0
  158. package/releng/meson/mesonbuild/dependencies/python.py +431 -0
  159. package/releng/meson/mesonbuild/dependencies/qt.py +484 -0
  160. package/releng/meson/mesonbuild/dependencies/scalapack.py +142 -0
  161. package/releng/meson/mesonbuild/dependencies/ui.py +281 -0
  162. package/releng/meson/mesonbuild/depfile.py +82 -0
  163. package/releng/meson/mesonbuild/envconfig.py +480 -0
  164. package/releng/meson/mesonbuild/environment.py +987 -0
  165. package/releng/meson/mesonbuild/interpreter/__init__.py +47 -0
  166. package/releng/meson/mesonbuild/interpreter/compiler.py +900 -0
  167. package/releng/meson/mesonbuild/interpreter/dependencyfallbacks.py +386 -0
  168. package/releng/meson/mesonbuild/interpreter/interpreter.py +3595 -0
  169. package/releng/meson/mesonbuild/interpreter/interpreterobjects.py +1096 -0
  170. package/releng/meson/mesonbuild/interpreter/kwargs.py +479 -0
  171. package/releng/meson/mesonbuild/interpreter/mesonmain.py +487 -0
  172. package/releng/meson/mesonbuild/interpreter/primitives/__init__.py +29 -0
  173. package/releng/meson/mesonbuild/interpreter/primitives/array.py +108 -0
  174. package/releng/meson/mesonbuild/interpreter/primitives/boolean.py +52 -0
  175. package/releng/meson/mesonbuild/interpreter/primitives/dict.py +88 -0
  176. package/releng/meson/mesonbuild/interpreter/primitives/integer.py +86 -0
  177. package/releng/meson/mesonbuild/interpreter/primitives/range.py +38 -0
  178. package/releng/meson/mesonbuild/interpreter/primitives/string.py +247 -0
  179. package/releng/meson/mesonbuild/interpreter/type_checking.py +853 -0
  180. package/releng/meson/mesonbuild/interpreterbase/__init__.py +126 -0
  181. package/releng/meson/mesonbuild/interpreterbase/_unholder.py +25 -0
  182. package/releng/meson/mesonbuild/interpreterbase/baseobjects.py +174 -0
  183. package/releng/meson/mesonbuild/interpreterbase/decorators.py +806 -0
  184. package/releng/meson/mesonbuild/interpreterbase/disabler.py +35 -0
  185. package/releng/meson/mesonbuild/interpreterbase/exceptions.py +22 -0
  186. package/releng/meson/mesonbuild/interpreterbase/helpers.py +67 -0
  187. package/releng/meson/mesonbuild/interpreterbase/interpreterbase.py +665 -0
  188. package/releng/meson/mesonbuild/interpreterbase/operator.py +32 -0
  189. package/releng/meson/mesonbuild/linkers/__init__.py +20 -0
  190. package/releng/meson/mesonbuild/linkers/base.py +39 -0
  191. package/releng/meson/mesonbuild/linkers/detect.py +229 -0
  192. package/releng/meson/mesonbuild/linkers/linkers.py +1614 -0
  193. package/releng/meson/mesonbuild/mcompile.py +380 -0
  194. package/releng/meson/mesonbuild/mconf.py +368 -0
  195. package/releng/meson/mesonbuild/mdevenv.py +234 -0
  196. package/releng/meson/mesonbuild/mdist.py +376 -0
  197. package/releng/meson/mesonbuild/mesondata.py +38 -0
  198. package/releng/meson/mesonbuild/mesonlib.py +23 -0
  199. package/releng/meson/mesonbuild/mesonmain.py +289 -0
  200. package/releng/meson/mesonbuild/minit.py +204 -0
  201. package/releng/meson/mesonbuild/minstall.py +864 -0
  202. package/releng/meson/mesonbuild/mintro.py +667 -0
  203. package/releng/meson/mesonbuild/mlog.py +542 -0
  204. package/releng/meson/mesonbuild/modules/__init__.py +270 -0
  205. package/releng/meson/mesonbuild/modules/cmake.py +442 -0
  206. package/releng/meson/mesonbuild/modules/cuda.py +377 -0
  207. package/releng/meson/mesonbuild/modules/dlang.py +117 -0
  208. package/releng/meson/mesonbuild/modules/external_project.py +306 -0
  209. package/releng/meson/mesonbuild/modules/fs.py +323 -0
  210. package/releng/meson/mesonbuild/modules/gnome.py +2215 -0
  211. package/releng/meson/mesonbuild/modules/hotdoc.py +487 -0
  212. package/releng/meson/mesonbuild/modules/i18n.py +405 -0
  213. package/releng/meson/mesonbuild/modules/icestorm.py +123 -0
  214. package/releng/meson/mesonbuild/modules/java.py +112 -0
  215. package/releng/meson/mesonbuild/modules/keyval.py +65 -0
  216. package/releng/meson/mesonbuild/modules/modtest.py +33 -0
  217. package/releng/meson/mesonbuild/modules/pkgconfig.py +744 -0
  218. package/releng/meson/mesonbuild/modules/python.py +556 -0
  219. package/releng/meson/mesonbuild/modules/python3.py +85 -0
  220. package/releng/meson/mesonbuild/modules/qt.py +621 -0
  221. package/releng/meson/mesonbuild/modules/qt4.py +23 -0
  222. package/releng/meson/mesonbuild/modules/qt5.py +23 -0
  223. package/releng/meson/mesonbuild/modules/qt6.py +22 -0
  224. package/releng/meson/mesonbuild/modules/rust.py +355 -0
  225. package/releng/meson/mesonbuild/modules/simd.py +114 -0
  226. package/releng/meson/mesonbuild/modules/sourceset.py +291 -0
  227. package/releng/meson/mesonbuild/modules/wayland.py +151 -0
  228. package/releng/meson/mesonbuild/modules/windows.py +207 -0
  229. package/releng/meson/mesonbuild/mparser.py +1114 -0
  230. package/releng/meson/mesonbuild/msetup.py +365 -0
  231. package/releng/meson/mesonbuild/msubprojects.py +764 -0
  232. package/releng/meson/mesonbuild/mtest.py +2201 -0
  233. package/releng/meson/mesonbuild/munstable_coredata.py +107 -0
  234. package/releng/meson/mesonbuild/optinterpreter.py +276 -0
  235. package/releng/meson/mesonbuild/programs.py +367 -0
  236. package/releng/meson/mesonbuild/rewriter.py +1075 -0
  237. package/releng/meson/mesonbuild/scripts/__init__.py +10 -0
  238. package/releng/meson/mesonbuild/scripts/clangformat.py +55 -0
  239. package/releng/meson/mesonbuild/scripts/clangtidy.py +30 -0
  240. package/releng/meson/mesonbuild/scripts/cleantrees.py +35 -0
  241. package/releng/meson/mesonbuild/scripts/cmake_run_ctgt.py +103 -0
  242. package/releng/meson/mesonbuild/scripts/cmd_or_ps.ps1 +17 -0
  243. package/releng/meson/mesonbuild/scripts/copy.py +19 -0
  244. package/releng/meson/mesonbuild/scripts/coverage.py +214 -0
  245. package/releng/meson/mesonbuild/scripts/delwithsuffix.py +27 -0
  246. package/releng/meson/mesonbuild/scripts/depfixer.py +495 -0
  247. package/releng/meson/mesonbuild/scripts/depscan.py +198 -0
  248. package/releng/meson/mesonbuild/scripts/dirchanger.py +20 -0
  249. package/releng/meson/mesonbuild/scripts/env2mfile.py +402 -0
  250. package/releng/meson/mesonbuild/scripts/externalproject.py +106 -0
  251. package/releng/meson/mesonbuild/scripts/gettext.py +86 -0
  252. package/releng/meson/mesonbuild/scripts/gtkdochelper.py +286 -0
  253. package/releng/meson/mesonbuild/scripts/hotdochelper.py +40 -0
  254. package/releng/meson/mesonbuild/scripts/itstool.py +77 -0
  255. package/releng/meson/mesonbuild/scripts/meson_exe.py +115 -0
  256. package/releng/meson/mesonbuild/scripts/msgfmthelper.py +29 -0
  257. package/releng/meson/mesonbuild/scripts/pycompile.py +54 -0
  258. package/releng/meson/mesonbuild/scripts/python_info.py +121 -0
  259. package/releng/meson/mesonbuild/scripts/regen_checker.py +55 -0
  260. package/releng/meson/mesonbuild/scripts/run_tool.py +58 -0
  261. package/releng/meson/mesonbuild/scripts/scanbuild.py +57 -0
  262. package/releng/meson/mesonbuild/scripts/symbolextractor.py +322 -0
  263. package/releng/meson/mesonbuild/scripts/tags.py +44 -0
  264. package/releng/meson/mesonbuild/scripts/test_loaded_modules.py +14 -0
  265. package/releng/meson/mesonbuild/scripts/uninstall.py +41 -0
  266. package/releng/meson/mesonbuild/scripts/vcstagger.py +35 -0
  267. package/releng/meson/mesonbuild/scripts/yasm.py +24 -0
  268. package/releng/meson/mesonbuild/templates/__init__.py +0 -0
  269. package/releng/meson/mesonbuild/templates/cpptemplates.py +143 -0
  270. package/releng/meson/mesonbuild/templates/cstemplates.py +90 -0
  271. package/releng/meson/mesonbuild/templates/ctemplates.py +126 -0
  272. package/releng/meson/mesonbuild/templates/cudatemplates.py +143 -0
  273. package/releng/meson/mesonbuild/templates/dlangtemplates.py +109 -0
  274. package/releng/meson/mesonbuild/templates/fortrantemplates.py +101 -0
  275. package/releng/meson/mesonbuild/templates/javatemplates.py +94 -0
  276. package/releng/meson/mesonbuild/templates/mesontemplates.py +70 -0
  277. package/releng/meson/mesonbuild/templates/objcpptemplates.py +126 -0
  278. package/releng/meson/mesonbuild/templates/objctemplates.py +126 -0
  279. package/releng/meson/mesonbuild/templates/rusttemplates.py +79 -0
  280. package/releng/meson/mesonbuild/templates/samplefactory.py +41 -0
  281. package/releng/meson/mesonbuild/templates/sampleimpl.py +160 -0
  282. package/releng/meson/mesonbuild/templates/valatemplates.py +82 -0
  283. package/releng/meson/mesonbuild/utils/__init__.py +0 -0
  284. package/releng/meson/mesonbuild/utils/core.py +166 -0
  285. package/releng/meson/mesonbuild/utils/platform.py +27 -0
  286. package/releng/meson/mesonbuild/utils/posix.py +32 -0
  287. package/releng/meson/mesonbuild/utils/universal.py +2445 -0
  288. package/releng/meson/mesonbuild/utils/vsenv.py +126 -0
  289. package/releng/meson/mesonbuild/utils/win32.py +29 -0
  290. package/releng/meson/mesonbuild/wrap/__init__.py +59 -0
  291. package/releng/meson/mesonbuild/wrap/wrap.py +846 -0
  292. package/releng/meson/mesonbuild/wrap/wraptool.py +198 -0
  293. package/releng/meson-scripts/BSDmakefile +6 -0
  294. package/releng/meson-scripts/Makefile +16 -0
  295. package/releng/meson-scripts/configure +18 -0
  296. package/releng/meson-scripts/configure.bat +22 -0
  297. package/releng/meson-scripts/make.bat +23 -0
  298. package/releng/meson_configure.py +506 -0
  299. package/releng/meson_make.py +131 -0
  300. package/releng/mkdevkit.py +107 -0
  301. package/releng/mkfatmacho.py +54 -0
  302. package/releng/post-process-oabi.py +97 -0
  303. package/releng/progress.py +14 -0
  304. package/releng/sync-from-upstream.py +185 -0
  305. package/releng/tomlkit/tomlkit/__init__.py +59 -0
  306. package/releng/tomlkit/tomlkit/_compat.py +22 -0
  307. package/releng/tomlkit/tomlkit/_types.py +83 -0
  308. package/releng/tomlkit/tomlkit/_utils.py +158 -0
  309. package/releng/tomlkit/tomlkit/api.py +308 -0
  310. package/releng/tomlkit/tomlkit/container.py +875 -0
  311. package/releng/tomlkit/tomlkit/exceptions.py +227 -0
  312. package/releng/tomlkit/tomlkit/items.py +1967 -0
  313. package/releng/tomlkit/tomlkit/parser.py +1141 -0
  314. package/releng/tomlkit/tomlkit/py.typed +0 -0
  315. package/releng/tomlkit/tomlkit/source.py +180 -0
  316. package/releng/tomlkit/tomlkit/toml_char.py +52 -0
  317. package/releng/tomlkit/tomlkit/toml_document.py +7 -0
  318. package/releng/tomlkit/tomlkit/toml_file.py +58 -0
  319. package/releng/winenv.py +140 -0
  320. package/scripts/adjust-version.py +19 -0
  321. package/scripts/detect-version.py +40 -0
  322. package/scripts/fetch-abi-bits.py +343 -0
  323. package/scripts/install.js +23 -0
  324. package/scripts/package.py +15 -0
  325. package/src/addon.cc +76 -0
  326. package/src/application.cc +148 -0
  327. package/src/application.h +31 -0
  328. package/src/authentication.cc +174 -0
  329. package/src/authentication.h +24 -0
  330. package/src/bus.cc +167 -0
  331. package/src/bus.h +33 -0
  332. package/src/cancellable.cc +117 -0
  333. package/src/cancellable.h +31 -0
  334. package/src/child.cc +150 -0
  335. package/src/child.h +32 -0
  336. package/src/crash.cc +122 -0
  337. package/src/crash.h +30 -0
  338. package/src/device.cc +1302 -0
  339. package/src/device.h +55 -0
  340. package/src/device_manager.cc +362 -0
  341. package/src/device_manager.h +35 -0
  342. package/src/endpoint_parameters.cc +171 -0
  343. package/src/endpoint_parameters.h +28 -0
  344. package/src/glib_context.cc +62 -0
  345. package/src/glib_context.h +29 -0
  346. package/src/glib_object.cc +25 -0
  347. package/src/glib_object.h +37 -0
  348. package/src/iostream.cc +247 -0
  349. package/src/iostream.h +30 -0
  350. package/src/meson.build +26 -0
  351. package/src/operation.h +94 -0
  352. package/src/portal_membership.cc +100 -0
  353. package/src/portal_membership.h +26 -0
  354. package/src/portal_service.cc +401 -0
  355. package/src/portal_service.h +40 -0
  356. package/src/process.cc +135 -0
  357. package/src/process.h +30 -0
  358. package/src/relay.cc +139 -0
  359. package/src/relay.h +31 -0
  360. package/src/runtime.cc +443 -0
  361. package/src/runtime.h +64 -0
  362. package/src/script.cc +301 -0
  363. package/src/script.h +36 -0
  364. package/src/session.cc +860 -0
  365. package/src/session.h +42 -0
  366. package/src/signals.cc +334 -0
  367. package/src/signals.h +47 -0
  368. package/src/spawn.cc +95 -0
  369. package/src/spawn.h +27 -0
  370. package/src/usage_monitor.h +117 -0
  371. package/src/uv_context.cc +118 -0
  372. package/src/uv_context.h +40 -0
  373. package/src/win_delay_load_hook.cc +63 -0
  374. package/subprojects/frida-core.wrap +8 -0
  375. package/subprojects/nan.wrap +9 -0
  376. package/subprojects/packagefiles/nan.patch +13 -0
  377. package/test/data/index.ts +13 -0
  378. package/test/data/unixvictim-linux-x86 +0 -0
  379. package/test/data/unixvictim-linux-x86_64 +0 -0
  380. package/test/data/unixvictim-macos +0 -0
  381. package/test/device.ts +27 -0
  382. package/test/device_manager.ts +16 -0
  383. package/test/labrat.ts +32 -0
  384. package/test/script.ts +176 -0
  385. package/test/session.ts +73 -0
  386. package/tsconfig.json +18 -0
@@ -0,0 +1,1114 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ # Copyright 2014-2017 The Meson development team
3
+
4
+ from __future__ import annotations
5
+ from dataclasses import dataclass, field
6
+ import re
7
+ import codecs
8
+ import os
9
+ import typing as T
10
+
11
+ from .mesonlib import MesonException
12
+ from . import mlog
13
+
14
+ if T.TYPE_CHECKING:
15
+ from typing_extensions import Literal
16
+
17
+ from .ast import AstVisitor
18
+
19
+ BaseNodeT = T.TypeVar('BaseNodeT', bound='BaseNode')
20
+
21
+ # This is the regex for the supported escape sequences of a regular string
22
+ # literal, like 'abc\x00'
23
+ ESCAPE_SEQUENCE_SINGLE_RE = re.compile(r'''
24
+ ( \\U[A-Fa-f0-9]{8} # 8-digit hex escapes
25
+ | \\u[A-Fa-f0-9]{4} # 4-digit hex escapes
26
+ | \\x[A-Fa-f0-9]{2} # 2-digit hex escapes
27
+ | \\[0-7]{1,3} # Octal escapes
28
+ | \\N\{[^}]+\} # Unicode characters by name
29
+ | \\[\\'abfnrtv] # Single-character escapes
30
+ )''', re.UNICODE | re.VERBOSE)
31
+
32
+ def decode_match(match: T.Match[str]) -> str:
33
+ return codecs.decode(match.group(0).encode(), 'unicode_escape')
34
+
35
+ class ParseException(MesonException):
36
+
37
+ ast: T.Optional[CodeBlockNode] = None
38
+
39
+ def __init__(self, text: str, line: str, lineno: int, colno: int) -> None:
40
+ # Format as error message, followed by the line with the error, followed by a caret to show the error column.
41
+ super().__init__(mlog.code_line(text, line, colno))
42
+ self.lineno = lineno
43
+ self.colno = colno
44
+
45
+ class BlockParseException(ParseException):
46
+ def __init__(
47
+ self,
48
+ text: str,
49
+ line: str,
50
+ lineno: int,
51
+ colno: int,
52
+ start_line: str,
53
+ start_lineno: int,
54
+ start_colno: int,
55
+ ) -> None:
56
+ # This can be formatted in two ways - one if the block start and end are on the same line, and a different way if they are on different lines.
57
+
58
+ if lineno == start_lineno:
59
+ # If block start and end are on the same line, it is formatted as:
60
+ # Error message
61
+ # Followed by the line with the error
62
+ # Followed by a caret to show the block start
63
+ # Followed by underscores
64
+ # Followed by a caret to show the block end.
65
+ MesonException.__init__(self, "{}\n{}\n{}".format(text, line, '{}^{}^'.format(' ' * start_colno, '_' * (colno - start_colno - 1))))
66
+ else:
67
+ # If block start and end are on different lines, it is formatted as:
68
+ # Error message
69
+ # Followed by the line with the error
70
+ # Followed by a caret to show the error column.
71
+ # Followed by a message saying where the block started.
72
+ # Followed by the line of the block start.
73
+ # Followed by a caret for the block start.
74
+ MesonException.__init__(self, "%s\n%s\n%s\nFor a block that started at %d,%d\n%s\n%s" % (text, line, '%s^' % (' ' * colno), start_lineno, start_colno, start_line, "%s^" % (' ' * start_colno)))
75
+ self.lineno = lineno
76
+ self.colno = colno
77
+
78
+ TV_TokenTypes = T.TypeVar('TV_TokenTypes', int, str, bool)
79
+
80
+ @dataclass(eq=False)
81
+ class Token(T.Generic[TV_TokenTypes]):
82
+ tid: str
83
+ filename: str
84
+ line_start: int
85
+ lineno: int
86
+ colno: int
87
+ bytespan: T.Tuple[int, int]
88
+ value: TV_TokenTypes
89
+
90
+ def __eq__(self, other: object) -> bool:
91
+ if isinstance(other, str):
92
+ return self.tid == other
93
+ elif isinstance(other, Token):
94
+ return self.tid == other.tid
95
+ return NotImplemented
96
+
97
+ class Lexer:
98
+ def __init__(self, code: str):
99
+ if code.startswith(codecs.BOM_UTF8.decode('utf-8')):
100
+ line, *_ = code.split('\n', maxsplit=1)
101
+ raise ParseException('Builder file must be encoded in UTF-8 (with no BOM)', line, lineno=0, colno=0)
102
+
103
+ self.code = code
104
+ self.keywords = {'true', 'false', 'if', 'else', 'elif',
105
+ 'endif', 'and', 'or', 'not', 'foreach', 'endforeach',
106
+ 'in', 'continue', 'break'}
107
+ self.future_keywords = {'return'}
108
+ self.in_unit_test = 'MESON_RUNNING_IN_PROJECT_TESTS' in os.environ
109
+ if self.in_unit_test:
110
+ self.keywords.update({'testcase', 'endtestcase'})
111
+ self.token_specification = [
112
+ # Need to be sorted longest to shortest.
113
+ ('whitespace', re.compile(r'[ \t]+')),
114
+ ('multiline_fstring', re.compile(r"f'''(.|\n)*?'''", re.M)),
115
+ ('fstring', re.compile(r"f'([^'\\]|(\\.))*'")),
116
+ ('id', re.compile('[_a-zA-Z][_0-9a-zA-Z]*')),
117
+ ('number', re.compile(r'0[bB][01]+|0[oO][0-7]+|0[xX][0-9a-fA-F]+|0|[1-9]\d*')),
118
+ ('eol_cont', re.compile(r'\\[ \t]*(#.*)?\n')),
119
+ ('eol', re.compile(r'\n')),
120
+ ('multiline_string', re.compile(r"'''(.|\n)*?'''", re.M)),
121
+ ('comment', re.compile(r'#.*')),
122
+ ('lparen', re.compile(r'\(')),
123
+ ('rparen', re.compile(r'\)')),
124
+ ('lbracket', re.compile(r'\[')),
125
+ ('rbracket', re.compile(r'\]')),
126
+ ('lcurl', re.compile(r'\{')),
127
+ ('rcurl', re.compile(r'\}')),
128
+ ('dblquote', re.compile(r'"')),
129
+ ('string', re.compile(r"'([^'\\]|(\\.))*'")),
130
+ ('comma', re.compile(r',')),
131
+ ('plusassign', re.compile(r'\+=')),
132
+ ('dot', re.compile(r'\.')),
133
+ ('plus', re.compile(r'\+')),
134
+ ('dash', re.compile(r'-')),
135
+ ('star', re.compile(r'\*')),
136
+ ('percent', re.compile(r'%')),
137
+ ('fslash', re.compile(r'/')),
138
+ ('colon', re.compile(r':')),
139
+ ('equal', re.compile(r'==')),
140
+ ('nequal', re.compile(r'!=')),
141
+ ('assign', re.compile(r'=')),
142
+ ('le', re.compile(r'<=')),
143
+ ('lt', re.compile(r'<')),
144
+ ('ge', re.compile(r'>=')),
145
+ ('gt', re.compile(r'>')),
146
+ ('questionmark', re.compile(r'\?')),
147
+ ]
148
+
149
+ def getline(self, line_start: int) -> str:
150
+ return self.code[line_start:self.code.find('\n', line_start)]
151
+
152
+ def lex(self, filename: str) -> T.Generator[Token, None, None]:
153
+ line_start = 0
154
+ lineno = 1
155
+ loc = 0
156
+ par_count = 0
157
+ bracket_count = 0
158
+ curl_count = 0
159
+ col = 0
160
+ while loc < len(self.code):
161
+ matched = False
162
+ value: str = ''
163
+ for (tid, reg) in self.token_specification:
164
+ mo = reg.match(self.code, loc)
165
+ if mo:
166
+ curline = lineno
167
+ curline_start = line_start
168
+ col = mo.start() - line_start
169
+ matched = True
170
+ span_start = loc
171
+ loc = mo.end()
172
+ span_end = loc
173
+ bytespan = (span_start, span_end)
174
+ value = mo.group()
175
+ if tid == 'lparen':
176
+ par_count += 1
177
+ elif tid == 'rparen':
178
+ par_count -= 1
179
+ elif tid == 'lbracket':
180
+ bracket_count += 1
181
+ elif tid == 'rbracket':
182
+ bracket_count -= 1
183
+ elif tid == 'lcurl':
184
+ curl_count += 1
185
+ elif tid == 'rcurl':
186
+ curl_count -= 1
187
+ elif tid == 'dblquote':
188
+ raise ParseException('Double quotes are not supported. Use single quotes.', self.getline(line_start), lineno, col)
189
+ elif tid in {'string', 'fstring'}:
190
+ if value.find("\n") != -1:
191
+ msg = ("Newline character in a string detected, use ''' (three single quotes) "
192
+ "for multiline strings instead.\n"
193
+ "This will become a hard error in a future Meson release.")
194
+ mlog.warning(mlog.code_line(msg, self.getline(line_start), col), location=BaseNode(lineno, col, filename))
195
+ value = value[2 if tid == 'fstring' else 1:-1]
196
+ elif tid in {'multiline_string', 'multiline_fstring'}:
197
+ value = value[4 if tid == 'multiline_fstring' else 3:-3]
198
+ lines = value.split('\n')
199
+ if len(lines) > 1:
200
+ lineno += len(lines) - 1
201
+ line_start = mo.end() - len(lines[-1])
202
+ elif tid == 'eol_cont':
203
+ lineno += 1
204
+ line_start = loc
205
+ tid = 'whitespace'
206
+ elif tid == 'eol':
207
+ lineno += 1
208
+ line_start = loc
209
+ if par_count > 0 or bracket_count > 0 or curl_count > 0:
210
+ tid = 'whitespace'
211
+ elif tid == 'id':
212
+ if value in self.keywords:
213
+ tid = value
214
+ else:
215
+ if value in self.future_keywords:
216
+ mlog.warning(f"Identifier '{value}' will become a reserved keyword in a future release. Please rename it.",
217
+ location=BaseNode(lineno, col, filename))
218
+ yield Token(tid, filename, curline_start, curline, col, bytespan, value)
219
+ break
220
+ if not matched:
221
+ raise ParseException('lexer', self.getline(line_start), lineno, col)
222
+
223
+ @dataclass
224
+ class BaseNode:
225
+ lineno: int
226
+ colno: int
227
+ filename: str = field(hash=False)
228
+ end_lineno: int = field(hash=False)
229
+ end_colno: int = field(hash=False)
230
+ whitespaces: T.Optional[WhitespaceNode] = field(hash=False)
231
+
232
+ def __init__(self, lineno: int, colno: int, filename: str,
233
+ end_lineno: T.Optional[int] = None, end_colno: T.Optional[int] = None) -> None:
234
+ self.lineno = lineno
235
+ self.colno = colno
236
+ self.filename = filename
237
+ self.end_lineno = end_lineno if end_lineno is not None else lineno
238
+ self.end_colno = end_colno if end_colno is not None else colno
239
+ self.whitespaces = None
240
+
241
+ # Attributes for the visitors
242
+ self.level = 0
243
+ self.ast_id = ''
244
+ self.condition_level = 0
245
+
246
+ def accept(self, visitor: 'AstVisitor') -> None:
247
+ fname = 'visit_{}'.format(type(self).__name__)
248
+ if hasattr(visitor, fname):
249
+ func = getattr(visitor, fname)
250
+ if callable(func):
251
+ func(self)
252
+
253
+ def append_whitespaces(self, token: Token) -> None:
254
+ if self.whitespaces is None:
255
+ self.whitespaces = WhitespaceNode(token)
256
+ else:
257
+ self.whitespaces.append(token)
258
+
259
+
260
+ @dataclass(unsafe_hash=True)
261
+ class WhitespaceNode(BaseNode):
262
+
263
+ value: str
264
+
265
+ def __init__(self, token: Token[str]):
266
+ super().__init__(token.lineno, token.colno, token.filename)
267
+ self.value = ''
268
+ self.append(token)
269
+
270
+ def append(self, token: Token[str]) -> None:
271
+ self.value += token.value
272
+
273
+ @dataclass(unsafe_hash=True)
274
+ class ElementaryNode(T.Generic[TV_TokenTypes], BaseNode):
275
+
276
+ value: TV_TokenTypes
277
+ bytespan: T.Tuple[int, int] = field(hash=False)
278
+
279
+ def __init__(self, token: Token[TV_TokenTypes]):
280
+ super().__init__(token.lineno, token.colno, token.filename)
281
+ self.value = token.value
282
+ self.bytespan = token.bytespan
283
+
284
+ class BooleanNode(ElementaryNode[bool]):
285
+ pass
286
+
287
+ class IdNode(ElementaryNode[str]):
288
+ pass
289
+
290
+ @dataclass(unsafe_hash=True)
291
+ class NumberNode(ElementaryNode[int]):
292
+
293
+ raw_value: str = field(hash=False)
294
+
295
+ def __init__(self, token: Token[str]):
296
+ BaseNode.__init__(self, token.lineno, token.colno, token.filename)
297
+ self.raw_value = token.value
298
+ self.value = int(token.value, base=0)
299
+ self.bytespan = token.bytespan
300
+
301
+ class BaseStringNode(ElementaryNode[str]):
302
+ pass
303
+
304
+ @dataclass(unsafe_hash=True)
305
+ class StringNode(BaseStringNode):
306
+
307
+ raw_value: str = field(hash=False)
308
+
309
+ def __init__(self, token: Token[str], escape: bool = True):
310
+ super().__init__(token)
311
+ self.value = ESCAPE_SEQUENCE_SINGLE_RE.sub(decode_match, token.value) if escape else token.value
312
+ self.raw_value = token.value
313
+
314
+ class FormatStringNode(StringNode):
315
+ pass
316
+
317
+ @dataclass(unsafe_hash=True)
318
+ class MultilineStringNode(BaseStringNode):
319
+
320
+ def __init__(self, token: Token[str]):
321
+ super().__init__(token)
322
+ self.value = token.value
323
+
324
+ class MultilineFormatStringNode(MultilineStringNode):
325
+ pass
326
+
327
+ class ContinueNode(ElementaryNode):
328
+ pass
329
+
330
+ class BreakNode(ElementaryNode):
331
+ pass
332
+
333
+ class SymbolNode(ElementaryNode[str]):
334
+ pass
335
+
336
+ @dataclass(unsafe_hash=True)
337
+ class ArgumentNode(BaseNode):
338
+
339
+ arguments: T.List[BaseNode] = field(hash=False)
340
+ commas: T.List[SymbolNode] = field(hash=False)
341
+ columns: T.List[SymbolNode] = field(hash=False)
342
+ kwargs: T.Dict[BaseNode, BaseNode] = field(hash=False)
343
+
344
+ def __init__(self, token: Token[TV_TokenTypes]):
345
+ super().__init__(token.lineno, token.colno, token.filename)
346
+ self.arguments = []
347
+ self.commas = []
348
+ self.columns = []
349
+ self.kwargs = {}
350
+ self.order_error = False
351
+
352
+ def prepend(self, statement: BaseNode) -> None:
353
+ if self.num_kwargs() > 0:
354
+ self.order_error = True
355
+ if not isinstance(statement, EmptyNode):
356
+ self.arguments = [statement] + self.arguments
357
+
358
+ def append(self, statement: BaseNode) -> None:
359
+ if self.num_kwargs() > 0:
360
+ self.order_error = True
361
+ if not isinstance(statement, EmptyNode):
362
+ self.arguments += [statement]
363
+
364
+ def set_kwarg(self, name: IdNode, value: BaseNode) -> None:
365
+ if any((isinstance(x, IdNode) and name.value == x.value) for x in self.kwargs):
366
+ mlog.warning(f'Keyword argument "{name.value}" defined multiple times.', location=self)
367
+ mlog.warning('This will be an error in future Meson releases.')
368
+ self.kwargs[name] = value
369
+
370
+ def set_kwarg_no_check(self, name: BaseNode, value: BaseNode) -> None:
371
+ self.kwargs[name] = value
372
+
373
+ def num_args(self) -> int:
374
+ return len(self.arguments)
375
+
376
+ def num_kwargs(self) -> int:
377
+ return len(self.kwargs)
378
+
379
+ def incorrect_order(self) -> bool:
380
+ return self.order_error
381
+
382
+ def __len__(self) -> int:
383
+ return self.num_args() # Fixme
384
+
385
+ @dataclass(unsafe_hash=True)
386
+ class ArrayNode(BaseNode):
387
+
388
+ lbracket: SymbolNode
389
+ args: ArgumentNode
390
+ rbracket: SymbolNode
391
+
392
+ def __init__(self, lbracket: SymbolNode, args: ArgumentNode, rbracket: SymbolNode):
393
+ super().__init__(lbracket.lineno, lbracket.colno, args.filename, end_lineno=rbracket.lineno, end_colno=rbracket.colno+1)
394
+ self.lbracket = lbracket
395
+ self.args = args
396
+ self.rbracket = rbracket
397
+
398
+ @dataclass(unsafe_hash=True)
399
+ class DictNode(BaseNode):
400
+
401
+ lcurl: SymbolNode
402
+ args: ArgumentNode
403
+ rcurl: SymbolNode
404
+
405
+ def __init__(self, lcurl: SymbolNode, args: ArgumentNode, rcurl: SymbolNode):
406
+ super().__init__(lcurl.lineno, lcurl.colno, args.filename, end_lineno=rcurl.lineno, end_colno=rcurl.colno+1)
407
+ self.lcurl = lcurl
408
+ self.args = args
409
+ self.rcurl = rcurl
410
+
411
+ class EmptyNode(BaseNode):
412
+ pass
413
+
414
+ @dataclass(unsafe_hash=True)
415
+ class BinaryOperatorNode(BaseNode):
416
+
417
+ left: BaseNode
418
+ operator: SymbolNode
419
+ right: BaseNode
420
+
421
+ def __init__(self, left: BaseNode, operator: SymbolNode, right: BaseNode):
422
+ super().__init__(left.lineno, left.colno, left.filename)
423
+ self.left = left
424
+ self.operator = operator
425
+ self.right = right
426
+
427
+ class OrNode(BinaryOperatorNode):
428
+ pass
429
+
430
+ class AndNode(BinaryOperatorNode):
431
+ pass
432
+
433
+ @dataclass(unsafe_hash=True)
434
+ class ComparisonNode(BinaryOperatorNode):
435
+
436
+ ctype: COMPARISONS
437
+
438
+ def __init__(self, ctype: COMPARISONS, left: BaseNode, operator: SymbolNode, right: BaseNode):
439
+ super().__init__(left, operator, right)
440
+ self.ctype = ctype
441
+
442
+ @dataclass(unsafe_hash=True)
443
+ class ArithmeticNode(BinaryOperatorNode):
444
+
445
+ # TODO: use a Literal for operation
446
+ operation: str
447
+
448
+ def __init__(self, operation: str, left: BaseNode, operator: SymbolNode, right: BaseNode):
449
+ super().__init__(left, operator, right)
450
+ self.operation = operation
451
+
452
+ @dataclass(unsafe_hash=True)
453
+ class UnaryOperatorNode(BaseNode):
454
+
455
+ operator: SymbolNode
456
+ value: BaseNode
457
+
458
+ def __init__(self, token: Token[TV_TokenTypes], operator: SymbolNode, value: BaseNode):
459
+ super().__init__(token.lineno, token.colno, token.filename)
460
+ self.operator = operator
461
+ self.value = value
462
+
463
+ class NotNode(UnaryOperatorNode):
464
+ pass
465
+
466
+ class UMinusNode(UnaryOperatorNode):
467
+ pass
468
+
469
+ @dataclass(unsafe_hash=True)
470
+ class CodeBlockNode(BaseNode):
471
+
472
+ pre_whitespaces: T.Optional[WhitespaceNode] = field(hash=False)
473
+ lines: T.List[BaseNode] = field(hash=False)
474
+
475
+ def __init__(self, token: Token[TV_TokenTypes]):
476
+ super().__init__(token.lineno, token.colno, token.filename)
477
+ self.pre_whitespaces = None
478
+ self.lines = []
479
+
480
+ def append_whitespaces(self, token: Token) -> None:
481
+ if self.lines:
482
+ self.lines[-1].append_whitespaces(token)
483
+ elif self.pre_whitespaces is None:
484
+ self.pre_whitespaces = WhitespaceNode(token)
485
+ else:
486
+ self.pre_whitespaces.append(token)
487
+
488
+ @dataclass(unsafe_hash=True)
489
+ class IndexNode(BaseNode):
490
+
491
+ iobject: BaseNode
492
+ lbracket: SymbolNode
493
+ index: BaseNode
494
+ rbracket: SymbolNode
495
+
496
+ def __init__(self, iobject: BaseNode, lbracket: SymbolNode, index: BaseNode, rbracket: SymbolNode):
497
+ super().__init__(iobject.lineno, iobject.colno, iobject.filename)
498
+ self.iobject = iobject
499
+ self.lbracket = lbracket
500
+ self.index = index
501
+ self.rbracket = rbracket
502
+
503
+ @dataclass(unsafe_hash=True)
504
+ class MethodNode(BaseNode):
505
+
506
+ source_object: BaseNode
507
+ dot: SymbolNode
508
+ name: IdNode
509
+ lpar: SymbolNode
510
+ args: ArgumentNode
511
+ rpar: SymbolNode
512
+
513
+ def __init__(self, source_object: BaseNode, dot: SymbolNode, name: IdNode, lpar: SymbolNode, args: ArgumentNode, rpar: SymbolNode):
514
+ super().__init__(name.lineno, name.colno, name.filename, end_lineno=rpar.lineno, end_colno=rpar.colno+1)
515
+ self.source_object = source_object
516
+ self.dot = dot
517
+ self.name = name
518
+ self.lpar = lpar
519
+ self.args = args
520
+ self.rpar = rpar
521
+
522
+ @dataclass(unsafe_hash=True)
523
+ class FunctionNode(BaseNode):
524
+
525
+ func_name: IdNode
526
+ lpar: SymbolNode
527
+ args: ArgumentNode
528
+ rpar: SymbolNode
529
+
530
+ def __init__(self, func_name: IdNode, lpar: SymbolNode, args: ArgumentNode, rpar: SymbolNode):
531
+ super().__init__(func_name.lineno, func_name.colno, func_name.filename, end_lineno=rpar.end_lineno, end_colno=rpar.end_colno+1)
532
+ self.func_name = func_name
533
+ self.lpar = lpar
534
+ self.args = args
535
+ self.rpar = rpar
536
+
537
+ @dataclass(unsafe_hash=True)
538
+ class AssignmentNode(BaseNode):
539
+
540
+ var_name: IdNode
541
+ operator: SymbolNode
542
+ value: BaseNode
543
+
544
+ def __init__(self, var_name: IdNode, operator: SymbolNode, value: BaseNode):
545
+ super().__init__(var_name.lineno, var_name.colno, var_name.filename)
546
+ self.var_name = var_name
547
+ self.operator = operator
548
+ self.value = value
549
+
550
+ class PlusAssignmentNode(AssignmentNode):
551
+ pass
552
+
553
+ @dataclass(unsafe_hash=True)
554
+ class ForeachClauseNode(BaseNode):
555
+
556
+ foreach_: SymbolNode = field(hash=False)
557
+ varnames: T.List[IdNode] = field(hash=False)
558
+ commas: T.List[SymbolNode] = field(hash=False)
559
+ column: SymbolNode = field(hash=False)
560
+ items: BaseNode
561
+ block: CodeBlockNode
562
+ endforeach: SymbolNode = field(hash=False)
563
+
564
+ def __init__(self, foreach_: SymbolNode, varnames: T.List[IdNode], commas: T.List[SymbolNode], column: SymbolNode, items: BaseNode, block: CodeBlockNode, endforeach: SymbolNode):
565
+ super().__init__(foreach_.lineno, foreach_.colno, foreach_.filename)
566
+ self.foreach_ = foreach_
567
+ self.varnames = varnames
568
+ self.commas = commas
569
+ self.column = column
570
+ self.items = items
571
+ self.block = block
572
+ self.endforeach = endforeach
573
+
574
+
575
+ @dataclass(unsafe_hash=True)
576
+ class IfNode(BaseNode):
577
+
578
+ if_: SymbolNode
579
+ condition: BaseNode
580
+ block: CodeBlockNode
581
+
582
+ def __init__(self, linenode: BaseNode, if_node: SymbolNode, condition: BaseNode, block: CodeBlockNode):
583
+ super().__init__(linenode.lineno, linenode.colno, linenode.filename)
584
+ self.if_ = if_node
585
+ self.condition = condition
586
+ self.block = block
587
+
588
+ @dataclass(unsafe_hash=True)
589
+ class ElseNode(BaseNode):
590
+
591
+ else_: SymbolNode
592
+ block: CodeBlockNode
593
+
594
+ def __init__(self, else_: SymbolNode, block: CodeBlockNode):
595
+ super().__init__(block.lineno, block.colno, block.filename)
596
+ self.else_ = else_
597
+ self.block = block
598
+
599
+ @dataclass(unsafe_hash=True)
600
+ class IfClauseNode(BaseNode):
601
+
602
+ ifs: T.List[IfNode] = field(hash=False)
603
+ elseblock: T.Union[EmptyNode, ElseNode]
604
+ endif: SymbolNode
605
+
606
+ def __init__(self, linenode: BaseNode):
607
+ super().__init__(linenode.lineno, linenode.colno, linenode.filename)
608
+ self.ifs = []
609
+ self.elseblock = EmptyNode(linenode.lineno, linenode.colno, linenode.filename)
610
+
611
+ @dataclass(unsafe_hash=True)
612
+ class TestCaseClauseNode(BaseNode):
613
+
614
+ testcase: SymbolNode
615
+ condition: BaseNode
616
+ block: CodeBlockNode
617
+ endtestcase: SymbolNode
618
+
619
+ def __init__(self, testcase: SymbolNode, condition: BaseNode, block: CodeBlockNode, endtestcase: SymbolNode):
620
+ super().__init__(condition.lineno, condition.colno, condition.filename)
621
+ self.testcase = testcase
622
+ self.condition = condition
623
+ self.block = block
624
+ self.endtestcase = endtestcase
625
+
626
+ @dataclass(unsafe_hash=True)
627
+ class TernaryNode(BaseNode):
628
+
629
+ condition: BaseNode
630
+ questionmark: SymbolNode
631
+ trueblock: BaseNode
632
+ column: SymbolNode
633
+ falseblock: BaseNode
634
+
635
+ def __init__(self, condition: BaseNode, questionmark: SymbolNode, trueblock: BaseNode, column: SymbolNode, falseblock: BaseNode):
636
+ super().__init__(condition.lineno, condition.colno, condition.filename)
637
+ self.condition = condition
638
+ self.questionmark = questionmark
639
+ self.trueblock = trueblock
640
+ self.column = column
641
+ self.falseblock = falseblock
642
+
643
+
644
+ @dataclass(unsafe_hash=True)
645
+ class ParenthesizedNode(BaseNode):
646
+
647
+ lpar: SymbolNode = field(hash=False)
648
+ inner: BaseNode
649
+ rpar: SymbolNode = field(hash=False)
650
+
651
+ def __init__(self, lpar: SymbolNode, inner: BaseNode, rpar: SymbolNode):
652
+ super().__init__(lpar.lineno, lpar.colno, inner.filename, end_lineno=rpar.lineno, end_colno=rpar.colno+1)
653
+ self.lpar = lpar
654
+ self.inner = inner
655
+ self.rpar = rpar
656
+
657
+
658
+ if T.TYPE_CHECKING:
659
+ COMPARISONS = Literal['==', '!=', '<', '<=', '>=', '>', 'in', 'notin']
660
+
661
+ comparison_map: T.Mapping[str, COMPARISONS] = {
662
+ 'equal': '==',
663
+ 'nequal': '!=',
664
+ 'lt': '<',
665
+ 'le': '<=',
666
+ 'gt': '>',
667
+ 'ge': '>=',
668
+ 'in': 'in',
669
+ 'not in': 'notin',
670
+ }
671
+
672
+ # Recursive descent parser for Meson's definition language.
673
+ # Very basic apart from the fact that we have many precedence
674
+ # levels so there are not enough words to describe them all.
675
+ # Enter numbering:
676
+ #
677
+ # 1 assignment
678
+ # 2 or
679
+ # 3 and
680
+ # 4 comparison
681
+ # 5 arithmetic
682
+ # 6 negation
683
+ # 7 funcall, method call
684
+ # 8 parentheses
685
+ # 9 plain token
686
+
687
+ class Parser:
688
+ def __init__(self, code: str, filename: str):
689
+ self.lexer = Lexer(code)
690
+ self.stream = self.lexer.lex(filename)
691
+ self.current: Token = Token('eof', '', 0, 0, 0, (0, 0), None)
692
+ self.previous = self.current
693
+ self.current_ws: T.List[Token] = []
694
+
695
+ self.getsym()
696
+ self.in_ternary = False
697
+
698
+ def create_node(self, node_type: T.Type[BaseNodeT], *args: T.Any, **kwargs: T.Any) -> BaseNodeT:
699
+ node = node_type(*args, **kwargs)
700
+ for ws_token in self.current_ws:
701
+ node.append_whitespaces(ws_token)
702
+ self.current_ws = []
703
+ return node
704
+
705
+ def getsym(self) -> None:
706
+ self.previous = self.current
707
+ try:
708
+ self.current = next(self.stream)
709
+
710
+ while self.current.tid in {'eol', 'comment', 'whitespace'}:
711
+ self.current_ws.append(self.current)
712
+ if self.current.tid == 'eol':
713
+ break
714
+ self.current = next(self.stream)
715
+
716
+ except StopIteration:
717
+ self.current = Token('eof', '', self.current.line_start, self.current.lineno, self.current.colno + self.current.bytespan[1] - self.current.bytespan[0], (0, 0), None)
718
+
719
+ def getline(self) -> str:
720
+ return self.lexer.getline(self.current.line_start)
721
+
722
+ def accept(self, s: str) -> bool:
723
+ if self.current.tid == s:
724
+ self.getsym()
725
+ return True
726
+ return False
727
+
728
+ def accept_any(self, tids: T.Tuple[str, ...]) -> str:
729
+ tid = self.current.tid
730
+ if tid in tids:
731
+ self.getsym()
732
+ return tid
733
+ return ''
734
+
735
+ def expect(self, s: str) -> bool:
736
+ if self.accept(s):
737
+ return True
738
+ raise ParseException(f'Expecting {s} got {self.current.tid}.', self.getline(), self.current.lineno, self.current.colno)
739
+
740
+ def block_expect(self, s: str, block_start: Token) -> bool:
741
+ if self.accept(s):
742
+ return True
743
+ raise BlockParseException(f'Expecting {s} got {self.current.tid}.', self.getline(), self.current.lineno, self.current.colno, self.lexer.getline(block_start.line_start), block_start.lineno, block_start.colno)
744
+
745
+ def parse(self) -> CodeBlockNode:
746
+ block = self.codeblock()
747
+ try:
748
+ self.expect('eof')
749
+ except ParseException as e:
750
+ e.ast = block
751
+ raise
752
+ return block
753
+
754
+ def statement(self) -> BaseNode:
755
+ return self.e1()
756
+
757
+ def e1(self) -> BaseNode:
758
+ left = self.e2()
759
+ if self.accept('plusassign'):
760
+ operator = self.create_node(SymbolNode, self.previous)
761
+ value = self.e1()
762
+ if not isinstance(left, IdNode):
763
+ raise ParseException('Plusassignment target must be an id.', self.getline(), left.lineno, left.colno)
764
+ assert isinstance(left.value, str)
765
+ return self.create_node(PlusAssignmentNode, left, operator, value)
766
+ elif self.accept('assign'):
767
+ operator = self.create_node(SymbolNode, self.previous)
768
+ value = self.e1()
769
+ if not isinstance(left, IdNode):
770
+ raise ParseException('Assignment target must be an id.',
771
+ self.getline(), left.lineno, left.colno)
772
+ assert isinstance(left.value, str)
773
+ return self.create_node(AssignmentNode, left, operator, value)
774
+ elif self.accept('questionmark'):
775
+ if self.in_ternary:
776
+ raise ParseException('Nested ternary operators are not allowed.',
777
+ self.getline(), left.lineno, left.colno)
778
+
779
+ qm_node = self.create_node(SymbolNode, self.previous)
780
+ self.in_ternary = True
781
+ trueblock = self.e1()
782
+ self.expect('colon')
783
+ column_node = self.create_node(SymbolNode, self.previous)
784
+ falseblock = self.e1()
785
+ self.in_ternary = False
786
+ return self.create_node(TernaryNode, left, qm_node, trueblock, column_node, falseblock)
787
+ return left
788
+
789
+ def e2(self) -> BaseNode:
790
+ left = self.e3()
791
+ while self.accept('or'):
792
+ operator = self.create_node(SymbolNode, self.previous)
793
+ if isinstance(left, EmptyNode):
794
+ raise ParseException('Invalid or clause.',
795
+ self.getline(), left.lineno, left.colno)
796
+ left = self.create_node(OrNode, left, operator, self.e3())
797
+ return left
798
+
799
+ def e3(self) -> BaseNode:
800
+ left = self.e4()
801
+ while self.accept('and'):
802
+ operator = self.create_node(SymbolNode, self.previous)
803
+ if isinstance(left, EmptyNode):
804
+ raise ParseException('Invalid and clause.',
805
+ self.getline(), left.lineno, left.colno)
806
+ left = self.create_node(AndNode, left, operator, self.e4())
807
+ return left
808
+
809
+ def e4(self) -> BaseNode:
810
+ left = self.e5()
811
+ for nodename, operator_type in comparison_map.items():
812
+ if self.accept(nodename):
813
+ operator = self.create_node(SymbolNode, self.previous)
814
+ return self.create_node(ComparisonNode, operator_type, left, operator, self.e5())
815
+ if self.accept('not'):
816
+ ws = self.current_ws.copy()
817
+ not_token = self.previous
818
+ if self.accept('in'):
819
+ in_token = self.previous
820
+ self.current_ws = self.current_ws[len(ws):] # remove whitespaces between not and in
821
+ temp_node = EmptyNode(in_token.lineno, in_token.colno, in_token.filename)
822
+ for w in ws:
823
+ temp_node.append_whitespaces(w)
824
+
825
+ not_token.bytespan = (not_token.bytespan[0], in_token.bytespan[1])
826
+ not_token.value += temp_node.whitespaces.value + in_token.value
827
+ operator = self.create_node(SymbolNode, not_token)
828
+ return self.create_node(ComparisonNode, 'notin', left, operator, self.e5())
829
+ return left
830
+
831
+ def e5(self) -> BaseNode:
832
+ return self.e5addsub()
833
+
834
+ def e5addsub(self) -> BaseNode:
835
+ op_map = {
836
+ 'plus': 'add',
837
+ 'dash': 'sub',
838
+ }
839
+ left = self.e5muldiv()
840
+ while True:
841
+ op = self.accept_any(tuple(op_map.keys()))
842
+ if op:
843
+ operator = self.create_node(SymbolNode, self.previous)
844
+ left = self.create_node(ArithmeticNode, op_map[op], left, operator, self.e5muldiv())
845
+ else:
846
+ break
847
+ return left
848
+
849
+ def e5muldiv(self) -> BaseNode:
850
+ op_map = {
851
+ 'percent': 'mod',
852
+ 'star': 'mul',
853
+ 'fslash': 'div',
854
+ }
855
+ left = self.e6()
856
+ while True:
857
+ op = self.accept_any(tuple(op_map.keys()))
858
+ if op:
859
+ operator = self.create_node(SymbolNode, self.previous)
860
+ left = self.create_node(ArithmeticNode, op_map[op], left, operator, self.e6())
861
+ else:
862
+ break
863
+ return left
864
+
865
+ def e6(self) -> BaseNode:
866
+ if self.accept('not'):
867
+ operator = self.create_node(SymbolNode, self.previous)
868
+ return self.create_node(NotNode, self.current, operator, self.e7())
869
+ if self.accept('dash'):
870
+ operator = self.create_node(SymbolNode, self.previous)
871
+ return self.create_node(UMinusNode, self.current, operator, self.e7())
872
+ return self.e7()
873
+
874
+ def e7(self) -> BaseNode:
875
+ left = self.e8()
876
+ block_start = self.current
877
+ if self.accept('lparen'):
878
+ lpar = self.create_node(SymbolNode, block_start)
879
+ args = self.args()
880
+ self.block_expect('rparen', block_start)
881
+ rpar = self.create_node(SymbolNode, self.previous)
882
+ if not isinstance(left, IdNode):
883
+ raise ParseException('Function call must be applied to plain id',
884
+ self.getline(), left.lineno, left.colno)
885
+ assert isinstance(left.value, str)
886
+ left = self.create_node(FunctionNode, left, lpar, args, rpar)
887
+ go_again = True
888
+ while go_again:
889
+ go_again = False
890
+ if self.accept('dot'):
891
+ go_again = True
892
+ left = self.method_call(left)
893
+ if self.accept('lbracket'):
894
+ go_again = True
895
+ left = self.index_call(left)
896
+ return left
897
+
898
+ def e8(self) -> BaseNode:
899
+ block_start = self.current
900
+ if self.accept('lparen'):
901
+ lpar = self.create_node(SymbolNode, block_start)
902
+ e = self.statement()
903
+ self.block_expect('rparen', block_start)
904
+ rpar = self.create_node(SymbolNode, self.previous)
905
+ return ParenthesizedNode(lpar, e, rpar)
906
+ elif self.accept('lbracket'):
907
+ lbracket = self.create_node(SymbolNode, block_start)
908
+ args = self.args()
909
+ self.block_expect('rbracket', block_start)
910
+ rbracket = self.create_node(SymbolNode, self.previous)
911
+ return self.create_node(ArrayNode, lbracket, args, rbracket)
912
+ elif self.accept('lcurl'):
913
+ lcurl = self.create_node(SymbolNode, block_start)
914
+ key_values = self.key_values()
915
+ self.block_expect('rcurl', block_start)
916
+ rcurl = self.create_node(SymbolNode, self.previous)
917
+ return self.create_node(DictNode, lcurl, key_values, rcurl)
918
+ else:
919
+ return self.e9()
920
+
921
+ def e9(self) -> BaseNode:
922
+ t = self.current
923
+ if self.accept('true'):
924
+ t.value = True
925
+ return self.create_node(BooleanNode, t)
926
+ if self.accept('false'):
927
+ t.value = False
928
+ return self.create_node(BooleanNode, t)
929
+ if self.accept('id'):
930
+ return self.create_node(IdNode, t)
931
+ if self.accept('number'):
932
+ return self.create_node(NumberNode, t)
933
+ if self.accept('string'):
934
+ return self.create_node(StringNode, t)
935
+ if self.accept('fstring'):
936
+ return self.create_node(FormatStringNode, t)
937
+ if self.accept('multiline_string'):
938
+ return self.create_node(MultilineStringNode, t)
939
+ if self.accept('multiline_fstring'):
940
+ return self.create_node(MultilineFormatStringNode, t)
941
+ return EmptyNode(self.current.lineno, self.current.colno, self.current.filename)
942
+
943
+ def key_values(self) -> ArgumentNode:
944
+ s = self.statement()
945
+ a = self.create_node(ArgumentNode, self.current)
946
+
947
+ while not isinstance(s, EmptyNode):
948
+ if self.accept('colon'):
949
+ a.columns.append(self.create_node(SymbolNode, self.previous))
950
+ a.set_kwarg_no_check(s, self.statement())
951
+ if not self.accept('comma'):
952
+ return a
953
+ a.commas.append(self.create_node(SymbolNode, self.previous))
954
+ else:
955
+ raise ParseException('Only key:value pairs are valid in dict construction.',
956
+ self.getline(), s.lineno, s.colno)
957
+ s = self.statement()
958
+ return a
959
+
960
+ def args(self) -> ArgumentNode:
961
+ s = self.statement()
962
+ a = self.create_node(ArgumentNode, self.current)
963
+
964
+ while not isinstance(s, EmptyNode):
965
+ if self.accept('comma'):
966
+ a.commas.append(self.create_node(SymbolNode, self.previous))
967
+ a.append(s)
968
+ elif self.accept('colon'):
969
+ a.columns.append(self.create_node(SymbolNode, self.previous))
970
+ if not isinstance(s, IdNode):
971
+ raise ParseException('Dictionary key must be a plain identifier.',
972
+ self.getline(), s.lineno, s.colno)
973
+ a.set_kwarg(s, self.statement())
974
+ if not self.accept('comma'):
975
+ return a
976
+ a.commas.append(self.create_node(SymbolNode, self.previous))
977
+ else:
978
+ a.append(s)
979
+ return a
980
+ s = self.statement()
981
+ return a
982
+
983
+ def method_call(self, source_object: BaseNode) -> MethodNode:
984
+ dot = self.create_node(SymbolNode, self.previous)
985
+ methodname = self.e9()
986
+ if not isinstance(methodname, IdNode):
987
+ if isinstance(source_object, NumberNode) and isinstance(methodname, NumberNode):
988
+ raise ParseException('meson does not support float numbers',
989
+ self.getline(), source_object.lineno, source_object.colno)
990
+ raise ParseException('Method name must be plain id',
991
+ self.getline(), self.current.lineno, self.current.colno)
992
+ assert isinstance(methodname.value, str)
993
+ self.expect('lparen')
994
+ lpar = self.create_node(SymbolNode, self.previous)
995
+ args = self.args()
996
+ rpar = self.create_node(SymbolNode, self.current)
997
+ self.expect('rparen')
998
+ method = self.create_node(MethodNode, source_object, dot, methodname, lpar, args, rpar)
999
+ if self.accept('dot'):
1000
+ return self.method_call(method)
1001
+ return method
1002
+
1003
+ def index_call(self, source_object: BaseNode) -> IndexNode:
1004
+ lbracket = self.create_node(SymbolNode, self.previous)
1005
+ index_statement = self.statement()
1006
+ self.expect('rbracket')
1007
+ rbracket = self.create_node(SymbolNode, self.previous)
1008
+ return self.create_node(IndexNode, source_object, lbracket, index_statement, rbracket)
1009
+
1010
+ def foreachblock(self) -> ForeachClauseNode:
1011
+ foreach_ = self.create_node(SymbolNode, self.previous)
1012
+ self.expect('id')
1013
+ assert isinstance(self.previous.value, str)
1014
+ varnames = [self.create_node(IdNode, self.previous)]
1015
+ commas = []
1016
+
1017
+ if self.accept('comma'):
1018
+ commas.append(self.create_node(SymbolNode, self.previous))
1019
+ self.expect('id')
1020
+ assert isinstance(self.previous.value, str)
1021
+ varnames.append(self.create_node(IdNode, self.previous))
1022
+
1023
+ self.expect('colon')
1024
+ column = self.create_node(SymbolNode, self.previous)
1025
+ items = self.statement()
1026
+ block = self.codeblock()
1027
+ endforeach = self.create_node(SymbolNode, self.current)
1028
+ return self.create_node(ForeachClauseNode, foreach_, varnames, commas, column, items, block, endforeach)
1029
+
1030
+ def ifblock(self) -> IfClauseNode:
1031
+ if_node = self.create_node(SymbolNode, self.previous)
1032
+ condition = self.statement()
1033
+ clause = self.create_node(IfClauseNode, condition)
1034
+ self.expect('eol')
1035
+ block = self.codeblock()
1036
+ clause.ifs.append(self.create_node(IfNode, clause, if_node, condition, block))
1037
+ self.elseifblock(clause)
1038
+ clause.elseblock = self.elseblock()
1039
+ clause.endif = self.create_node(SymbolNode, self.current)
1040
+ return clause
1041
+
1042
+ def elseifblock(self, clause: IfClauseNode) -> None:
1043
+ while self.accept('elif'):
1044
+ elif_ = self.create_node(SymbolNode, self.previous)
1045
+ s = self.statement()
1046
+ self.expect('eol')
1047
+ b = self.codeblock()
1048
+ clause.ifs.append(self.create_node(IfNode, s, elif_, s, b))
1049
+
1050
+ def elseblock(self) -> T.Union[ElseNode, EmptyNode]:
1051
+ if self.accept('else'):
1052
+ else_ = self.create_node(SymbolNode, self.previous)
1053
+ self.expect('eol')
1054
+ block = self.codeblock()
1055
+ return ElseNode(else_, block)
1056
+ return EmptyNode(self.current.lineno, self.current.colno, self.current.filename)
1057
+
1058
+ def testcaseblock(self) -> TestCaseClauseNode:
1059
+ testcase = self.create_node(SymbolNode, self.previous)
1060
+ condition = self.statement()
1061
+ self.expect('eol')
1062
+ block = self.codeblock()
1063
+ endtestcase = SymbolNode(self.current)
1064
+ return self.create_node(TestCaseClauseNode, testcase, condition, block, endtestcase)
1065
+
1066
+ def line(self) -> BaseNode:
1067
+ block_start = self.current
1068
+ if self.current == 'eol':
1069
+ return EmptyNode(self.current.lineno, self.current.colno, self.current.filename)
1070
+ if self.accept('if'):
1071
+ ifblock = self.ifblock()
1072
+ self.block_expect('endif', block_start)
1073
+ return ifblock
1074
+ if self.accept('foreach'):
1075
+ forblock = self.foreachblock()
1076
+ self.block_expect('endforeach', block_start)
1077
+ return forblock
1078
+ if self.accept('continue'):
1079
+ return self.create_node(ContinueNode, self.current)
1080
+ if self.accept('break'):
1081
+ return self.create_node(BreakNode, self.current)
1082
+ if self.lexer.in_unit_test and self.accept('testcase'):
1083
+ block = self.testcaseblock()
1084
+ self.block_expect('endtestcase', block_start)
1085
+ return block
1086
+ return self.statement()
1087
+
1088
+ def codeblock(self) -> CodeBlockNode:
1089
+ block = self.create_node(CodeBlockNode, self.current)
1090
+ cond = True
1091
+
1092
+ try:
1093
+ while cond:
1094
+ for ws_token in self.current_ws:
1095
+ block.append_whitespaces(ws_token)
1096
+ self.current_ws = []
1097
+
1098
+ curline = self.line()
1099
+
1100
+ if not isinstance(curline, EmptyNode):
1101
+ block.lines.append(curline)
1102
+
1103
+ cond = self.accept('eol')
1104
+
1105
+ except ParseException as e:
1106
+ e.ast = block
1107
+ raise
1108
+
1109
+ # Remaining whitespaces will not be catched since there are no more nodes
1110
+ for ws_token in self.current_ws:
1111
+ block.append_whitespaces(ws_token)
1112
+ self.current_ws = []
1113
+
1114
+ return block