@flarum/cli 2.0.0-beta.8 → 3.0.0

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 (663) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +178 -48
  3. package/bin/run +2 -1
  4. package/bin/splitsh-lite-darwin +0 -0
  5. package/bin/splitsh-lite-linux +0 -0
  6. package/boilerplate/skeleton/extension/.gitattributes +16 -14
  7. package/boilerplate/skeleton/extension/.github/workflows/backend.yml +2 -6
  8. package/boilerplate/skeleton/extension/.github/workflows/frontend.yml +5 -6
  9. package/boilerplate/skeleton/extension/.github/workflows/phpstan.yml +12 -0
  10. package/boilerplate/skeleton/extension/LICENSE.md +1 -1
  11. package/boilerplate/skeleton/extension/README.md +1 -1
  12. package/boilerplate/skeleton/extension/composer.json +13 -7
  13. package/boilerplate/skeleton/extension/extend.php +2 -2
  14. package/boilerplate/skeleton/extension/gitignore +1 -0
  15. package/boilerplate/skeleton/extension/js/admin.ts +2 -0
  16. package/boilerplate/skeleton/extension/js/forum.ts +2 -0
  17. package/boilerplate/skeleton/extension/js/jest.config.cjs +1 -0
  18. package/boilerplate/skeleton/extension/js/package.json +11 -4
  19. package/boilerplate/skeleton/extension/js/src/admin/extend.js +8 -0
  20. package/boilerplate/skeleton/extension/js/src/admin/extend.ts +8 -0
  21. package/boilerplate/skeleton/extension/js/src/admin/index.js +2 -0
  22. package/boilerplate/skeleton/extension/js/src/admin/index.ts +7 -0
  23. package/boilerplate/skeleton/extension/js/src/common/extend.js +5 -0
  24. package/boilerplate/skeleton/extension/js/src/common/extend.ts +5 -0
  25. package/boilerplate/skeleton/extension/js/src/common/index.ts +5 -0
  26. package/boilerplate/skeleton/extension/js/src/forum/extend.js +8 -0
  27. package/boilerplate/skeleton/extension/js/src/forum/extend.ts +8 -0
  28. package/boilerplate/skeleton/extension/js/src/forum/index.js +2 -0
  29. package/boilerplate/skeleton/extension/js/src/forum/index.ts +7 -0
  30. package/boilerplate/skeleton/extension/js/tests/unit/.gitkeep +0 -0
  31. package/boilerplate/skeleton/extension/js/tsconfig.json +10 -2
  32. package/boilerplate/skeleton/extension/js/tsconfig.test.json +10 -0
  33. package/boilerplate/skeleton/extension/locale/en.yml +1 -1
  34. package/boilerplate/skeleton/extension/phpstan.neon +12 -0
  35. package/boilerplate/skeleton/extension/tests/phpunit.integration.xml +6 -7
  36. package/boilerplate/skeleton/extension/tests/phpunit.unit.xml +5 -10
  37. package/boilerplate/stubs/backend/advanced-api-resource.php +85 -0
  38. package/boilerplate/stubs/backend/api-resource.php +73 -0
  39. package/boilerplate/stubs/backend/command.php +2 -2
  40. package/boilerplate/stubs/backend/controller.php +19 -0
  41. package/boilerplate/stubs/backend/event-listener.php +1 -1
  42. package/boilerplate/stubs/backend/filter.php +25 -0
  43. package/boilerplate/stubs/backend/handler/command.php +6 -20
  44. package/boilerplate/stubs/backend/handler/handler.php +6 -14
  45. package/boilerplate/stubs/backend/integration-test.php +10 -7
  46. package/boilerplate/stubs/backend/job.php +6 -11
  47. package/boilerplate/stubs/backend/mail-driver.php +36 -0
  48. package/boilerplate/stubs/backend/middleware.php +19 -0
  49. package/boilerplate/stubs/backend/model.php +1 -1
  50. package/boilerplate/stubs/backend/notification-blueprint.php +42 -0
  51. package/boilerplate/stubs/backend/notification-driver.php +32 -0
  52. package/boilerplate/stubs/backend/policy.php +1 -1
  53. package/boilerplate/stubs/backend/post-type.php +35 -0
  54. package/boilerplate/stubs/backend/repository.php +2 -10
  55. package/boilerplate/stubs/backend/search/driver.php +13 -0
  56. package/boilerplate/stubs/backend/search/searcher.php +41 -0
  57. package/boilerplate/stubs/backend/service-provider.php +1 -1
  58. package/boilerplate/stubs/backend/validator.php +1 -1
  59. package/boilerplate/stubs/frontend/component.js +1 -1
  60. package/boilerplate/stubs/frontend/forum-page.js +68 -0
  61. package/boilerplate/stubs/frontend/gambit/boolean.js +12 -0
  62. package/boilerplate/stubs/frontend/gambit/key-value.js +16 -0
  63. package/boilerplate/stubs/frontend/modal.js +1 -1
  64. package/boilerplate/stubs/frontend/model.js +1 -1
  65. package/boilerplate/stubs/frontend/notification.js +22 -0
  66. package/boilerplate/stubs/frontend/post-type.js +13 -0
  67. package/boilerplate/stubs/migration.php +1 -1
  68. package/boilerplate/stubs/views/email/html/information.blade.php +8 -0
  69. package/boilerplate/stubs/views/email/html/notification.blade.php +8 -0
  70. package/boilerplate/stubs/views/email/plain/information.blade.php +7 -0
  71. package/boilerplate/stubs/views/email/plain/notification.blade.php +6 -0
  72. package/lib/base-command.d.ts +22 -6
  73. package/lib/base-command.js +114 -56
  74. package/lib/boilersmith/io.d.ts +33 -11
  75. package/lib/boilersmith/io.js +32 -17
  76. package/lib/boilersmith/paths.d.ts +3 -3
  77. package/lib/boilersmith/paths.js +7 -7
  78. package/lib/boilersmith/scaffolding/audit-step-factory.js +12 -12
  79. package/lib/boilersmith/scaffolding/infra-step-factory.js +2 -2
  80. package/lib/boilersmith/scaffolding/init-step-factory.js +5 -5
  81. package/lib/boilersmith/scaffolding/module.d.ts +30 -10
  82. package/lib/boilersmith/scaffolding/module.js +61 -19
  83. package/lib/boilersmith/scaffolding/scaffolder.d.ts +4 -1
  84. package/lib/boilersmith/scaffolding/scaffolder.js +33 -33
  85. package/lib/boilersmith/scaffolding/template-param.d.ts +2 -2
  86. package/lib/boilersmith/scaffolding/template-param.js +2 -2
  87. package/lib/boilersmith/step-manager.d.ts +15 -11
  88. package/lib/boilersmith/step-manager.js +45 -29
  89. package/lib/boilersmith/steps/stub-base.js +4 -4
  90. package/lib/boilersmith/utils/clone-and-fill.js +1 -1
  91. package/lib/boilersmith/utils/commit-async.d.ts +2 -0
  92. package/lib/boilersmith/utils/commit-async.js +15 -0
  93. package/lib/boilersmith/utils/json-leaf-paths.d.ts +2 -2
  94. package/lib/boilersmith/utils/read-tpl.js +2 -2
  95. package/lib/commands/audit/infra.d.ts +2 -5
  96. package/lib/commands/audit/infra.js +31 -9
  97. package/lib/commands/infra.d.ts +2 -10
  98. package/lib/commands/infra.js +20 -14
  99. package/lib/commands/init.d.ts +2 -5
  100. package/lib/commands/init.js +7 -5
  101. package/lib/commands/make/backend/{api-serializer.d.ts → api-resource.d.ts} +2 -5
  102. package/lib/commands/make/backend/api-resource.js +26 -0
  103. package/lib/commands/make/backend/command.d.ts +1 -4
  104. package/lib/commands/make/backend/command.js +3 -4
  105. package/lib/commands/make/backend/{api-controller.d.ts → controller.d.ts} +2 -5
  106. package/lib/commands/make/backend/controller.js +31 -0
  107. package/lib/commands/make/backend/event-listener.d.ts +1 -4
  108. package/lib/commands/make/backend/event-listener.js +2 -3
  109. package/lib/commands/make/backend/{api-serializer-attributes.d.ts → filter.d.ts} +3 -6
  110. package/lib/commands/make/backend/filter.js +26 -0
  111. package/lib/commands/make/backend/handler.d.ts +2 -5
  112. package/lib/commands/make/backend/handler.js +8 -11
  113. package/lib/commands/make/backend/integration-test.d.ts +1 -4
  114. package/lib/commands/make/backend/integration-test.js +4 -6
  115. package/lib/commands/make/backend/job.d.ts +1 -4
  116. package/lib/commands/make/backend/job.js +2 -2
  117. package/lib/commands/make/backend/mail-driver.d.ts +12 -0
  118. package/lib/commands/make/backend/mail-driver.js +29 -0
  119. package/lib/commands/make/backend/middleware.d.ts +11 -0
  120. package/lib/commands/make/backend/middleware.js +26 -0
  121. package/lib/commands/make/backend/migration.d.ts +1 -4
  122. package/lib/commands/make/backend/migration.js +10 -4
  123. package/lib/commands/make/backend/model.d.ts +6 -7
  124. package/lib/commands/make/backend/model.js +69 -449
  125. package/lib/commands/make/backend/notification-blueprint.d.ts +12 -0
  126. package/lib/commands/make/backend/notification-blueprint.js +29 -0
  127. package/lib/commands/make/backend/notification-driver.d.ts +12 -0
  128. package/lib/commands/make/backend/notification-driver.js +29 -0
  129. package/lib/commands/make/backend/policy.d.ts +1 -4
  130. package/lib/commands/make/backend/policy.js +2 -3
  131. package/lib/commands/make/backend/post-type.d.ts +12 -0
  132. package/lib/commands/make/backend/post-type.js +29 -0
  133. package/lib/commands/make/backend/repository.d.ts +1 -4
  134. package/lib/commands/make/backend/repository.js +1 -1
  135. package/lib/commands/make/backend/route.d.ts +1 -4
  136. package/lib/commands/make/backend/route.js +2 -3
  137. package/lib/commands/make/backend/search-driver.d.ts +11 -0
  138. package/lib/commands/make/backend/search-driver.js +51 -0
  139. package/lib/commands/make/backend/service-provider.d.ts +1 -4
  140. package/lib/commands/make/backend/service-provider.js +3 -4
  141. package/lib/commands/make/backend/validator.d.ts +1 -4
  142. package/lib/commands/make/backend/validator.js +2 -2
  143. package/lib/commands/make/frontend/component.d.ts +4 -5
  144. package/lib/commands/make/frontend/component.js +7 -2
  145. package/lib/commands/make/frontend/forum-page.d.ts +11 -0
  146. package/lib/commands/make/frontend/forum-page.js +92 -0
  147. package/lib/commands/make/frontend/gambit.d.ts +11 -0
  148. package/lib/commands/make/frontend/gambit.js +30 -0
  149. package/lib/commands/make/frontend/modal.d.ts +1 -4
  150. package/lib/commands/make/frontend/modal.js +3 -2
  151. package/lib/commands/make/frontend/model.d.ts +6 -7
  152. package/lib/commands/make/frontend/model.js +27 -28
  153. package/lib/commands/make/frontend/notification.d.ts +12 -0
  154. package/lib/commands/make/frontend/notification.js +62 -0
  155. package/lib/commands/make/frontend/post-type.d.ts +12 -0
  156. package/lib/commands/make/frontend/post-type.js +59 -0
  157. package/lib/commands/make/locale.d.ts +11 -0
  158. package/lib/commands/make/locale.js +27 -0
  159. package/lib/commands/make/model.d.ts +12 -0
  160. package/lib/commands/make/model.js +29 -0
  161. package/lib/commands/make/notification.d.ts +11 -0
  162. package/lib/commands/make/notification.js +33 -0
  163. package/lib/commands/make/post-type.d.ts +11 -0
  164. package/lib/commands/make/post-type.js +31 -0
  165. package/lib/commands/monorepo/create.d.ts +12 -0
  166. package/lib/commands/monorepo/create.js +20 -0
  167. package/lib/commands/monorepo/split.d.ts +12 -0
  168. package/lib/commands/monorepo/split.js +19 -0
  169. package/lib/commands/update/js-imports.d.ts +1 -4
  170. package/lib/commands/update/js-imports.js +2 -3
  171. package/lib/commands/upgrade/2.0.d.ts +17 -0
  172. package/lib/commands/upgrade/2.0.js +113 -0
  173. package/lib/help.js +2 -2
  174. package/lib/providers/php-provider.d.ts +7 -1
  175. package/lib/providers/php-provider.js +18 -5
  176. package/lib/steps/extenders/{api-serializer.d.ts → api-resource.d.ts} +1 -1
  177. package/lib/steps/extenders/api-resource.js +38 -0
  178. package/lib/steps/extenders/base.d.ts +1 -1
  179. package/lib/steps/extenders/base.js +13 -1
  180. package/lib/steps/extenders/console-command.js +1 -1
  181. package/lib/steps/extenders/event.js +1 -1
  182. package/lib/steps/extenders/mail-driver.d.ts +5 -0
  183. package/lib/steps/extenders/mail-driver.js +58 -0
  184. package/lib/steps/extenders/middleware.d.ts +5 -0
  185. package/lib/steps/extenders/middleware.js +57 -0
  186. package/lib/steps/extenders/notification-driver.d.ts +5 -0
  187. package/lib/steps/extenders/notification-driver.js +58 -0
  188. package/lib/steps/extenders/notification-type.d.ts +5 -0
  189. package/lib/steps/extenders/notification-type.js +55 -0
  190. package/lib/steps/extenders/policy.js +1 -1
  191. package/lib/steps/extenders/post-type.d.ts +5 -0
  192. package/lib/steps/extenders/post-type.js +42 -0
  193. package/lib/steps/extenders/route.js +11 -2
  194. package/lib/steps/extenders/search-driver.d.ts +5 -0
  195. package/lib/steps/extenders/search-driver.js +38 -0
  196. package/lib/steps/extenders/search-filter.d.ts +5 -0
  197. package/lib/steps/extenders/search-filter.js +67 -0
  198. package/lib/steps/extenders/service-provider.js +1 -1
  199. package/lib/steps/gen-ext-scaffolder.d.ts +4 -4
  200. package/lib/steps/gen-ext-scaffolder.js +264 -58
  201. package/lib/steps/js/base.d.ts +14 -5
  202. package/lib/steps/js/base.js +101 -27
  203. package/lib/steps/js/model.d.ts +4 -7
  204. package/lib/steps/js/model.js +45 -19
  205. package/lib/steps/js/notification.d.ts +7 -0
  206. package/lib/steps/js/notification.js +58 -0
  207. package/lib/steps/js/post-type.d.ts +8 -0
  208. package/lib/steps/js/post-type.js +60 -0
  209. package/lib/steps/js/routes.d.ts +7 -0
  210. package/lib/steps/js/routes.js +63 -0
  211. package/lib/steps/js/search-driver-locale.d.ts +8 -0
  212. package/lib/steps/js/search-driver-locale.js +36 -0
  213. package/lib/steps/js/search-gambit.d.ts +7 -0
  214. package/lib/steps/js/search-gambit.js +51 -0
  215. package/lib/steps/locale/base.d.ts +32 -0
  216. package/lib/steps/locale/base.js +97 -0
  217. package/lib/steps/misc/composer.js +2 -2
  218. package/lib/steps/misc/git.d.ts +1 -1
  219. package/lib/steps/misc/git.js +3 -3
  220. package/lib/steps/misc/npm.d.ts +11 -0
  221. package/lib/steps/misc/npm.js +19 -0
  222. package/lib/steps/misc/yarn.js +2 -2
  223. package/lib/steps/monorepo/create.d.ts +19 -0
  224. package/lib/steps/monorepo/create.js +187 -0
  225. package/lib/steps/monorepo/split.d.ts +14 -0
  226. package/lib/steps/monorepo/split.js +99 -0
  227. package/lib/steps/stubs/backend/advanced-api-resource.d.ts +13 -0
  228. package/lib/steps/stubs/backend/advanced-api-resource.js +81 -0
  229. package/lib/steps/stubs/backend/{api-serializer.d.ts → api-resource.d.ts} +2 -2
  230. package/lib/steps/stubs/backend/{api-serializer.js → api-resource.js} +12 -9
  231. package/lib/steps/stubs/backend/command.d.ts +2 -21
  232. package/lib/steps/stubs/backend/command.js +15 -1
  233. package/lib/steps/stubs/backend/{api-controller.d.ts → controller.d.ts} +4 -14
  234. package/lib/steps/stubs/backend/controller.js +40 -0
  235. package/lib/steps/stubs/backend/event-listener.d.ts +1 -1
  236. package/lib/steps/stubs/backend/event-listener.js +3 -1
  237. package/lib/steps/stubs/backend/filter.d.ts +8 -0
  238. package/lib/steps/stubs/backend/filter.js +44 -0
  239. package/lib/steps/stubs/backend/handler-command.d.ts +2 -27
  240. package/lib/steps/stubs/backend/handler-command.js +3 -1
  241. package/lib/steps/stubs/backend/handler.d.ts +1 -1
  242. package/lib/steps/stubs/backend/handler.js +5 -1
  243. package/lib/steps/stubs/backend/integration-test.d.ts +1 -1
  244. package/lib/steps/stubs/backend/integration-test.js +1 -4
  245. package/lib/steps/stubs/backend/job.d.ts +1 -1
  246. package/lib/steps/stubs/backend/job.js +1 -0
  247. package/lib/steps/stubs/backend/mail-driver.d.ts +7 -0
  248. package/lib/steps/stubs/backend/mail-driver.js +30 -0
  249. package/lib/steps/stubs/backend/middleware.d.ts +22 -0
  250. package/lib/steps/stubs/backend/middleware.js +31 -0
  251. package/lib/steps/stubs/backend/migration.js +6 -3
  252. package/lib/steps/stubs/backend/model.d.ts +2 -24
  253. package/lib/steps/stubs/backend/model.js +3 -5
  254. package/lib/steps/stubs/backend/notification-blueprint.d.ts +7 -0
  255. package/lib/steps/stubs/backend/notification-blueprint.js +44 -0
  256. package/lib/steps/stubs/backend/notification-driver.d.ts +7 -0
  257. package/lib/steps/stubs/backend/notification-driver.js +30 -0
  258. package/lib/steps/stubs/backend/policy.d.ts +1 -1
  259. package/lib/steps/stubs/backend/policy.js +3 -1
  260. package/lib/steps/stubs/backend/post-type.d.ts +7 -0
  261. package/lib/steps/stubs/backend/post-type.js +44 -0
  262. package/lib/steps/stubs/backend/repository.d.ts +1 -1
  263. package/lib/steps/stubs/backend/repository.js +3 -1
  264. package/lib/steps/stubs/backend/search-driver-searcher.d.ts +24 -0
  265. package/lib/steps/stubs/backend/search-driver-searcher.js +32 -0
  266. package/lib/steps/stubs/backend/search-driver.d.ts +8 -0
  267. package/lib/steps/stubs/backend/search-driver.js +49 -0
  268. package/lib/steps/stubs/backend/service-provider.d.ts +1 -1
  269. package/lib/steps/stubs/backend/service-provider.js +1 -0
  270. package/lib/steps/stubs/backend/validator.d.ts +1 -1
  271. package/lib/steps/stubs/backend/validator.js +1 -0
  272. package/lib/steps/stubs/flarum-base.js +1 -1
  273. package/lib/steps/stubs/frontend/component.d.ts +0 -5
  274. package/lib/steps/stubs/frontend/component.js +1 -0
  275. package/lib/steps/stubs/frontend/forum-page.d.ts +25 -0
  276. package/lib/steps/stubs/frontend/forum-page.js +37 -0
  277. package/lib/steps/stubs/frontend/gambit.d.ts +7 -0
  278. package/lib/steps/stubs/frontend/gambit.js +50 -0
  279. package/lib/steps/stubs/frontend/modal.d.ts +0 -5
  280. package/lib/steps/stubs/frontend/modal.js +1 -0
  281. package/lib/steps/stubs/frontend/model.d.ts +8 -1
  282. package/lib/steps/stubs/frontend/model.js +6 -0
  283. package/lib/steps/stubs/frontend/notification.d.ts +11 -0
  284. package/lib/steps/stubs/frontend/notification.js +48 -0
  285. package/lib/steps/stubs/frontend/post-type.d.ts +11 -0
  286. package/lib/steps/stubs/frontend/post-type.js +48 -0
  287. package/lib/steps/stubs/js-base.js +12 -5
  288. package/lib/steps/stubs/php-base.js +13 -9
  289. package/lib/steps/update/js-imports.js +9 -3
  290. package/lib/steps/upgrade/twopointoh/backend/email-views.d.ts +18 -0
  291. package/lib/steps/upgrade/twopointoh/backend/email-views.js +81 -0
  292. package/lib/steps/upgrade/twopointoh/backend/filesystem.d.ts +8 -0
  293. package/lib/steps/upgrade/twopointoh/backend/filesystem.js +40 -0
  294. package/lib/steps/upgrade/twopointoh/backend/intervention-image.d.ts +8 -0
  295. package/lib/steps/upgrade/twopointoh/backend/intervention-image.js +44 -0
  296. package/lib/steps/upgrade/twopointoh/backend/json-api.d.ts +12 -0
  297. package/lib/steps/upgrade/twopointoh/backend/json-api.js +111 -0
  298. package/lib/steps/upgrade/twopointoh/backend/mailer.d.ts +8 -0
  299. package/lib/steps/upgrade/twopointoh/backend/mailer.js +37 -0
  300. package/lib/steps/upgrade/twopointoh/backend/misc.d.ts +8 -0
  301. package/lib/steps/upgrade/twopointoh/backend/misc.js +42 -0
  302. package/lib/steps/upgrade/twopointoh/backend/phpunit.d.ts +8 -0
  303. package/lib/steps/upgrade/twopointoh/backend/phpunit.js +52 -0
  304. package/lib/steps/upgrade/twopointoh/backend/search.d.ts +28 -0
  305. package/lib/steps/upgrade/twopointoh/backend/search.js +200 -0
  306. package/lib/steps/upgrade/twopointoh/base.d.ts +58 -0
  307. package/lib/steps/upgrade/twopointoh/base.js +284 -0
  308. package/lib/steps/upgrade/twopointoh/dependencies.d.ts +10 -0
  309. package/lib/steps/upgrade/twopointoh/dependencies.js +108 -0
  310. package/lib/steps/upgrade/twopointoh/frontend/code-splitting/usage-of-lazy-modules.d.ts +26 -0
  311. package/lib/steps/upgrade/twopointoh/frontend/code-splitting/usage-of-lazy-modules.js +418 -0
  312. package/lib/steps/upgrade/twopointoh/frontend/export-registry/compat.d.ts +12 -0
  313. package/lib/steps/upgrade/twopointoh/frontend/export-registry/compat.js +75 -0
  314. package/lib/steps/upgrade/twopointoh/frontend/export-registry/import-ext.d.ts +13 -0
  315. package/lib/steps/upgrade/twopointoh/frontend/export-registry/import-ext.js +126 -0
  316. package/lib/steps/upgrade/twopointoh/frontend/format.d.ts +8 -0
  317. package/lib/steps/upgrade/twopointoh/frontend/format.js +32 -0
  318. package/lib/steps/upgrade/twopointoh/frontend/misc.d.ts +17 -0
  319. package/lib/steps/upgrade/twopointoh/frontend/misc.js +433 -0
  320. package/lib/steps/upgrade/twopointoh/infra.d.ts +10 -0
  321. package/lib/steps/upgrade/twopointoh/infra.js +51 -0
  322. package/lib/steps/upgrade/twopointoh/less.d.ts +12 -0
  323. package/lib/steps/upgrade/twopointoh/less.js +217 -0
  324. package/lib/utils/add-extenders.d.ts +2 -0
  325. package/lib/utils/add-extenders.js +115 -0
  326. package/lib/utils/ast.d.ts +22 -0
  327. package/lib/utils/ast.js +235 -0
  328. package/lib/utils/composer.d.ts +2 -1
  329. package/lib/utils/migration.js +3 -1
  330. package/lib/utils/model-name.d.ts +1 -0
  331. package/lib/utils/model-name.js +7 -3
  332. package/lib/utils/monorepo.d.ts +24 -0
  333. package/lib/utils/monorepo.js +24 -0
  334. package/lib/utils/validation.d.ts +6 -1
  335. package/lib/utils/validation.js +15 -0
  336. package/oclif.manifest.json +1 -1
  337. package/package.json +27 -14
  338. package/php-subsystem/composer.json +11 -9
  339. package/php-subsystem/composer.lock +66 -71
  340. package/php-subsystem/index.php +41 -6
  341. package/php-subsystem/src/CustomPrettyPrinter.php +1 -1
  342. package/php-subsystem/src/ExtenderUtil.php +7 -13
  343. package/php-subsystem/src/NodeUtil.php +72 -0
  344. package/php-subsystem/src/NodeVisitors/AddExtender.php +28 -12
  345. package/php-subsystem/src/NodeVisitors/AddUses.php +24 -0
  346. package/php-subsystem/src/NodeVisitors/ChangeSignatures.php +200 -0
  347. package/php-subsystem/src/NodeVisitors/ReplaceUses.php +175 -0
  348. package/php-subsystem/src/Upgrade/Replacement.php +51 -0
  349. package/php-subsystem/src/Upgrade/ReplacementResult.php +17 -0
  350. package/php-subsystem/src/Upgrade/TwoPointOh/EmailViews.php +94 -0
  351. package/php-subsystem/src/Upgrade/TwoPointOh/Filesystem.php +88 -0
  352. package/php-subsystem/src/Upgrade/TwoPointOh/InterventionImage.php +86 -0
  353. package/php-subsystem/src/Upgrade/TwoPointOh/JsonApi.php +186 -0
  354. package/php-subsystem/src/Upgrade/TwoPointOh/Misc.php +564 -0
  355. package/php-subsystem/src/Upgrade/TwoPointOh/PhpUnit.php +241 -0
  356. package/php-subsystem/src/Upgrade/TwoPointOh/Search.php +589 -0
  357. package/php-subsystem/vendor/autoload.php +18 -0
  358. package/php-subsystem/vendor/bin/php-parse +119 -0
  359. package/php-subsystem/vendor/composer/ClassLoader.php +166 -32
  360. package/php-subsystem/vendor/composer/InstalledVersions.php +350 -209
  361. package/php-subsystem/vendor/composer/autoload_classmap.php +1 -1
  362. package/php-subsystem/vendor/composer/autoload_namespaces.php +1 -1
  363. package/php-subsystem/vendor/composer/autoload_psr4.php +1 -1
  364. package/php-subsystem/vendor/composer/autoload_real.php +3 -22
  365. package/php-subsystem/vendor/composer/installed.json +56 -61
  366. package/php-subsystem/vendor/composer/installed.php +29 -30
  367. package/php-subsystem/vendor/composer/platform_check.php +2 -2
  368. package/php-subsystem/vendor/nikic/php-parser/README.md +21 -13
  369. package/php-subsystem/vendor/nikic/php-parser/bin/php-parse +12 -11
  370. package/php-subsystem/vendor/nikic/php-parser/composer.json +41 -39
  371. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Builder/ClassConst.php +58 -11
  372. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Builder/Class_.php +54 -25
  373. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Builder/Declaration.php +11 -4
  374. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Builder/EnumCase.php +87 -0
  375. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Builder/Enum_.php +116 -0
  376. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Builder/FunctionLike.php +8 -9
  377. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Builder/Function_.php +22 -5
  378. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Builder/Interface_.php +26 -7
  379. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Builder/Method.php +31 -13
  380. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Builder/Namespace_.php +5 -5
  381. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Builder/Param.php +69 -26
  382. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Builder/Property.php +47 -18
  383. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Builder/TraitUse.php +6 -5
  384. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Builder/TraitUseAdaptation.php +25 -28
  385. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Builder/Trait_.php +31 -8
  386. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Builder/Use_.php +8 -8
  387. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Builder.php +2 -3
  388. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/BuilderFactory.php +85 -70
  389. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/BuilderHelpers.php +119 -71
  390. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Comment/Doc.php +1 -2
  391. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Comment.php +35 -67
  392. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/ConstExprEvaluationException.php +3 -3
  393. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/ConstExprEvaluator.php +17 -9
  394. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Error.php +24 -33
  395. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/ErrorHandler/Collecting.php +6 -9
  396. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/ErrorHandler/Throwing.php +2 -3
  397. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/ErrorHandler.php +2 -3
  398. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Internal/DiffElem.php +11 -7
  399. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Internal/Differ.php +36 -22
  400. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Internal/PrintableNewAnonClassNode.php +24 -14
  401. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Internal/TokenPolyfill.php +237 -0
  402. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Internal/TokenStream.php +63 -69
  403. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/JsonDecoder.php +15 -10
  404. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Lexer/Emulative.php +74 -92
  405. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/AttributeEmulator.php +11 -18
  406. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/EnumTokenEmulator.php +10 -15
  407. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ExplicitOctalEmulator.php +45 -0
  408. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/KeywordEmulator.php +19 -25
  409. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/MatchTokenEmulator.php +6 -10
  410. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/NullsafeTokenEmulator.php +22 -29
  411. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ReadonlyFunctionTokenEmulator.php +31 -0
  412. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ReadonlyTokenEmulator.php +31 -0
  413. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ReverseEmulator.php +6 -5
  414. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/TokenEmulator.php +10 -5
  415. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Lexer.php +70 -491
  416. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Modifiers.php +69 -0
  417. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/NameContext.php +23 -24
  418. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Arg.php +13 -14
  419. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/ArrayItem.php +43 -0
  420. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Attribute.php +9 -10
  421. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/AttributeGroup.php +5 -7
  422. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/ClosureUse.php +36 -0
  423. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/ComplexType.php +13 -0
  424. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Const_.php +12 -13
  425. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/DeclareItem.php +37 -0
  426. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayDimFetch.php +10 -11
  427. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayItem.php +1 -39
  428. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Array_.php +11 -11
  429. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ArrowFunction.php +35 -30
  430. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Assign.php +9 -10
  431. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseAnd.php +2 -3
  432. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseOr.php +2 -3
  433. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseXor.php +2 -3
  434. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Coalesce.php +2 -3
  435. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Concat.php +2 -3
  436. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Div.php +2 -3
  437. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Minus.php +2 -3
  438. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Mod.php +2 -3
  439. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Mul.php +2 -3
  440. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Plus.php +2 -3
  441. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Pow.php +2 -3
  442. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/ShiftLeft.php +2 -3
  443. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/ShiftRight.php +2 -3
  444. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp.php +7 -8
  445. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignRef.php +9 -10
  446. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseAnd.php +4 -5
  447. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseOr.php +4 -5
  448. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseXor.php +4 -5
  449. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BooleanAnd.php +4 -5
  450. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BooleanOr.php +4 -5
  451. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Coalesce.php +4 -5
  452. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Concat.php +4 -5
  453. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Div.php +4 -5
  454. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Equal.php +4 -5
  455. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Greater.php +4 -5
  456. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/GreaterOrEqual.php +4 -5
  457. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Identical.php +4 -5
  458. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/LogicalAnd.php +4 -5
  459. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/LogicalOr.php +4 -5
  460. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/LogicalXor.php +4 -5
  461. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Minus.php +4 -5
  462. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Mod.php +4 -5
  463. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Mul.php +4 -5
  464. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/NotEqual.php +4 -5
  465. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/NotIdentical.php +4 -5
  466. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Plus.php +4 -5
  467. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Pow.php +4 -5
  468. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/ShiftLeft.php +4 -5
  469. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/ShiftRight.php +4 -5
  470. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Smaller.php +4 -5
  471. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/SmallerOrEqual.php +4 -5
  472. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Spaceship.php +4 -5
  473. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp.php +8 -11
  474. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BitwiseNot.php +7 -8
  475. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BooleanNot.php +7 -8
  476. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/CallLike.php +35 -0
  477. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Array_.php +2 -3
  478. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Bool_.php +2 -3
  479. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Double.php +5 -6
  480. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Int_.php +2 -3
  481. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Object_.php +2 -3
  482. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/String_.php +2 -3
  483. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Unset_.php +2 -3
  484. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast.php +5 -6
  485. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ClassConstFetch.php +12 -12
  486. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Clone_.php +7 -8
  487. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Closure.php +34 -27
  488. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ClosureUse.php +1 -32
  489. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ConstFetch.php +7 -8
  490. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Empty_.php +7 -8
  491. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Error.php +5 -6
  492. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ErrorSuppress.php +7 -8
  493. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Eval_.php +7 -8
  494. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Exit_.php +10 -11
  495. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/FuncCall.php +15 -12
  496. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Include_.php +13 -14
  497. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Instanceof_.php +11 -11
  498. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Isset_.php +7 -8
  499. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/List_.php +12 -8
  500. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Match_.php +8 -7
  501. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/MethodCall.php +18 -13
  502. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/New_.php +17 -12
  503. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/NullsafeMethodCall.php +18 -13
  504. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/NullsafePropertyFetch.php +10 -10
  505. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PostDec.php +7 -8
  506. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PostInc.php +7 -8
  507. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PreDec.php +6 -7
  508. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PreInc.php +7 -8
  509. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Print_.php +7 -8
  510. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PropertyFetch.php +10 -10
  511. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ShellExec.php +9 -9
  512. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/StaticCall.php +19 -14
  513. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/StaticPropertyFetch.php +11 -11
  514. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Ternary.php +12 -13
  515. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Throw_.php +6 -7
  516. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryMinus.php +7 -8
  517. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryPlus.php +7 -8
  518. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Variable.php +6 -7
  519. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/YieldFrom.php +7 -8
  520. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Yield_.php +10 -11
  521. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Expr.php +1 -2
  522. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/FunctionLike.php +6 -9
  523. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Identifier.php +13 -13
  524. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/InterpolatedStringPart.php +32 -0
  525. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/IntersectionType.php +27 -0
  526. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/MatchArm.php +8 -9
  527. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Name/FullyQualified.php +8 -9
  528. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Name/Relative.php +8 -9
  529. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Name.php +80 -53
  530. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/NullableType.php +10 -11
  531. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Param.php +47 -23
  532. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/PropertyItem.php +37 -0
  533. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/DNumber.php +1 -68
  534. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/Encapsed.php +1 -29
  535. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/EncapsedStringPart.php +1 -28
  536. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/Float_.php +78 -0
  537. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/Int_.php +82 -0
  538. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/InterpolatedString.php +34 -0
  539. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/LNumber.php +1 -71
  540. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Class_.php +4 -5
  541. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Dir.php +4 -5
  542. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/File.php +4 -5
  543. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Function_.php +4 -5
  544. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Line.php +4 -5
  545. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Method.php +4 -5
  546. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Namespace_.php +4 -5
  547. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Trait_.php +4 -5
  548. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst.php +4 -5
  549. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/String_.php +44 -24
  550. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar.php +1 -2
  551. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/StaticVar.php +39 -0
  552. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Block.php +29 -0
  553. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Break_.php +8 -9
  554. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Case_.php +10 -11
  555. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Catch_.php +11 -12
  556. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassConst.php +33 -27
  557. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassLike.php +15 -15
  558. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassMethod.php +66 -71
  559. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Class_.php +48 -61
  560. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Const_.php +7 -8
  561. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Continue_.php +8 -9
  562. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/DeclareDeclare.php +1 -32
  563. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Declare_.php +12 -12
  564. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Do_.php +9 -10
  565. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Echo_.php +7 -8
  566. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ElseIf_.php +9 -10
  567. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Else_.php +7 -8
  568. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/EnumCase.php +11 -12
  569. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Enum_.php +17 -13
  570. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Expression.php +7 -8
  571. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Finally_.php +7 -8
  572. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/For_.php +19 -15
  573. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Foreach_.php +20 -17
  574. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Function_.php +31 -27
  575. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Global_.php +7 -8
  576. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Goto_.php +7 -8
  577. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/GroupUse.php +16 -14
  578. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/HaltCompiler.php +7 -8
  579. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/If_.php +18 -15
  580. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/InlineHTML.php +7 -8
  581. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Interface_.php +13 -10
  582. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Label.php +7 -8
  583. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Namespace_.php +11 -12
  584. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Nop.php +4 -5
  585. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Property.php +35 -36
  586. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/PropertyProperty.php +1 -32
  587. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Return_.php +8 -9
  588. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/StaticVar.php +1 -35
  589. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Static_.php +8 -8
  590. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Switch_.php +9 -10
  591. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUse.php +8 -9
  592. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation/Alias.php +12 -13
  593. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation/Precedence.php +9 -10
  594. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation.php +3 -4
  595. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Trait_.php +10 -8
  596. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TryCatch.php +11 -12
  597. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Unset_.php +7 -8
  598. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/UseUse.php +1 -50
  599. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Use_.php +16 -16
  600. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/While_.php +9 -10
  601. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt.php +1 -2
  602. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/UnionType.php +8 -11
  603. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/UseItem.php +55 -0
  604. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/VarLikeIdentifier.php +2 -3
  605. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/VariadicPlaceholder.php +27 -0
  606. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node.php +24 -29
  607. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/NodeAbstract.php +20 -20
  608. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/NodeDumper.php +169 -82
  609. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/NodeFinder.php +28 -19
  610. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php +71 -84
  611. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/NodeTraverserInterface.php +4 -7
  612. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/CloningVisitor.php +1 -2
  613. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/CommentAnnotatingVisitor.php +82 -0
  614. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/FindingVisitor.php +4 -5
  615. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/FirstFindingVisitor.php +6 -7
  616. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php +40 -24
  617. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/NodeConnectingVisitor.php +2 -3
  618. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/ParentConnectingVisitor.php +8 -11
  619. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor.php +59 -7
  620. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/NodeVisitorAbstract.php +1 -2
  621. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Parser/Php7.php +2011 -2058
  622. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Parser/Php8.php +2717 -0
  623. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Parser.php +9 -3
  624. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/ParserAbstract.php +466 -248
  625. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/ParserFactory.php +31 -33
  626. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/PhpVersion.php +164 -0
  627. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinter/Standard.php +419 -338
  628. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinter.php +51 -0
  629. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php +587 -431
  630. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Token.php +18 -0
  631. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/compatibility_tokens.php +63 -0
  632. package/boilerplate/stubs/backend/api-controller/create.php +0 -53
  633. package/boilerplate/stubs/backend/api-controller/delete.php +0 -52
  634. package/boilerplate/stubs/backend/api-controller/list.php +0 -61
  635. package/boilerplate/stubs/backend/api-controller/normal.php +0 -29
  636. package/boilerplate/stubs/backend/api-controller/show.php +0 -48
  637. package/boilerplate/stubs/backend/api-controller/update.php +0 -54
  638. package/boilerplate/stubs/backend/api-serializer.php +0 -36
  639. package/lib/commands/make/backend/api-controller.js +0 -27
  640. package/lib/commands/make/backend/api-serializer-attributes.js +0 -15
  641. package/lib/commands/make/backend/api-serializer.js +0 -15
  642. package/lib/steps/extenders/api-serializer.js +0 -77
  643. package/lib/steps/stubs/backend/api-controller.js +0 -62
  644. package/lib/steps/stubs/frontend/migration.js +0 -1
  645. package/php-subsystem/vendor/nikic/php-parser/.editorconfig +0 -9
  646. package/php-subsystem/vendor/nikic/php-parser/grammar/README.md +0 -30
  647. package/php-subsystem/vendor/nikic/php-parser/grammar/parser.template +0 -106
  648. package/php-subsystem/vendor/nikic/php-parser/grammar/php5.y +0 -1026
  649. package/php-subsystem/vendor/nikic/php-parser/grammar/php7.y +0 -1152
  650. package/php-subsystem/vendor/nikic/php-parser/grammar/phpyLang.php +0 -192
  651. package/php-subsystem/vendor/nikic/php-parser/grammar/rebuildParsers.php +0 -81
  652. package/php-subsystem/vendor/nikic/php-parser/grammar/tokens.template +0 -17
  653. package/php-subsystem/vendor/nikic/php-parser/grammar/tokens.y +0 -115
  654. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/CoaleseEqualTokenEmulator.php +0 -47
  655. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/FlexibleDocStringEmulator.php +0 -76
  656. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/FnTokenEmulator.php +0 -23
  657. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/NumericLiteralSeparatorEmulator.php +0 -105
  658. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Throw_.php +0 -30
  659. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Parser/Multiple.php +0 -55
  660. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Parser/Php5.php +0 -2630
  661. package/php-subsystem/vendor/nikic/php-parser/lib/PhpParser/Parser/Tokens.php +0 -145
  662. /package/{lib/steps/stubs/frontend/migration.d.ts → boilerplate/skeleton/extension/js/tests/integration/.gitkeep} +0 -0
  663. /package/boilerplate/skeleton/extension/js/{webpack.config.js → webpack.config.cjs} +0 -0
@@ -13,11 +13,10 @@ use PhpParser\Node\Scalar\MagicConst;
13
13
  use PhpParser\Node\Stmt;
14
14
  use PhpParser\PrettyPrinterAbstract;
15
15
 
16
- class Standard extends PrettyPrinterAbstract
17
- {
16
+ class Standard extends PrettyPrinterAbstract {
18
17
  // Special nodes
19
18
 
20
- protected function pParam(Node\Param $node) {
19
+ protected function pParam(Node\Param $node): string {
21
20
  return $this->pAttrGroups($node->attrGroups, true)
22
21
  . $this->pModifiers($node->flags)
23
22
  . ($node->type ? $this->p($node->type) . ' ' : '')
@@ -27,152 +26,180 @@ class Standard extends PrettyPrinterAbstract
27
26
  . ($node->default ? ' = ' . $this->p($node->default) : '');
28
27
  }
29
28
 
30
- protected function pArg(Node\Arg $node) {
29
+ protected function pArg(Node\Arg $node): string {
31
30
  return ($node->name ? $node->name->toString() . ': ' : '')
32
31
  . ($node->byRef ? '&' : '') . ($node->unpack ? '...' : '')
33
32
  . $this->p($node->value);
34
33
  }
35
34
 
36
- protected function pConst(Node\Const_ $node) {
35
+ protected function pVariadicPlaceholder(Node\VariadicPlaceholder $node): string {
36
+ return '...';
37
+ }
38
+
39
+ protected function pConst(Node\Const_ $node): string {
37
40
  return $node->name . ' = ' . $this->p($node->value);
38
41
  }
39
42
 
40
- protected function pNullableType(Node\NullableType $node) {
43
+ protected function pNullableType(Node\NullableType $node): string {
41
44
  return '?' . $this->p($node->type);
42
45
  }
43
46
 
44
- protected function pUnionType(Node\UnionType $node) {
45
- return $this->pImplode($node->types, '|');
47
+ protected function pUnionType(Node\UnionType $node): string {
48
+ $types = [];
49
+ foreach ($node->types as $typeNode) {
50
+ if ($typeNode instanceof Node\IntersectionType) {
51
+ $types[] = '('. $this->p($typeNode) . ')';
52
+ continue;
53
+ }
54
+ $types[] = $this->p($typeNode);
55
+ }
56
+ return implode('|', $types);
46
57
  }
47
58
 
48
- protected function pIdentifier(Node\Identifier $node) {
59
+ protected function pIntersectionType(Node\IntersectionType $node): string {
60
+ return $this->pImplode($node->types, '&');
61
+ }
62
+
63
+ protected function pIdentifier(Node\Identifier $node): string {
49
64
  return $node->name;
50
65
  }
51
66
 
52
- protected function pVarLikeIdentifier(Node\VarLikeIdentifier $node) {
67
+ protected function pVarLikeIdentifier(Node\VarLikeIdentifier $node): string {
53
68
  return '$' . $node->name;
54
69
  }
55
70
 
56
- protected function pAttribute(Node\Attribute $node) {
71
+ protected function pAttribute(Node\Attribute $node): string {
57
72
  return $this->p($node->name)
58
73
  . ($node->args ? '(' . $this->pCommaSeparated($node->args) . ')' : '');
59
74
  }
60
75
 
61
- protected function pAttributeGroup(Node\AttributeGroup $node) {
76
+ protected function pAttributeGroup(Node\AttributeGroup $node): string {
62
77
  return '#[' . $this->pCommaSeparated($node->attrs) . ']';
63
78
  }
64
79
 
65
80
  // Names
66
81
 
67
- protected function pName(Name $node) {
68
- return implode('\\', $node->parts);
82
+ protected function pName(Name $node): string {
83
+ return $node->name;
69
84
  }
70
85
 
71
- protected function pName_FullyQualified(Name\FullyQualified $node) {
72
- return '\\' . implode('\\', $node->parts);
86
+ protected function pName_FullyQualified(Name\FullyQualified $node): string {
87
+ return '\\' . $node->name;
73
88
  }
74
89
 
75
- protected function pName_Relative(Name\Relative $node) {
76
- return 'namespace\\' . implode('\\', $node->parts);
90
+ protected function pName_Relative(Name\Relative $node): string {
91
+ return 'namespace\\' . $node->name;
77
92
  }
78
93
 
79
94
  // Magic Constants
80
95
 
81
- protected function pScalar_MagicConst_Class(MagicConst\Class_ $node) {
96
+ protected function pScalar_MagicConst_Class(MagicConst\Class_ $node): string {
82
97
  return '__CLASS__';
83
98
  }
84
99
 
85
- protected function pScalar_MagicConst_Dir(MagicConst\Dir $node) {
100
+ protected function pScalar_MagicConst_Dir(MagicConst\Dir $node): string {
86
101
  return '__DIR__';
87
102
  }
88
103
 
89
- protected function pScalar_MagicConst_File(MagicConst\File $node) {
104
+ protected function pScalar_MagicConst_File(MagicConst\File $node): string {
90
105
  return '__FILE__';
91
106
  }
92
107
 
93
- protected function pScalar_MagicConst_Function(MagicConst\Function_ $node) {
108
+ protected function pScalar_MagicConst_Function(MagicConst\Function_ $node): string {
94
109
  return '__FUNCTION__';
95
110
  }
96
111
 
97
- protected function pScalar_MagicConst_Line(MagicConst\Line $node) {
112
+ protected function pScalar_MagicConst_Line(MagicConst\Line $node): string {
98
113
  return '__LINE__';
99
114
  }
100
115
 
101
- protected function pScalar_MagicConst_Method(MagicConst\Method $node) {
116
+ protected function pScalar_MagicConst_Method(MagicConst\Method $node): string {
102
117
  return '__METHOD__';
103
118
  }
104
119
 
105
- protected function pScalar_MagicConst_Namespace(MagicConst\Namespace_ $node) {
120
+ protected function pScalar_MagicConst_Namespace(MagicConst\Namespace_ $node): string {
106
121
  return '__NAMESPACE__';
107
122
  }
108
123
 
109
- protected function pScalar_MagicConst_Trait(MagicConst\Trait_ $node) {
124
+ protected function pScalar_MagicConst_Trait(MagicConst\Trait_ $node): string {
110
125
  return '__TRAIT__';
111
126
  }
112
127
 
113
128
  // Scalars
114
129
 
115
- protected function pScalar_String(Scalar\String_ $node) {
130
+ private function indentString(string $str): string {
131
+ return str_replace("\n", $this->nl, $str);
132
+ }
133
+
134
+ protected function pScalar_String(Scalar\String_ $node): string {
116
135
  $kind = $node->getAttribute('kind', Scalar\String_::KIND_SINGLE_QUOTED);
117
136
  switch ($kind) {
118
137
  case Scalar\String_::KIND_NOWDOC:
119
138
  $label = $node->getAttribute('docLabel');
120
139
  if ($label && !$this->containsEndLabel($node->value, $label)) {
140
+ $shouldIdent = $this->phpVersion->supportsFlexibleHeredoc();
141
+ $nl = $shouldIdent ? $this->nl : $this->newline;
121
142
  if ($node->value === '') {
122
- return "<<<'$label'\n$label" . $this->docStringEndToken;
143
+ return "<<<'$label'$nl$label{$this->docStringEndToken}";
123
144
  }
124
145
 
125
- return "<<<'$label'\n$node->value\n$label"
126
- . $this->docStringEndToken;
146
+ // Make sure trailing \r is not combined with following \n into CRLF.
147
+ if ($node->value[strlen($node->value) - 1] !== "\r") {
148
+ $value = $shouldIdent ? $this->indentString($node->value) : $node->value;
149
+ return "<<<'$label'$nl$value$nl$label{$this->docStringEndToken}";
150
+ }
127
151
  }
128
152
  /* break missing intentionally */
153
+ // no break
129
154
  case Scalar\String_::KIND_SINGLE_QUOTED:
130
155
  return $this->pSingleQuotedString($node->value);
131
156
  case Scalar\String_::KIND_HEREDOC:
132
157
  $label = $node->getAttribute('docLabel');
133
- if ($label && !$this->containsEndLabel($node->value, $label)) {
134
- if ($node->value === '') {
135
- return "<<<$label\n$label" . $this->docStringEndToken;
158
+ $escaped = $this->escapeString($node->value, null);
159
+ if ($label && !$this->containsEndLabel($escaped, $label)) {
160
+ $nl = $this->phpVersion->supportsFlexibleHeredoc() ? $this->nl : $this->newline;
161
+ if ($escaped === '') {
162
+ return "<<<$label$nl$label{$this->docStringEndToken}";
136
163
  }
137
164
 
138
- $escaped = $this->escapeString($node->value, null);
139
- return "<<<$label\n" . $escaped . "\n$label"
140
- . $this->docStringEndToken;
165
+ return "<<<$label$nl$escaped$nl$label{$this->docStringEndToken}";
141
166
  }
142
- /* break missing intentionally */
167
+ /* break missing intentionally */
168
+ // no break
143
169
  case Scalar\String_::KIND_DOUBLE_QUOTED:
144
170
  return '"' . $this->escapeString($node->value, '"') . '"';
145
171
  }
146
172
  throw new \Exception('Invalid string kind');
147
173
  }
148
174
 
149
- protected function pScalar_Encapsed(Scalar\Encapsed $node) {
175
+ protected function pScalar_InterpolatedString(Scalar\InterpolatedString $node): string {
150
176
  if ($node->getAttribute('kind') === Scalar\String_::KIND_HEREDOC) {
151
177
  $label = $node->getAttribute('docLabel');
152
178
  if ($label && !$this->encapsedContainsEndLabel($node->parts, $label)) {
179
+ $nl = $this->phpVersion->supportsFlexibleHeredoc() ? $this->nl : $this->newline;
153
180
  if (count($node->parts) === 1
154
- && $node->parts[0] instanceof Scalar\EncapsedStringPart
181
+ && $node->parts[0] instanceof Node\InterpolatedStringPart
155
182
  && $node->parts[0]->value === ''
156
183
  ) {
157
- return "<<<$label\n$label" . $this->docStringEndToken;
184
+ return "<<<$label$nl$label{$this->docStringEndToken}";
158
185
  }
159
186
 
160
- return "<<<$label\n" . $this->pEncapsList($node->parts, null) . "\n$label"
161
- . $this->docStringEndToken;
187
+ return "<<<$label$nl" . $this->pEncapsList($node->parts, null)
188
+ . "$nl$label{$this->docStringEndToken}";
162
189
  }
163
190
  }
164
191
  return '"' . $this->pEncapsList($node->parts, '"') . '"';
165
192
  }
166
193
 
167
- protected function pScalar_LNumber(Scalar\LNumber $node) {
168
- if ($node->value === -\PHP_INT_MAX-1) {
194
+ protected function pScalar_Int(Scalar\Int_ $node): string {
195
+ if ($node->value === -\PHP_INT_MAX - 1) {
169
196
  // PHP_INT_MIN cannot be represented as a literal,
170
197
  // because the sign is not part of the literal
171
198
  return '(-' . \PHP_INT_MAX . '-1)';
172
199
  }
173
200
 
174
- $kind = $node->getAttribute('kind', Scalar\LNumber::KIND_DEC);
175
- if (Scalar\LNumber::KIND_DEC === $kind) {
201
+ $kind = $node->getAttribute('kind', Scalar\Int_::KIND_DEC);
202
+ if (Scalar\Int_::KIND_DEC === $kind) {
176
203
  return (string) $node->value;
177
204
  }
178
205
 
@@ -184,22 +211,23 @@ class Standard extends PrettyPrinterAbstract
184
211
  $str = (string) $node->value;
185
212
  }
186
213
  switch ($kind) {
187
- case Scalar\LNumber::KIND_BIN:
214
+ case Scalar\Int_::KIND_BIN:
188
215
  return $sign . '0b' . base_convert($str, 10, 2);
189
- case Scalar\LNumber::KIND_OCT:
216
+ case Scalar\Int_::KIND_OCT:
190
217
  return $sign . '0' . base_convert($str, 10, 8);
191
- case Scalar\LNumber::KIND_HEX:
218
+ case Scalar\Int_::KIND_HEX:
192
219
  return $sign . '0x' . base_convert($str, 10, 16);
193
220
  }
194
221
  throw new \Exception('Invalid number kind');
195
222
  }
196
223
 
197
- protected function pScalar_DNumber(Scalar\DNumber $node) {
224
+ protected function pScalar_Float(Scalar\Float_ $node): string {
198
225
  if (!is_finite($node->value)) {
199
226
  if ($node->value === \INF) {
200
- return '\INF';
201
- } elseif ($node->value === -\INF) {
202
- return '-\INF';
227
+ return '1.0E+1000';
228
+ }
229
+ if ($node->value === -\INF) {
230
+ return '-1.0E+1000';
203
231
  } else {
204
232
  return '\NAN';
205
233
  }
@@ -207,7 +235,7 @@ class Standard extends PrettyPrinterAbstract
207
235
 
208
236
  // Try to find a short full-precision representation
209
237
  $stringValue = sprintf('%.16G', $node->value);
210
- if ($node->value !== (double) $stringValue) {
238
+ if ($node->value !== (float) $stringValue) {
211
239
  $stringValue = sprintf('%.17G', $node->value);
212
240
  }
213
241
 
@@ -220,300 +248,289 @@ class Standard extends PrettyPrinterAbstract
220
248
  return preg_match('/^-?[0-9]+$/', $stringValue) ? $stringValue . '.0' : $stringValue;
221
249
  }
222
250
 
223
- protected function pScalar_EncapsedStringPart(Scalar\EncapsedStringPart $node) {
224
- throw new \LogicException('Cannot directly print EncapsedStringPart');
225
- }
226
-
227
251
  // Assignments
228
252
 
229
- protected function pExpr_Assign(Expr\Assign $node) {
230
- return $this->pInfixOp(Expr\Assign::class, $node->var, ' = ', $node->expr);
253
+ protected function pExpr_Assign(Expr\Assign $node, int $precedence, int $lhsPrecedence): string {
254
+ return $this->pPrefixOp(Expr\Assign::class, $this->p($node->var) . ' = ', $node->expr, $precedence, $lhsPrecedence);
231
255
  }
232
256
 
233
- protected function pExpr_AssignRef(Expr\AssignRef $node) {
234
- return $this->pInfixOp(Expr\AssignRef::class, $node->var, ' =& ', $node->expr);
257
+ protected function pExpr_AssignRef(Expr\AssignRef $node, int $precedence, int $lhsPrecedence): string {
258
+ return $this->pPrefixOp(Expr\AssignRef::class, $this->p($node->var) . ' =& ', $node->expr, $precedence, $lhsPrecedence);
235
259
  }
236
260
 
237
- protected function pExpr_AssignOp_Plus(AssignOp\Plus $node) {
238
- return $this->pInfixOp(AssignOp\Plus::class, $node->var, ' += ', $node->expr);
261
+ protected function pExpr_AssignOp_Plus(AssignOp\Plus $node, int $precedence, int $lhsPrecedence): string {
262
+ return $this->pPrefixOp(AssignOp\Plus::class, $this->p($node->var) . ' += ', $node->expr, $precedence, $lhsPrecedence);
239
263
  }
240
264
 
241
- protected function pExpr_AssignOp_Minus(AssignOp\Minus $node) {
242
- return $this->pInfixOp(AssignOp\Minus::class, $node->var, ' -= ', $node->expr);
265
+ protected function pExpr_AssignOp_Minus(AssignOp\Minus $node, int $precedence, int $lhsPrecedence): string {
266
+ return $this->pPrefixOp(AssignOp\Minus::class, $this->p($node->var) . ' -= ', $node->expr, $precedence, $lhsPrecedence);
243
267
  }
244
268
 
245
- protected function pExpr_AssignOp_Mul(AssignOp\Mul $node) {
246
- return $this->pInfixOp(AssignOp\Mul::class, $node->var, ' *= ', $node->expr);
269
+ protected function pExpr_AssignOp_Mul(AssignOp\Mul $node, int $precedence, int $lhsPrecedence): string {
270
+ return $this->pPrefixOp(AssignOp\Mul::class, $this->p($node->var) . ' *= ', $node->expr, $precedence, $lhsPrecedence);
247
271
  }
248
272
 
249
- protected function pExpr_AssignOp_Div(AssignOp\Div $node) {
250
- return $this->pInfixOp(AssignOp\Div::class, $node->var, ' /= ', $node->expr);
273
+ protected function pExpr_AssignOp_Div(AssignOp\Div $node, int $precedence, int $lhsPrecedence): string {
274
+ return $this->pPrefixOp(AssignOp\Div::class, $this->p($node->var) . ' /= ', $node->expr, $precedence, $lhsPrecedence);
251
275
  }
252
276
 
253
- protected function pExpr_AssignOp_Concat(AssignOp\Concat $node) {
254
- return $this->pInfixOp(AssignOp\Concat::class, $node->var, ' .= ', $node->expr);
277
+ protected function pExpr_AssignOp_Concat(AssignOp\Concat $node, int $precedence, int $lhsPrecedence): string {
278
+ return $this->pPrefixOp(AssignOp\Concat::class, $this->p($node->var) . ' .= ', $node->expr, $precedence, $lhsPrecedence);
255
279
  }
256
280
 
257
- protected function pExpr_AssignOp_Mod(AssignOp\Mod $node) {
258
- return $this->pInfixOp(AssignOp\Mod::class, $node->var, ' %= ', $node->expr);
281
+ protected function pExpr_AssignOp_Mod(AssignOp\Mod $node, int $precedence, int $lhsPrecedence): string {
282
+ return $this->pPrefixOp(AssignOp\Mod::class, $this->p($node->var) . ' %= ', $node->expr, $precedence, $lhsPrecedence);
259
283
  }
260
284
 
261
- protected function pExpr_AssignOp_BitwiseAnd(AssignOp\BitwiseAnd $node) {
262
- return $this->pInfixOp(AssignOp\BitwiseAnd::class, $node->var, ' &= ', $node->expr);
285
+ protected function pExpr_AssignOp_BitwiseAnd(AssignOp\BitwiseAnd $node, int $precedence, int $lhsPrecedence): string {
286
+ return $this->pPrefixOp(AssignOp\BitwiseAnd::class, $this->p($node->var) . ' &= ', $node->expr, $precedence, $lhsPrecedence);
263
287
  }
264
288
 
265
- protected function pExpr_AssignOp_BitwiseOr(AssignOp\BitwiseOr $node) {
266
- return $this->pInfixOp(AssignOp\BitwiseOr::class, $node->var, ' |= ', $node->expr);
289
+ protected function pExpr_AssignOp_BitwiseOr(AssignOp\BitwiseOr $node, int $precedence, int $lhsPrecedence): string {
290
+ return $this->pPrefixOp(AssignOp\BitwiseOr::class, $this->p($node->var) . ' |= ', $node->expr, $precedence, $lhsPrecedence);
267
291
  }
268
292
 
269
- protected function pExpr_AssignOp_BitwiseXor(AssignOp\BitwiseXor $node) {
270
- return $this->pInfixOp(AssignOp\BitwiseXor::class, $node->var, ' ^= ', $node->expr);
293
+ protected function pExpr_AssignOp_BitwiseXor(AssignOp\BitwiseXor $node, int $precedence, int $lhsPrecedence): string {
294
+ return $this->pPrefixOp(AssignOp\BitwiseXor::class, $this->p($node->var) . ' ^= ', $node->expr, $precedence, $lhsPrecedence);
271
295
  }
272
296
 
273
- protected function pExpr_AssignOp_ShiftLeft(AssignOp\ShiftLeft $node) {
274
- return $this->pInfixOp(AssignOp\ShiftLeft::class, $node->var, ' <<= ', $node->expr);
297
+ protected function pExpr_AssignOp_ShiftLeft(AssignOp\ShiftLeft $node, int $precedence, int $lhsPrecedence): string {
298
+ return $this->pPrefixOp(AssignOp\ShiftLeft::class, $this->p($node->var) . ' <<= ', $node->expr, $precedence, $lhsPrecedence);
275
299
  }
276
300
 
277
- protected function pExpr_AssignOp_ShiftRight(AssignOp\ShiftRight $node) {
278
- return $this->pInfixOp(AssignOp\ShiftRight::class, $node->var, ' >>= ', $node->expr);
301
+ protected function pExpr_AssignOp_ShiftRight(AssignOp\ShiftRight $node, int $precedence, int $lhsPrecedence): string {
302
+ return $this->pPrefixOp(AssignOp\ShiftRight::class, $this->p($node->var) . ' >>= ', $node->expr, $precedence, $lhsPrecedence);
279
303
  }
280
304
 
281
- protected function pExpr_AssignOp_Pow(AssignOp\Pow $node) {
282
- return $this->pInfixOp(AssignOp\Pow::class, $node->var, ' **= ', $node->expr);
305
+ protected function pExpr_AssignOp_Pow(AssignOp\Pow $node, int $precedence, int $lhsPrecedence): string {
306
+ return $this->pPrefixOp(AssignOp\Pow::class, $this->p($node->var) . ' **= ', $node->expr, $precedence, $lhsPrecedence);
283
307
  }
284
308
 
285
- protected function pExpr_AssignOp_Coalesce(AssignOp\Coalesce $node) {
286
- return $this->pInfixOp(AssignOp\Coalesce::class, $node->var, ' ??= ', $node->expr);
309
+ protected function pExpr_AssignOp_Coalesce(AssignOp\Coalesce $node, int $precedence, int $lhsPrecedence): string {
310
+ return $this->pPrefixOp(AssignOp\Coalesce::class, $this->p($node->var) . ' ??= ', $node->expr, $precedence, $lhsPrecedence);
287
311
  }
288
312
 
289
313
  // Binary expressions
290
314
 
291
- protected function pExpr_BinaryOp_Plus(BinaryOp\Plus $node) {
292
- return $this->pInfixOp(BinaryOp\Plus::class, $node->left, ' + ', $node->right);
315
+ protected function pExpr_BinaryOp_Plus(BinaryOp\Plus $node, int $precedence, int $lhsPrecedence): string {
316
+ return $this->pInfixOp(BinaryOp\Plus::class, $node->left, ' + ', $node->right, $precedence, $lhsPrecedence);
293
317
  }
294
318
 
295
- protected function pExpr_BinaryOp_Minus(BinaryOp\Minus $node) {
296
- return $this->pInfixOp(BinaryOp\Minus::class, $node->left, ' - ', $node->right);
319
+ protected function pExpr_BinaryOp_Minus(BinaryOp\Minus $node, int $precedence, int $lhsPrecedence): string {
320
+ return $this->pInfixOp(BinaryOp\Minus::class, $node->left, ' - ', $node->right, $precedence, $lhsPrecedence);
297
321
  }
298
322
 
299
- protected function pExpr_BinaryOp_Mul(BinaryOp\Mul $node) {
300
- return $this->pInfixOp(BinaryOp\Mul::class, $node->left, ' * ', $node->right);
323
+ protected function pExpr_BinaryOp_Mul(BinaryOp\Mul $node, int $precedence, int $lhsPrecedence): string {
324
+ return $this->pInfixOp(BinaryOp\Mul::class, $node->left, ' * ', $node->right, $precedence, $lhsPrecedence);
301
325
  }
302
326
 
303
- protected function pExpr_BinaryOp_Div(BinaryOp\Div $node) {
304
- return $this->pInfixOp(BinaryOp\Div::class, $node->left, ' / ', $node->right);
327
+ protected function pExpr_BinaryOp_Div(BinaryOp\Div $node, int $precedence, int $lhsPrecedence): string {
328
+ return $this->pInfixOp(BinaryOp\Div::class, $node->left, ' / ', $node->right, $precedence, $lhsPrecedence);
305
329
  }
306
330
 
307
- protected function pExpr_BinaryOp_Concat(BinaryOp\Concat $node) {
308
- return $this->pInfixOp(BinaryOp\Concat::class, $node->left, ' . ', $node->right);
331
+ protected function pExpr_BinaryOp_Concat(BinaryOp\Concat $node, int $precedence, int $lhsPrecedence): string {
332
+ return $this->pInfixOp(BinaryOp\Concat::class, $node->left, ' . ', $node->right, $precedence, $lhsPrecedence);
309
333
  }
310
334
 
311
- protected function pExpr_BinaryOp_Mod(BinaryOp\Mod $node) {
312
- return $this->pInfixOp(BinaryOp\Mod::class, $node->left, ' % ', $node->right);
335
+ protected function pExpr_BinaryOp_Mod(BinaryOp\Mod $node, int $precedence, int $lhsPrecedence): string {
336
+ return $this->pInfixOp(BinaryOp\Mod::class, $node->left, ' % ', $node->right, $precedence, $lhsPrecedence);
313
337
  }
314
338
 
315
- protected function pExpr_BinaryOp_BooleanAnd(BinaryOp\BooleanAnd $node) {
316
- return $this->pInfixOp(BinaryOp\BooleanAnd::class, $node->left, ' && ', $node->right);
339
+ protected function pExpr_BinaryOp_BooleanAnd(BinaryOp\BooleanAnd $node, int $precedence, int $lhsPrecedence): string {
340
+ return $this->pInfixOp(BinaryOp\BooleanAnd::class, $node->left, ' && ', $node->right, $precedence, $lhsPrecedence);
317
341
  }
318
342
 
319
- protected function pExpr_BinaryOp_BooleanOr(BinaryOp\BooleanOr $node) {
320
- return $this->pInfixOp(BinaryOp\BooleanOr::class, $node->left, ' || ', $node->right);
343
+ protected function pExpr_BinaryOp_BooleanOr(BinaryOp\BooleanOr $node, int $precedence, int $lhsPrecedence): string {
344
+ return $this->pInfixOp(BinaryOp\BooleanOr::class, $node->left, ' || ', $node->right, $precedence, $lhsPrecedence);
321
345
  }
322
346
 
323
- protected function pExpr_BinaryOp_BitwiseAnd(BinaryOp\BitwiseAnd $node) {
324
- return $this->pInfixOp(BinaryOp\BitwiseAnd::class, $node->left, ' & ', $node->right);
347
+ protected function pExpr_BinaryOp_BitwiseAnd(BinaryOp\BitwiseAnd $node, int $precedence, int $lhsPrecedence): string {
348
+ return $this->pInfixOp(BinaryOp\BitwiseAnd::class, $node->left, ' & ', $node->right, $precedence, $lhsPrecedence);
325
349
  }
326
350
 
327
- protected function pExpr_BinaryOp_BitwiseOr(BinaryOp\BitwiseOr $node) {
328
- return $this->pInfixOp(BinaryOp\BitwiseOr::class, $node->left, ' | ', $node->right);
351
+ protected function pExpr_BinaryOp_BitwiseOr(BinaryOp\BitwiseOr $node, int $precedence, int $lhsPrecedence): string {
352
+ return $this->pInfixOp(BinaryOp\BitwiseOr::class, $node->left, ' | ', $node->right, $precedence, $lhsPrecedence);
329
353
  }
330
354
 
331
- protected function pExpr_BinaryOp_BitwiseXor(BinaryOp\BitwiseXor $node) {
332
- return $this->pInfixOp(BinaryOp\BitwiseXor::class, $node->left, ' ^ ', $node->right);
355
+ protected function pExpr_BinaryOp_BitwiseXor(BinaryOp\BitwiseXor $node, int $precedence, int $lhsPrecedence): string {
356
+ return $this->pInfixOp(BinaryOp\BitwiseXor::class, $node->left, ' ^ ', $node->right, $precedence, $lhsPrecedence);
333
357
  }
334
358
 
335
- protected function pExpr_BinaryOp_ShiftLeft(BinaryOp\ShiftLeft $node) {
336
- return $this->pInfixOp(BinaryOp\ShiftLeft::class, $node->left, ' << ', $node->right);
359
+ protected function pExpr_BinaryOp_ShiftLeft(BinaryOp\ShiftLeft $node, int $precedence, int $lhsPrecedence): string {
360
+ return $this->pInfixOp(BinaryOp\ShiftLeft::class, $node->left, ' << ', $node->right, $precedence, $lhsPrecedence);
337
361
  }
338
362
 
339
- protected function pExpr_BinaryOp_ShiftRight(BinaryOp\ShiftRight $node) {
340
- return $this->pInfixOp(BinaryOp\ShiftRight::class, $node->left, ' >> ', $node->right);
363
+ protected function pExpr_BinaryOp_ShiftRight(BinaryOp\ShiftRight $node, int $precedence, int $lhsPrecedence): string {
364
+ return $this->pInfixOp(BinaryOp\ShiftRight::class, $node->left, ' >> ', $node->right, $precedence, $lhsPrecedence);
341
365
  }
342
366
 
343
- protected function pExpr_BinaryOp_Pow(BinaryOp\Pow $node) {
344
- return $this->pInfixOp(BinaryOp\Pow::class, $node->left, ' ** ', $node->right);
367
+ protected function pExpr_BinaryOp_Pow(BinaryOp\Pow $node, int $precedence, int $lhsPrecedence): string {
368
+ return $this->pInfixOp(BinaryOp\Pow::class, $node->left, ' ** ', $node->right, $precedence, $lhsPrecedence);
345
369
  }
346
370
 
347
- protected function pExpr_BinaryOp_LogicalAnd(BinaryOp\LogicalAnd $node) {
348
- return $this->pInfixOp(BinaryOp\LogicalAnd::class, $node->left, ' and ', $node->right);
371
+ protected function pExpr_BinaryOp_LogicalAnd(BinaryOp\LogicalAnd $node, int $precedence, int $lhsPrecedence): string {
372
+ return $this->pInfixOp(BinaryOp\LogicalAnd::class, $node->left, ' and ', $node->right, $precedence, $lhsPrecedence);
349
373
  }
350
374
 
351
- protected function pExpr_BinaryOp_LogicalOr(BinaryOp\LogicalOr $node) {
352
- return $this->pInfixOp(BinaryOp\LogicalOr::class, $node->left, ' or ', $node->right);
375
+ protected function pExpr_BinaryOp_LogicalOr(BinaryOp\LogicalOr $node, int $precedence, int $lhsPrecedence): string {
376
+ return $this->pInfixOp(BinaryOp\LogicalOr::class, $node->left, ' or ', $node->right, $precedence, $lhsPrecedence);
353
377
  }
354
378
 
355
- protected function pExpr_BinaryOp_LogicalXor(BinaryOp\LogicalXor $node) {
356
- return $this->pInfixOp(BinaryOp\LogicalXor::class, $node->left, ' xor ', $node->right);
379
+ protected function pExpr_BinaryOp_LogicalXor(BinaryOp\LogicalXor $node, int $precedence, int $lhsPrecedence): string {
380
+ return $this->pInfixOp(BinaryOp\LogicalXor::class, $node->left, ' xor ', $node->right, $precedence, $lhsPrecedence);
357
381
  }
358
382
 
359
- protected function pExpr_BinaryOp_Equal(BinaryOp\Equal $node) {
360
- return $this->pInfixOp(BinaryOp\Equal::class, $node->left, ' == ', $node->right);
383
+ protected function pExpr_BinaryOp_Equal(BinaryOp\Equal $node, int $precedence, int $lhsPrecedence): string {
384
+ return $this->pInfixOp(BinaryOp\Equal::class, $node->left, ' == ', $node->right, $precedence, $lhsPrecedence);
361
385
  }
362
386
 
363
- protected function pExpr_BinaryOp_NotEqual(BinaryOp\NotEqual $node) {
364
- return $this->pInfixOp(BinaryOp\NotEqual::class, $node->left, ' != ', $node->right);
387
+ protected function pExpr_BinaryOp_NotEqual(BinaryOp\NotEqual $node, int $precedence, int $lhsPrecedence): string {
388
+ return $this->pInfixOp(BinaryOp\NotEqual::class, $node->left, ' != ', $node->right, $precedence, $lhsPrecedence);
365
389
  }
366
390
 
367
- protected function pExpr_BinaryOp_Identical(BinaryOp\Identical $node) {
368
- return $this->pInfixOp(BinaryOp\Identical::class, $node->left, ' === ', $node->right);
391
+ protected function pExpr_BinaryOp_Identical(BinaryOp\Identical $node, int $precedence, int $lhsPrecedence): string {
392
+ return $this->pInfixOp(BinaryOp\Identical::class, $node->left, ' === ', $node->right, $precedence, $lhsPrecedence);
369
393
  }
370
394
 
371
- protected function pExpr_BinaryOp_NotIdentical(BinaryOp\NotIdentical $node) {
372
- return $this->pInfixOp(BinaryOp\NotIdentical::class, $node->left, ' !== ', $node->right);
395
+ protected function pExpr_BinaryOp_NotIdentical(BinaryOp\NotIdentical $node, int $precedence, int $lhsPrecedence): string {
396
+ return $this->pInfixOp(BinaryOp\NotIdentical::class, $node->left, ' !== ', $node->right, $precedence, $lhsPrecedence);
373
397
  }
374
398
 
375
- protected function pExpr_BinaryOp_Spaceship(BinaryOp\Spaceship $node) {
376
- return $this->pInfixOp(BinaryOp\Spaceship::class, $node->left, ' <=> ', $node->right);
399
+ protected function pExpr_BinaryOp_Spaceship(BinaryOp\Spaceship $node, int $precedence, int $lhsPrecedence): string {
400
+ return $this->pInfixOp(BinaryOp\Spaceship::class, $node->left, ' <=> ', $node->right, $precedence, $lhsPrecedence);
377
401
  }
378
402
 
379
- protected function pExpr_BinaryOp_Greater(BinaryOp\Greater $node) {
380
- return $this->pInfixOp(BinaryOp\Greater::class, $node->left, ' > ', $node->right);
403
+ protected function pExpr_BinaryOp_Greater(BinaryOp\Greater $node, int $precedence, int $lhsPrecedence): string {
404
+ return $this->pInfixOp(BinaryOp\Greater::class, $node->left, ' > ', $node->right, $precedence, $lhsPrecedence);
381
405
  }
382
406
 
383
- protected function pExpr_BinaryOp_GreaterOrEqual(BinaryOp\GreaterOrEqual $node) {
384
- return $this->pInfixOp(BinaryOp\GreaterOrEqual::class, $node->left, ' >= ', $node->right);
407
+ protected function pExpr_BinaryOp_GreaterOrEqual(BinaryOp\GreaterOrEqual $node, int $precedence, int $lhsPrecedence): string {
408
+ return $this->pInfixOp(BinaryOp\GreaterOrEqual::class, $node->left, ' >= ', $node->right, $precedence, $lhsPrecedence);
385
409
  }
386
410
 
387
- protected function pExpr_BinaryOp_Smaller(BinaryOp\Smaller $node) {
388
- return $this->pInfixOp(BinaryOp\Smaller::class, $node->left, ' < ', $node->right);
411
+ protected function pExpr_BinaryOp_Smaller(BinaryOp\Smaller $node, int $precedence, int $lhsPrecedence): string {
412
+ return $this->pInfixOp(BinaryOp\Smaller::class, $node->left, ' < ', $node->right, $precedence, $lhsPrecedence);
389
413
  }
390
414
 
391
- protected function pExpr_BinaryOp_SmallerOrEqual(BinaryOp\SmallerOrEqual $node) {
392
- return $this->pInfixOp(BinaryOp\SmallerOrEqual::class, $node->left, ' <= ', $node->right);
415
+ protected function pExpr_BinaryOp_SmallerOrEqual(BinaryOp\SmallerOrEqual $node, int $precedence, int $lhsPrecedence): string {
416
+ return $this->pInfixOp(BinaryOp\SmallerOrEqual::class, $node->left, ' <= ', $node->right, $precedence, $lhsPrecedence);
393
417
  }
394
418
 
395
- protected function pExpr_BinaryOp_Coalesce(BinaryOp\Coalesce $node) {
396
- return $this->pInfixOp(BinaryOp\Coalesce::class, $node->left, ' ?? ', $node->right);
419
+ protected function pExpr_BinaryOp_Coalesce(BinaryOp\Coalesce $node, int $precedence, int $lhsPrecedence): string {
420
+ return $this->pInfixOp(BinaryOp\Coalesce::class, $node->left, ' ?? ', $node->right, $precedence, $lhsPrecedence);
397
421
  }
398
422
 
399
- protected function pExpr_Instanceof(Expr\Instanceof_ $node) {
400
- list($precedence, $associativity) = $this->precedenceMap[Expr\Instanceof_::class];
401
- return $this->pPrec($node->expr, $precedence, $associativity, -1)
402
- . ' instanceof '
403
- . $this->pNewVariable($node->class);
423
+ protected function pExpr_Instanceof(Expr\Instanceof_ $node, int $precedence, int $lhsPrecedence): string {
424
+ return $this->pPostfixOp(
425
+ Expr\Instanceof_::class, $node->expr,
426
+ ' instanceof ' . $this->pNewOperand($node->class),
427
+ $precedence, $lhsPrecedence);
404
428
  }
405
429
 
406
430
  // Unary expressions
407
431
 
408
- protected function pExpr_BooleanNot(Expr\BooleanNot $node) {
409
- return $this->pPrefixOp(Expr\BooleanNot::class, '!', $node->expr);
432
+ protected function pExpr_BooleanNot(Expr\BooleanNot $node, int $precedence, int $lhsPrecedence): string {
433
+ return $this->pPrefixOp(Expr\BooleanNot::class, '!', $node->expr, $precedence, $lhsPrecedence);
410
434
  }
411
435
 
412
- protected function pExpr_BitwiseNot(Expr\BitwiseNot $node) {
413
- return $this->pPrefixOp(Expr\BitwiseNot::class, '~', $node->expr);
436
+ protected function pExpr_BitwiseNot(Expr\BitwiseNot $node, int $precedence, int $lhsPrecedence): string {
437
+ return $this->pPrefixOp(Expr\BitwiseNot::class, '~', $node->expr, $precedence, $lhsPrecedence);
414
438
  }
415
439
 
416
- protected function pExpr_UnaryMinus(Expr\UnaryMinus $node) {
417
- if ($node->expr instanceof Expr\UnaryMinus || $node->expr instanceof Expr\PreDec) {
418
- // Enforce -(-$expr) instead of --$expr
419
- return '-(' . $this->p($node->expr) . ')';
420
- }
421
- return $this->pPrefixOp(Expr\UnaryMinus::class, '-', $node->expr);
440
+ protected function pExpr_UnaryMinus(Expr\UnaryMinus $node, int $precedence, int $lhsPrecedence): string {
441
+ return $this->pPrefixOp(Expr\UnaryMinus::class, '-', $node->expr, $precedence, $lhsPrecedence);
422
442
  }
423
443
 
424
- protected function pExpr_UnaryPlus(Expr\UnaryPlus $node) {
425
- if ($node->expr instanceof Expr\UnaryPlus || $node->expr instanceof Expr\PreInc) {
426
- // Enforce +(+$expr) instead of ++$expr
427
- return '+(' . $this->p($node->expr) . ')';
428
- }
429
- return $this->pPrefixOp(Expr\UnaryPlus::class, '+', $node->expr);
444
+ protected function pExpr_UnaryPlus(Expr\UnaryPlus $node, int $precedence, int $lhsPrecedence): string {
445
+ return $this->pPrefixOp(Expr\UnaryPlus::class, '+', $node->expr, $precedence, $lhsPrecedence);
430
446
  }
431
447
 
432
- protected function pExpr_PreInc(Expr\PreInc $node) {
433
- return $this->pPrefixOp(Expr\PreInc::class, '++', $node->var);
448
+ protected function pExpr_PreInc(Expr\PreInc $node): string {
449
+ return '++' . $this->p($node->var);
434
450
  }
435
451
 
436
- protected function pExpr_PreDec(Expr\PreDec $node) {
437
- return $this->pPrefixOp(Expr\PreDec::class, '--', $node->var);
452
+ protected function pExpr_PreDec(Expr\PreDec $node): string {
453
+ return '--' . $this->p($node->var);
438
454
  }
439
455
 
440
- protected function pExpr_PostInc(Expr\PostInc $node) {
441
- return $this->pPostfixOp(Expr\PostInc::class, $node->var, '++');
456
+ protected function pExpr_PostInc(Expr\PostInc $node): string {
457
+ return $this->p($node->var) . '++';
442
458
  }
443
459
 
444
- protected function pExpr_PostDec(Expr\PostDec $node) {
445
- return $this->pPostfixOp(Expr\PostDec::class, $node->var, '--');
460
+ protected function pExpr_PostDec(Expr\PostDec $node): string {
461
+ return $this->p($node->var) . '--';
446
462
  }
447
463
 
448
- protected function pExpr_ErrorSuppress(Expr\ErrorSuppress $node) {
449
- return $this->pPrefixOp(Expr\ErrorSuppress::class, '@', $node->expr);
464
+ protected function pExpr_ErrorSuppress(Expr\ErrorSuppress $node, int $precedence, int $lhsPrecedence): string {
465
+ return $this->pPrefixOp(Expr\ErrorSuppress::class, '@', $node->expr, $precedence, $lhsPrecedence);
450
466
  }
451
467
 
452
- protected function pExpr_YieldFrom(Expr\YieldFrom $node) {
453
- return $this->pPrefixOp(Expr\YieldFrom::class, 'yield from ', $node->expr);
468
+ protected function pExpr_YieldFrom(Expr\YieldFrom $node, int $precedence, int $lhsPrecedence): string {
469
+ return $this->pPrefixOp(Expr\YieldFrom::class, 'yield from ', $node->expr, $precedence, $lhsPrecedence);
454
470
  }
455
471
 
456
- protected function pExpr_Print(Expr\Print_ $node) {
457
- return $this->pPrefixOp(Expr\Print_::class, 'print ', $node->expr);
472
+ protected function pExpr_Print(Expr\Print_ $node, int $precedence, int $lhsPrecedence): string {
473
+ return $this->pPrefixOp(Expr\Print_::class, 'print ', $node->expr, $precedence, $lhsPrecedence);
458
474
  }
459
475
 
460
476
  // Casts
461
477
 
462
- protected function pExpr_Cast_Int(Cast\Int_ $node) {
463
- return $this->pPrefixOp(Cast\Int_::class, '(int) ', $node->expr);
478
+ protected function pExpr_Cast_Int(Cast\Int_ $node, int $precedence, int $lhsPrecedence): string {
479
+ return $this->pPrefixOp(Cast\Int_::class, '(int) ', $node->expr, $precedence, $lhsPrecedence);
464
480
  }
465
481
 
466
- protected function pExpr_Cast_Double(Cast\Double $node) {
482
+ protected function pExpr_Cast_Double(Cast\Double $node, int $precedence, int $lhsPrecedence): string {
467
483
  $kind = $node->getAttribute('kind', Cast\Double::KIND_DOUBLE);
468
484
  if ($kind === Cast\Double::KIND_DOUBLE) {
469
485
  $cast = '(double)';
470
486
  } elseif ($kind === Cast\Double::KIND_FLOAT) {
471
487
  $cast = '(float)';
472
- } elseif ($kind === Cast\Double::KIND_REAL) {
488
+ } else {
489
+ assert($kind === Cast\Double::KIND_REAL);
473
490
  $cast = '(real)';
474
491
  }
475
- return $this->pPrefixOp(Cast\Double::class, $cast . ' ', $node->expr);
492
+ return $this->pPrefixOp(Cast\Double::class, $cast . ' ', $node->expr, $precedence, $lhsPrecedence);
476
493
  }
477
494
 
478
- protected function pExpr_Cast_String(Cast\String_ $node) {
479
- return $this->pPrefixOp(Cast\String_::class, '(string) ', $node->expr);
495
+ protected function pExpr_Cast_String(Cast\String_ $node, int $precedence, int $lhsPrecedence): string {
496
+ return $this->pPrefixOp(Cast\String_::class, '(string) ', $node->expr, $precedence, $lhsPrecedence);
480
497
  }
481
498
 
482
- protected function pExpr_Cast_Array(Cast\Array_ $node) {
483
- return $this->pPrefixOp(Cast\Array_::class, '(array) ', $node->expr);
499
+ protected function pExpr_Cast_Array(Cast\Array_ $node, int $precedence, int $lhsPrecedence): string {
500
+ return $this->pPrefixOp(Cast\Array_::class, '(array) ', $node->expr, $precedence, $lhsPrecedence);
484
501
  }
485
502
 
486
- protected function pExpr_Cast_Object(Cast\Object_ $node) {
487
- return $this->pPrefixOp(Cast\Object_::class, '(object) ', $node->expr);
503
+ protected function pExpr_Cast_Object(Cast\Object_ $node, int $precedence, int $lhsPrecedence): string {
504
+ return $this->pPrefixOp(Cast\Object_::class, '(object) ', $node->expr, $precedence, $lhsPrecedence);
488
505
  }
489
506
 
490
- protected function pExpr_Cast_Bool(Cast\Bool_ $node) {
491
- return $this->pPrefixOp(Cast\Bool_::class, '(bool) ', $node->expr);
507
+ protected function pExpr_Cast_Bool(Cast\Bool_ $node, int $precedence, int $lhsPrecedence): string {
508
+ return $this->pPrefixOp(Cast\Bool_::class, '(bool) ', $node->expr, $precedence, $lhsPrecedence);
492
509
  }
493
510
 
494
- protected function pExpr_Cast_Unset(Cast\Unset_ $node) {
495
- return $this->pPrefixOp(Cast\Unset_::class, '(unset) ', $node->expr);
511
+ protected function pExpr_Cast_Unset(Cast\Unset_ $node, int $precedence, int $lhsPrecedence): string {
512
+ return $this->pPrefixOp(Cast\Unset_::class, '(unset) ', $node->expr, $precedence, $lhsPrecedence);
496
513
  }
497
514
 
498
515
  // Function calls and similar constructs
499
516
 
500
- protected function pExpr_FuncCall(Expr\FuncCall $node) {
517
+ protected function pExpr_FuncCall(Expr\FuncCall $node): string {
501
518
  return $this->pCallLhs($node->name)
502
519
  . '(' . $this->pMaybeMultiline($node->args) . ')';
503
520
  }
504
521
 
505
- protected function pExpr_MethodCall(Expr\MethodCall $node) {
522
+ protected function pExpr_MethodCall(Expr\MethodCall $node): string {
506
523
  return $this->pDereferenceLhs($node->var) . '->' . $this->pObjectProperty($node->name)
507
524
  . '(' . $this->pMaybeMultiline($node->args) . ')';
508
525
  }
509
526
 
510
- protected function pExpr_NullsafeMethodCall(Expr\NullsafeMethodCall $node) {
527
+ protected function pExpr_NullsafeMethodCall(Expr\NullsafeMethodCall $node): string {
511
528
  return $this->pDereferenceLhs($node->var) . '?->' . $this->pObjectProperty($node->name)
512
529
  . '(' . $this->pMaybeMultiline($node->args) . ')';
513
530
  }
514
531
 
515
- protected function pExpr_StaticCall(Expr\StaticCall $node) {
516
- return $this->pDereferenceLhs($node->class) . '::'
532
+ protected function pExpr_StaticCall(Expr\StaticCall $node): string {
533
+ return $this->pStaticDereferenceLhs($node->class) . '::'
517
534
  . ($node->name instanceof Expr
518
535
  ? ($node->name instanceof Expr\Variable
519
536
  ? $this->p($node->name)
@@ -522,19 +539,19 @@ class Standard extends PrettyPrinterAbstract
522
539
  . '(' . $this->pMaybeMultiline($node->args) . ')';
523
540
  }
524
541
 
525
- protected function pExpr_Empty(Expr\Empty_ $node) {
542
+ protected function pExpr_Empty(Expr\Empty_ $node): string {
526
543
  return 'empty(' . $this->p($node->expr) . ')';
527
544
  }
528
545
 
529
- protected function pExpr_Isset(Expr\Isset_ $node) {
546
+ protected function pExpr_Isset(Expr\Isset_ $node): string {
530
547
  return 'isset(' . $this->pCommaSeparated($node->vars) . ')';
531
548
  }
532
549
 
533
- protected function pExpr_Eval(Expr\Eval_ $node) {
550
+ protected function pExpr_Eval(Expr\Eval_ $node): string {
534
551
  return 'eval(' . $this->p($node->expr) . ')';
535
552
  }
536
553
 
537
- protected function pExpr_Include(Expr\Include_ $node) {
554
+ protected function pExpr_Include(Expr\Include_ $node, int $precedence, int $lhsPrecedence): string {
538
555
  static $map = [
539
556
  Expr\Include_::TYPE_INCLUDE => 'include',
540
557
  Expr\Include_::TYPE_INCLUDE_ONCE => 'include_once',
@@ -542,20 +559,26 @@ class Standard extends PrettyPrinterAbstract
542
559
  Expr\Include_::TYPE_REQUIRE_ONCE => 'require_once',
543
560
  ];
544
561
 
545
- return $map[$node->type] . ' ' . $this->p($node->expr);
562
+ return $this->pPrefixOp(Expr\Include_::class, $map[$node->type] . ' ', $node->expr, $precedence, $lhsPrecedence);
546
563
  }
547
564
 
548
- protected function pExpr_List(Expr\List_ $node) {
549
- return 'list(' . $this->pCommaSeparated($node->items) . ')';
565
+ protected function pExpr_List(Expr\List_ $node): string {
566
+ $syntax = $node->getAttribute('kind',
567
+ $this->phpVersion->supportsShortArrayDestructuring() ? Expr\List_::KIND_ARRAY : Expr\List_::KIND_LIST);
568
+ if ($syntax === Expr\List_::KIND_ARRAY) {
569
+ return '[' . $this->pMaybeMultiline($node->items, true) . ']';
570
+ } else {
571
+ return 'list(' . $this->pMaybeMultiline($node->items, true) . ')';
572
+ }
550
573
  }
551
574
 
552
575
  // Other
553
576
 
554
- protected function pExpr_Error(Expr\Error $node) {
577
+ protected function pExpr_Error(Expr\Error $node): string {
555
578
  throw new \LogicException('Cannot pretty-print AST with Error nodes');
556
579
  }
557
580
 
558
- protected function pExpr_Variable(Expr\Variable $node) {
581
+ protected function pExpr_Variable(Expr\Variable $node): string {
559
582
  if ($node->name instanceof Expr) {
560
583
  return '${' . $this->p($node->name) . '}';
561
584
  } else {
@@ -563,9 +586,9 @@ class Standard extends PrettyPrinterAbstract
563
586
  }
564
587
  }
565
588
 
566
- protected function pExpr_Array(Expr\Array_ $node) {
589
+ protected function pExpr_Array(Expr\Array_ $node): string {
567
590
  $syntax = $node->getAttribute('kind',
568
- $this->options['shortArraySyntax'] ? Expr\Array_::KIND_SHORT : Expr\Array_::KIND_LONG);
591
+ $this->shortArraySyntax ? Expr\Array_::KIND_SHORT : Expr\Array_::KIND_LONG);
569
592
  if ($syntax === Expr\Array_::KIND_SHORT) {
570
593
  return '[' . $this->pMaybeMultiline($node->items, true) . ']';
571
594
  } else {
@@ -573,124 +596,152 @@ class Standard extends PrettyPrinterAbstract
573
596
  }
574
597
  }
575
598
 
576
- protected function pExpr_ArrayItem(Expr\ArrayItem $node) {
577
- return (null !== $node->key ? $this->p($node->key) . ' => ' : '')
599
+ protected function pKey(?Node $node): string {
600
+ if ($node === null) {
601
+ return '';
602
+ }
603
+
604
+ // => is not really an operator and does not typically participate in precedence resolution.
605
+ // However, there is an exception if yield expressions with keys are involved:
606
+ // [yield $a => $b] is interpreted as [(yield $a => $b)], so we need to ensure that
607
+ // [(yield $a) => $b] is printed with parentheses. We approximate this by lowering the LHS
608
+ // precedence to that of yield (which will also print unnecessary parentheses for rare low
609
+ // precedence unary operators like include).
610
+ $yieldPrecedence = $this->precedenceMap[Expr\Yield_::class][0];
611
+ return $this->p($node, self::MAX_PRECEDENCE, $yieldPrecedence) . ' => ';
612
+ }
613
+
614
+ protected function pArrayItem(Node\ArrayItem $node): string {
615
+ return $this->pKey($node->key)
578
616
  . ($node->byRef ? '&' : '')
579
617
  . ($node->unpack ? '...' : '')
580
618
  . $this->p($node->value);
581
619
  }
582
620
 
583
- protected function pExpr_ArrayDimFetch(Expr\ArrayDimFetch $node) {
621
+ protected function pExpr_ArrayDimFetch(Expr\ArrayDimFetch $node): string {
584
622
  return $this->pDereferenceLhs($node->var)
585
623
  . '[' . (null !== $node->dim ? $this->p($node->dim) : '') . ']';
586
624
  }
587
625
 
588
- protected function pExpr_ConstFetch(Expr\ConstFetch $node) {
626
+ protected function pExpr_ConstFetch(Expr\ConstFetch $node): string {
589
627
  return $this->p($node->name);
590
628
  }
591
629
 
592
- protected function pExpr_ClassConstFetch(Expr\ClassConstFetch $node) {
593
- return $this->pDereferenceLhs($node->class) . '::' . $this->p($node->name);
630
+ protected function pExpr_ClassConstFetch(Expr\ClassConstFetch $node): string {
631
+ return $this->pStaticDereferenceLhs($node->class) . '::' . $this->pObjectProperty($node->name);
594
632
  }
595
633
 
596
- protected function pExpr_PropertyFetch(Expr\PropertyFetch $node) {
634
+ protected function pExpr_PropertyFetch(Expr\PropertyFetch $node): string {
597
635
  return $this->pDereferenceLhs($node->var) . '->' . $this->pObjectProperty($node->name);
598
636
  }
599
637
 
600
- protected function pExpr_NullsafePropertyFetch(Expr\NullsafePropertyFetch $node) {
638
+ protected function pExpr_NullsafePropertyFetch(Expr\NullsafePropertyFetch $node): string {
601
639
  return $this->pDereferenceLhs($node->var) . '?->' . $this->pObjectProperty($node->name);
602
640
  }
603
641
 
604
- protected function pExpr_StaticPropertyFetch(Expr\StaticPropertyFetch $node) {
605
- return $this->pDereferenceLhs($node->class) . '::$' . $this->pObjectProperty($node->name);
642
+ protected function pExpr_StaticPropertyFetch(Expr\StaticPropertyFetch $node): string {
643
+ return $this->pStaticDereferenceLhs($node->class) . '::$' . $this->pObjectProperty($node->name);
606
644
  }
607
645
 
608
- protected function pExpr_ShellExec(Expr\ShellExec $node) {
646
+ protected function pExpr_ShellExec(Expr\ShellExec $node): string {
609
647
  return '`' . $this->pEncapsList($node->parts, '`') . '`';
610
648
  }
611
649
 
612
- protected function pExpr_Closure(Expr\Closure $node) {
650
+ protected function pExpr_Closure(Expr\Closure $node): string {
613
651
  return $this->pAttrGroups($node->attrGroups, true)
614
- . ($node->static ? 'static ' : '')
652
+ . $this->pStatic($node->static)
615
653
  . 'function ' . ($node->byRef ? '&' : '')
616
- . '(' . $this->pCommaSeparated($node->params) . ')'
617
- . (!empty($node->uses) ? ' use(' . $this->pCommaSeparated($node->uses) . ')' : '')
618
- . (null !== $node->returnType ? ' : ' . $this->p($node->returnType) : '')
654
+ . '(' . $this->pMaybeMultiline($node->params, $this->phpVersion->supportsTrailingCommaInParamList()) . ')'
655
+ . (!empty($node->uses) ? ' use (' . $this->pCommaSeparated($node->uses) . ')' : '')
656
+ . (null !== $node->returnType ? ': ' . $this->p($node->returnType) : '')
619
657
  . ' {' . $this->pStmts($node->stmts) . $this->nl . '}';
620
658
  }
621
659
 
622
- protected function pExpr_Match(Expr\Match_ $node) {
660
+ protected function pExpr_Match(Expr\Match_ $node): string {
623
661
  return 'match (' . $this->p($node->cond) . ') {'
624
662
  . $this->pCommaSeparatedMultiline($node->arms, true)
625
663
  . $this->nl
626
664
  . '}';
627
665
  }
628
666
 
629
- protected function pMatchArm(Node\MatchArm $node) {
630
- return ($node->conds ? $this->pCommaSeparated($node->conds) : 'default')
631
- . ' => ' . $this->p($node->body);
667
+ protected function pMatchArm(Node\MatchArm $node): string {
668
+ $result = '';
669
+ if ($node->conds) {
670
+ for ($i = 0, $c = \count($node->conds); $i + 1 < $c; $i++) {
671
+ $result .= $this->p($node->conds[$i]) . ', ';
672
+ }
673
+ $result .= $this->pKey($node->conds[$i]);
674
+ } else {
675
+ $result = 'default => ';
676
+ }
677
+ return $result . $this->p($node->body);
632
678
  }
633
679
 
634
- protected function pExpr_ArrowFunction(Expr\ArrowFunction $node) {
635
- return $this->pAttrGroups($node->attrGroups, true)
636
- . ($node->static ? 'static ' : '')
680
+ protected function pExpr_ArrowFunction(Expr\ArrowFunction $node, int $precedence, int $lhsPrecedence): string {
681
+ return $this->pPrefixOp(
682
+ Expr\ArrowFunction::class,
683
+ $this->pAttrGroups($node->attrGroups, true)
684
+ . $this->pStatic($node->static)
637
685
  . 'fn' . ($node->byRef ? '&' : '')
638
- . '(' . $this->pCommaSeparated($node->params) . ')'
686
+ . '(' . $this->pMaybeMultiline($node->params, $this->phpVersion->supportsTrailingCommaInParamList()) . ')'
639
687
  . (null !== $node->returnType ? ': ' . $this->p($node->returnType) : '')
640
- . ' => '
641
- . $this->p($node->expr);
688
+ . ' => ',
689
+ $node->expr, $precedence, $lhsPrecedence);
642
690
  }
643
691
 
644
- protected function pExpr_ClosureUse(Expr\ClosureUse $node) {
692
+ protected function pClosureUse(Node\ClosureUse $node): string {
645
693
  return ($node->byRef ? '&' : '') . $this->p($node->var);
646
694
  }
647
695
 
648
- protected function pExpr_New(Expr\New_ $node) {
696
+ protected function pExpr_New(Expr\New_ $node): string {
649
697
  if ($node->class instanceof Stmt\Class_) {
650
698
  $args = $node->args ? '(' . $this->pMaybeMultiline($node->args) . ')' : '';
651
699
  return 'new ' . $this->pClassCommon($node->class, $args);
652
700
  }
653
- return 'new ' . $this->pNewVariable($node->class)
701
+ return 'new ' . $this->pNewOperand($node->class)
654
702
  . '(' . $this->pMaybeMultiline($node->args) . ')';
655
703
  }
656
704
 
657
- protected function pExpr_Clone(Expr\Clone_ $node) {
658
- return 'clone ' . $this->p($node->expr);
705
+ protected function pExpr_Clone(Expr\Clone_ $node, int $precedence, int $lhsPrecedence): string {
706
+ return $this->pPrefixOp(Expr\Clone_::class, 'clone ', $node->expr, $precedence, $lhsPrecedence);
659
707
  }
660
708
 
661
- protected function pExpr_Ternary(Expr\Ternary $node) {
709
+ protected function pExpr_Ternary(Expr\Ternary $node, int $precedence, int $lhsPrecedence): string {
662
710
  // a bit of cheating: we treat the ternary as a binary op where the ?...: part is the operator.
663
711
  // this is okay because the part between ? and : never needs parentheses.
664
712
  return $this->pInfixOp(Expr\Ternary::class,
665
- $node->cond, ' ?' . (null !== $node->if ? ' ' . $this->p($node->if) . ' ' : '') . ': ', $node->else
713
+ $node->cond, ' ?' . (null !== $node->if ? ' ' . $this->p($node->if) . ' ' : '') . ': ', $node->else,
714
+ $precedence, $lhsPrecedence
666
715
  );
667
716
  }
668
717
 
669
- protected function pExpr_Exit(Expr\Exit_ $node) {
718
+ protected function pExpr_Exit(Expr\Exit_ $node): string {
670
719
  $kind = $node->getAttribute('kind', Expr\Exit_::KIND_DIE);
671
720
  return ($kind === Expr\Exit_::KIND_EXIT ? 'exit' : 'die')
672
721
  . (null !== $node->expr ? '(' . $this->p($node->expr) . ')' : '');
673
722
  }
674
723
 
675
- protected function pExpr_Throw(Expr\Throw_ $node) {
676
- return 'throw ' . $this->p($node->expr);
724
+ protected function pExpr_Throw(Expr\Throw_ $node, int $precedence, int $lhsPrecedence): string {
725
+ return $this->pPrefixOp(Expr\Throw_::class, 'throw ', $node->expr, $precedence, $lhsPrecedence);
677
726
  }
678
727
 
679
- protected function pExpr_Yield(Expr\Yield_ $node) {
728
+ protected function pExpr_Yield(Expr\Yield_ $node, int $precedence, int $lhsPrecedence): string {
680
729
  if ($node->value === null) {
681
- return 'yield';
730
+ $opPrecedence = $this->precedenceMap[Expr\Yield_::class][0];
731
+ return $opPrecedence >= $lhsPrecedence ? '(yield)' : 'yield';
682
732
  } else {
683
- // this is a bit ugly, but currently there is no way to detect whether the parentheses are necessary
684
- return '(yield '
685
- . ($node->key !== null ? $this->p($node->key) . ' => ' : '')
686
- . $this->p($node->value)
687
- . ')';
733
+ if (!$this->phpVersion->supportsYieldWithoutParentheses()) {
734
+ return '(yield ' . $this->pKey($node->key) . $this->p($node->value) . ')';
735
+ }
736
+ return $this->pPrefixOp(
737
+ Expr\Yield_::class, 'yield ' . $this->pKey($node->key),
738
+ $node->value, $precedence, $lhsPrecedence);
688
739
  }
689
740
  }
690
741
 
691
742
  // Declarations
692
743
 
693
- protected function pStmt_Namespace(Stmt\Namespace_ $node) {
744
+ protected function pStmt_Namespace(Stmt\Namespace_ $node): string {
694
745
  if ($this->canUseSemicolonNamespaces) {
695
746
  return 'namespace ' . $this->p($node->name) . ';'
696
747
  . $this->nl . $this->pStmts($node->stmts, false);
@@ -700,146 +751,153 @@ class Standard extends PrettyPrinterAbstract
700
751
  }
701
752
  }
702
753
 
703
- protected function pStmt_Use(Stmt\Use_ $node) {
754
+ protected function pStmt_Use(Stmt\Use_ $node): string {
704
755
  return 'use ' . $this->pUseType($node->type)
705
756
  . $this->pCommaSeparated($node->uses) . ';';
706
757
  }
707
758
 
708
- protected function pStmt_GroupUse(Stmt\GroupUse $node) {
759
+ protected function pStmt_GroupUse(Stmt\GroupUse $node): string {
709
760
  return 'use ' . $this->pUseType($node->type) . $this->pName($node->prefix)
710
761
  . '\{' . $this->pCommaSeparated($node->uses) . '};';
711
762
  }
712
763
 
713
- protected function pStmt_UseUse(Stmt\UseUse $node) {
764
+ protected function pUseItem(Node\UseItem $node): string {
714
765
  return $this->pUseType($node->type) . $this->p($node->name)
715
766
  . (null !== $node->alias ? ' as ' . $node->alias : '');
716
767
  }
717
768
 
718
- protected function pUseType($type) {
769
+ protected function pUseType(int $type): string {
719
770
  return $type === Stmt\Use_::TYPE_FUNCTION ? 'function '
720
771
  : ($type === Stmt\Use_::TYPE_CONSTANT ? 'const ' : '');
721
772
  }
722
773
 
723
- protected function pStmt_Interface(Stmt\Interface_ $node) {
774
+ protected function pStmt_Interface(Stmt\Interface_ $node): string {
724
775
  return $this->pAttrGroups($node->attrGroups)
725
776
  . 'interface ' . $node->name
726
777
  . (!empty($node->extends) ? ' extends ' . $this->pCommaSeparated($node->extends) : '')
727
778
  . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}';
728
779
  }
729
780
 
730
- protected function pStmt_Enum(Stmt\Enum_ $node) {
781
+ protected function pStmt_Enum(Stmt\Enum_ $node): string {
731
782
  return $this->pAttrGroups($node->attrGroups)
732
783
  . 'enum ' . $node->name
784
+ . ($node->scalarType ? ' : ' . $this->p($node->scalarType) : '')
733
785
  . (!empty($node->implements) ? ' implements ' . $this->pCommaSeparated($node->implements) : '')
734
786
  . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}';
735
787
  }
736
788
 
737
- protected function pStmt_Class(Stmt\Class_ $node) {
789
+ protected function pStmt_Class(Stmt\Class_ $node): string {
738
790
  return $this->pClassCommon($node, ' ' . $node->name);
739
791
  }
740
792
 
741
- protected function pStmt_Trait(Stmt\Trait_ $node) {
793
+ protected function pStmt_Trait(Stmt\Trait_ $node): string {
742
794
  return $this->pAttrGroups($node->attrGroups)
743
795
  . 'trait ' . $node->name
744
796
  . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}';
745
797
  }
746
798
 
747
- protected function pStmt_EnumCase(Stmt\EnumCase $node) {
799
+ protected function pStmt_EnumCase(Stmt\EnumCase $node): string {
748
800
  return $this->pAttrGroups($node->attrGroups)
749
801
  . 'case ' . $node->name
750
802
  . ($node->expr ? ' = ' . $this->p($node->expr) : '')
751
803
  . ';';
752
804
  }
753
805
 
754
- protected function pStmt_TraitUse(Stmt\TraitUse $node) {
806
+ protected function pStmt_TraitUse(Stmt\TraitUse $node): string {
755
807
  return 'use ' . $this->pCommaSeparated($node->traits)
756
808
  . (empty($node->adaptations)
757
809
  ? ';'
758
810
  : ' {' . $this->pStmts($node->adaptations) . $this->nl . '}');
759
811
  }
760
812
 
761
- protected function pStmt_TraitUseAdaptation_Precedence(Stmt\TraitUseAdaptation\Precedence $node) {
813
+ protected function pStmt_TraitUseAdaptation_Precedence(Stmt\TraitUseAdaptation\Precedence $node): string {
762
814
  return $this->p($node->trait) . '::' . $node->method
763
815
  . ' insteadof ' . $this->pCommaSeparated($node->insteadof) . ';';
764
816
  }
765
817
 
766
- protected function pStmt_TraitUseAdaptation_Alias(Stmt\TraitUseAdaptation\Alias $node) {
818
+ protected function pStmt_TraitUseAdaptation_Alias(Stmt\TraitUseAdaptation\Alias $node): string {
767
819
  return (null !== $node->trait ? $this->p($node->trait) . '::' : '')
768
820
  . $node->method . ' as'
769
821
  . (null !== $node->newModifier ? ' ' . rtrim($this->pModifiers($node->newModifier), ' ') : '')
770
- . (null !== $node->newName ? ' ' . $node->newName : '')
822
+ . (null !== $node->newName ? ' ' . $node->newName : '')
771
823
  . ';';
772
824
  }
773
825
 
774
- protected function pStmt_Property(Stmt\Property $node) {
826
+ protected function pStmt_Property(Stmt\Property $node): string {
775
827
  return $this->pAttrGroups($node->attrGroups)
776
828
  . (0 === $node->flags ? 'var ' : $this->pModifiers($node->flags))
777
829
  . ($node->type ? $this->p($node->type) . ' ' : '')
778
830
  . $this->pCommaSeparated($node->props) . ';';
779
831
  }
780
832
 
781
- protected function pStmt_PropertyProperty(Stmt\PropertyProperty $node) {
833
+ protected function pPropertyItem(Node\PropertyItem $node): string {
782
834
  return '$' . $node->name
783
835
  . (null !== $node->default ? ' = ' . $this->p($node->default) : '');
784
836
  }
785
837
 
786
- protected function pStmt_ClassMethod(Stmt\ClassMethod $node) {
838
+ protected function pStmt_ClassMethod(Stmt\ClassMethod $node): string {
787
839
  return $this->pAttrGroups($node->attrGroups)
788
840
  . $this->pModifiers($node->flags)
789
841
  . 'function ' . ($node->byRef ? '&' : '') . $node->name
790
- . '(' . $this->pMaybeMultiline($node->params) . ')'
791
- . (null !== $node->returnType ? ' : ' . $this->p($node->returnType) : '')
842
+ . '(' . $this->pMaybeMultiline($node->params, $this->phpVersion->supportsTrailingCommaInParamList()) . ')'
843
+ . (null !== $node->returnType ? ': ' . $this->p($node->returnType) : '')
792
844
  . (null !== $node->stmts
793
845
  ? $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}'
794
846
  : ';');
795
847
  }
796
848
 
797
- protected function pStmt_ClassConst(Stmt\ClassConst $node) {
849
+ protected function pStmt_ClassConst(Stmt\ClassConst $node): string {
798
850
  return $this->pAttrGroups($node->attrGroups)
799
851
  . $this->pModifiers($node->flags)
800
- . 'const ' . $this->pCommaSeparated($node->consts) . ';';
852
+ . 'const '
853
+ . (null !== $node->type ? $this->p($node->type) . ' ' : '')
854
+ . $this->pCommaSeparated($node->consts) . ';';
801
855
  }
802
856
 
803
- protected function pStmt_Function(Stmt\Function_ $node) {
857
+ protected function pStmt_Function(Stmt\Function_ $node): string {
804
858
  return $this->pAttrGroups($node->attrGroups)
805
859
  . 'function ' . ($node->byRef ? '&' : '') . $node->name
806
- . '(' . $this->pCommaSeparated($node->params) . ')'
807
- . (null !== $node->returnType ? ' : ' . $this->p($node->returnType) : '')
860
+ . '(' . $this->pMaybeMultiline($node->params, $this->phpVersion->supportsTrailingCommaInParamList()) . ')'
861
+ . (null !== $node->returnType ? ': ' . $this->p($node->returnType) : '')
808
862
  . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}';
809
863
  }
810
864
 
811
- protected function pStmt_Const(Stmt\Const_ $node) {
865
+ protected function pStmt_Const(Stmt\Const_ $node): string {
812
866
  return 'const ' . $this->pCommaSeparated($node->consts) . ';';
813
867
  }
814
868
 
815
- protected function pStmt_Declare(Stmt\Declare_ $node) {
869
+ protected function pStmt_Declare(Stmt\Declare_ $node): string {
816
870
  return 'declare (' . $this->pCommaSeparated($node->declares) . ')'
817
871
  . (null !== $node->stmts ? ' {' . $this->pStmts($node->stmts) . $this->nl . '}' : ';');
818
872
  }
819
873
 
820
- protected function pStmt_DeclareDeclare(Stmt\DeclareDeclare $node) {
874
+ protected function pDeclareItem(Node\DeclareItem $node): string {
821
875
  return $node->key . '=' . $this->p($node->value);
822
876
  }
823
877
 
824
878
  // Control flow
825
879
 
826
- protected function pStmt_If(Stmt\If_ $node) {
880
+ protected function pStmt_If(Stmt\If_ $node): string {
827
881
  return 'if (' . $this->p($node->cond) . ') {'
828
882
  . $this->pStmts($node->stmts) . $this->nl . '}'
829
883
  . ($node->elseifs ? ' ' . $this->pImplode($node->elseifs, ' ') : '')
830
884
  . (null !== $node->else ? ' ' . $this->p($node->else) : '');
831
885
  }
832
886
 
833
- protected function pStmt_ElseIf(Stmt\ElseIf_ $node) {
887
+ protected function pStmt_ElseIf(Stmt\ElseIf_ $node): string {
834
888
  return 'elseif (' . $this->p($node->cond) . ') {'
835
889
  . $this->pStmts($node->stmts) . $this->nl . '}';
836
890
  }
837
891
 
838
- protected function pStmt_Else(Stmt\Else_ $node) {
892
+ protected function pStmt_Else(Stmt\Else_ $node): string {
893
+ if (\count($node->stmts) === 1 && $node->stmts[0] instanceof Stmt\If_) {
894
+ // Print as "else if" rather than "else { if }"
895
+ return 'else ' . $this->p($node->stmts[0]);
896
+ }
839
897
  return 'else {' . $this->pStmts($node->stmts) . $this->nl . '}';
840
898
  }
841
899
 
842
- protected function pStmt_For(Stmt\For_ $node) {
900
+ protected function pStmt_For(Stmt\For_ $node): string {
843
901
  return 'for ('
844
902
  . $this->pCommaSeparated($node->init) . ';' . (!empty($node->cond) ? ' ' : '')
845
903
  . $this->pCommaSeparated($node->cond) . ';' . (!empty($node->loop) ? ' ' : '')
@@ -847,116 +905,116 @@ class Standard extends PrettyPrinterAbstract
847
905
  . ') {' . $this->pStmts($node->stmts) . $this->nl . '}';
848
906
  }
849
907
 
850
- protected function pStmt_Foreach(Stmt\Foreach_ $node) {
908
+ protected function pStmt_Foreach(Stmt\Foreach_ $node): string {
851
909
  return 'foreach (' . $this->p($node->expr) . ' as '
852
910
  . (null !== $node->keyVar ? $this->p($node->keyVar) . ' => ' : '')
853
911
  . ($node->byRef ? '&' : '') . $this->p($node->valueVar) . ') {'
854
912
  . $this->pStmts($node->stmts) . $this->nl . '}';
855
913
  }
856
914
 
857
- protected function pStmt_While(Stmt\While_ $node) {
915
+ protected function pStmt_While(Stmt\While_ $node): string {
858
916
  return 'while (' . $this->p($node->cond) . ') {'
859
917
  . $this->pStmts($node->stmts) . $this->nl . '}';
860
918
  }
861
919
 
862
- protected function pStmt_Do(Stmt\Do_ $node) {
920
+ protected function pStmt_Do(Stmt\Do_ $node): string {
863
921
  return 'do {' . $this->pStmts($node->stmts) . $this->nl
864
922
  . '} while (' . $this->p($node->cond) . ');';
865
923
  }
866
924
 
867
- protected function pStmt_Switch(Stmt\Switch_ $node) {
925
+ protected function pStmt_Switch(Stmt\Switch_ $node): string {
868
926
  return 'switch (' . $this->p($node->cond) . ') {'
869
927
  . $this->pStmts($node->cases) . $this->nl . '}';
870
928
  }
871
929
 
872
- protected function pStmt_Case(Stmt\Case_ $node) {
930
+ protected function pStmt_Case(Stmt\Case_ $node): string {
873
931
  return (null !== $node->cond ? 'case ' . $this->p($node->cond) : 'default') . ':'
874
932
  . $this->pStmts($node->stmts);
875
933
  }
876
934
 
877
- protected function pStmt_TryCatch(Stmt\TryCatch $node) {
935
+ protected function pStmt_TryCatch(Stmt\TryCatch $node): string {
878
936
  return 'try {' . $this->pStmts($node->stmts) . $this->nl . '}'
879
937
  . ($node->catches ? ' ' . $this->pImplode($node->catches, ' ') : '')
880
938
  . ($node->finally !== null ? ' ' . $this->p($node->finally) : '');
881
939
  }
882
940
 
883
- protected function pStmt_Catch(Stmt\Catch_ $node) {
941
+ protected function pStmt_Catch(Stmt\Catch_ $node): string {
884
942
  return 'catch (' . $this->pImplode($node->types, '|')
885
943
  . ($node->var !== null ? ' ' . $this->p($node->var) : '')
886
944
  . ') {' . $this->pStmts($node->stmts) . $this->nl . '}';
887
945
  }
888
946
 
889
- protected function pStmt_Finally(Stmt\Finally_ $node) {
947
+ protected function pStmt_Finally(Stmt\Finally_ $node): string {
890
948
  return 'finally {' . $this->pStmts($node->stmts) . $this->nl . '}';
891
949
  }
892
950
 
893
- protected function pStmt_Break(Stmt\Break_ $node) {
951
+ protected function pStmt_Break(Stmt\Break_ $node): string {
894
952
  return 'break' . ($node->num !== null ? ' ' . $this->p($node->num) : '') . ';';
895
953
  }
896
954
 
897
- protected function pStmt_Continue(Stmt\Continue_ $node) {
955
+ protected function pStmt_Continue(Stmt\Continue_ $node): string {
898
956
  return 'continue' . ($node->num !== null ? ' ' . $this->p($node->num) : '') . ';';
899
957
  }
900
958
 
901
- protected function pStmt_Return(Stmt\Return_ $node) {
959
+ protected function pStmt_Return(Stmt\Return_ $node): string {
902
960
  return 'return' . (null !== $node->expr ? ' ' . $this->p($node->expr) : '') . ';';
903
961
  }
904
962
 
905
- protected function pStmt_Throw(Stmt\Throw_ $node) {
906
- return 'throw ' . $this->p($node->expr) . ';';
907
- }
908
-
909
- protected function pStmt_Label(Stmt\Label $node) {
963
+ protected function pStmt_Label(Stmt\Label $node): string {
910
964
  return $node->name . ':';
911
965
  }
912
966
 
913
- protected function pStmt_Goto(Stmt\Goto_ $node) {
967
+ protected function pStmt_Goto(Stmt\Goto_ $node): string {
914
968
  return 'goto ' . $node->name . ';';
915
969
  }
916
970
 
917
971
  // Other
918
972
 
919
- protected function pStmt_Expression(Stmt\Expression $node) {
973
+ protected function pStmt_Expression(Stmt\Expression $node): string {
920
974
  return $this->p($node->expr) . ';';
921
975
  }
922
976
 
923
- protected function pStmt_Echo(Stmt\Echo_ $node) {
977
+ protected function pStmt_Echo(Stmt\Echo_ $node): string {
924
978
  return 'echo ' . $this->pCommaSeparated($node->exprs) . ';';
925
979
  }
926
980
 
927
- protected function pStmt_Static(Stmt\Static_ $node) {
981
+ protected function pStmt_Static(Stmt\Static_ $node): string {
928
982
  return 'static ' . $this->pCommaSeparated($node->vars) . ';';
929
983
  }
930
984
 
931
- protected function pStmt_Global(Stmt\Global_ $node) {
985
+ protected function pStmt_Global(Stmt\Global_ $node): string {
932
986
  return 'global ' . $this->pCommaSeparated($node->vars) . ';';
933
987
  }
934
988
 
935
- protected function pStmt_StaticVar(Stmt\StaticVar $node) {
989
+ protected function pStaticVar(Node\StaticVar $node): string {
936
990
  return $this->p($node->var)
937
991
  . (null !== $node->default ? ' = ' . $this->p($node->default) : '');
938
992
  }
939
993
 
940
- protected function pStmt_Unset(Stmt\Unset_ $node) {
994
+ protected function pStmt_Unset(Stmt\Unset_ $node): string {
941
995
  return 'unset(' . $this->pCommaSeparated($node->vars) . ');';
942
996
  }
943
997
 
944
- protected function pStmt_InlineHTML(Stmt\InlineHTML $node) {
945
- $newline = $node->getAttribute('hasLeadingNewline', true) ? "\n" : '';
998
+ protected function pStmt_InlineHTML(Stmt\InlineHTML $node): string {
999
+ $newline = $node->getAttribute('hasLeadingNewline', true) ? $this->newline : '';
946
1000
  return '?>' . $newline . $node->value . '<?php ';
947
1001
  }
948
1002
 
949
- protected function pStmt_HaltCompiler(Stmt\HaltCompiler $node) {
1003
+ protected function pStmt_HaltCompiler(Stmt\HaltCompiler $node): string {
950
1004
  return '__halt_compiler();' . $node->remaining;
951
1005
  }
952
1006
 
953
- protected function pStmt_Nop(Stmt\Nop $node) {
1007
+ protected function pStmt_Nop(Stmt\Nop $node): string {
954
1008
  return '';
955
1009
  }
956
1010
 
1011
+ protected function pStmt_Block(Stmt\Block $node): string {
1012
+ return '{' . $this->pStmts($node->stmts) . $this->nl . '}';
1013
+ }
1014
+
957
1015
  // Helpers
958
1016
 
959
- protected function pClassCommon(Stmt\Class_ $node, $afterClassToken) {
1017
+ protected function pClassCommon(Stmt\Class_ $node, string $afterClassToken): string {
960
1018
  return $this->pAttrGroups($node->attrGroups, $node->name === null)
961
1019
  . $this->pModifiers($node->flags)
962
1020
  . 'class' . $afterClassToken
@@ -965,18 +1023,20 @@ class Standard extends PrettyPrinterAbstract
965
1023
  . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}';
966
1024
  }
967
1025
 
968
- protected function pObjectProperty($node) {
1026
+ protected function pObjectProperty(Node $node): string {
969
1027
  if ($node instanceof Expr) {
970
1028
  return '{' . $this->p($node) . '}';
971
1029
  } else {
972
- return $node;
1030
+ assert($node instanceof Node\Identifier);
1031
+ return $node->name;
973
1032
  }
974
1033
  }
975
1034
 
976
- protected function pEncapsList(array $encapsList, $quote) {
1035
+ /** @param (Expr|Node\InterpolatedStringPart)[] $encapsList */
1036
+ protected function pEncapsList(array $encapsList, ?string $quote): string {
977
1037
  $return = '';
978
1038
  foreach ($encapsList as $element) {
979
- if ($element instanceof Scalar\EncapsedStringPart) {
1039
+ if ($element instanceof Node\InterpolatedStringPart) {
980
1040
  $return .= $this->escapeString($element->value, $quote);
981
1041
  } else {
982
1042
  $return .= '{' . $this->p($element) . '}';
@@ -986,14 +1046,25 @@ class Standard extends PrettyPrinterAbstract
986
1046
  return $return;
987
1047
  }
988
1048
 
989
- protected function pSingleQuotedString(string $string) {
990
- return '\'' . addcslashes($string, '\'\\') . '\'';
1049
+ protected function pSingleQuotedString(string $string): string {
1050
+ // It is idiomatic to only escape backslashes when necessary, i.e. when followed by ', \ or
1051
+ // the end of the string ('Foo\Bar' instead of 'Foo\\Bar'). However, we also don't want to
1052
+ // produce an odd number of backslashes, so '\\\\a' should not get rendered as '\\\a', even
1053
+ // though that would be legal.
1054
+ $regex = '/\'|\\\\(?=[\'\\\\]|$)|(?<=\\\\)\\\\/';
1055
+ return '\'' . preg_replace($regex, '\\\\$0', $string) . '\'';
991
1056
  }
992
1057
 
993
- protected function escapeString($string, $quote) {
1058
+ protected function escapeString(string $string, ?string $quote): string {
994
1059
  if (null === $quote) {
995
1060
  // For doc strings, don't escape newlines
996
1061
  $escaped = addcslashes($string, "\t\f\v$\\");
1062
+ // But do escape isolated \r. Combined with the terminating newline, it might get
1063
+ // interpreted as \r\n and dropped from the string contents.
1064
+ $escaped = preg_replace('/\r(?!\n)/', '\\r', $escaped);
1065
+ if ($this->phpVersion->supportsFlexibleHeredoc()) {
1066
+ $escaped = $this->indentString($escaped);
1067
+ }
997
1068
  } else {
998
1069
  $escaped = addcslashes($string, "\n\r\t\f\v$" . $quote . "\\");
999
1070
  }
@@ -1015,26 +1086,24 @@ class Standard extends PrettyPrinterAbstract
1015
1086
  | (?<=[\xF0-\xF4])[\x80-\xBF](?![\x80-\xBF]{2}) # Short 4 byte sequence
1016
1087
  | (?<=[\xF0-\xF4][\x80-\xBF])[\x80-\xBF](?![\x80-\xBF]) # Short 4 byte sequence (2)
1017
1088
  )/x';
1018
- return preg_replace_callback($regex, function ($matches) {
1089
+ return preg_replace_callback($regex, function ($matches): string {
1019
1090
  assert(strlen($matches[0]) === 1);
1020
- $hex = dechex(ord($matches[0]));;
1091
+ $hex = dechex(ord($matches[0]));
1021
1092
  return '\\x' . str_pad($hex, 2, '0', \STR_PAD_LEFT);
1022
1093
  }, $escaped);
1023
1094
  }
1024
1095
 
1025
- protected function containsEndLabel($string, $label, $atStart = true, $atEnd = true) {
1026
- $start = $atStart ? '(?:^|[\r\n])' : '[\r\n]';
1027
- $end = $atEnd ? '(?:$|[;\r\n])' : '[;\r\n]';
1096
+ protected function containsEndLabel(string $string, string $label, bool $atStart = true): bool {
1097
+ $start = $atStart ? '(?:^|[\r\n])[ \t]*' : '[\r\n][ \t]*';
1028
1098
  return false !== strpos($string, $label)
1029
- && preg_match('/' . $start . $label . $end . '/', $string);
1099
+ && preg_match('/' . $start . $label . '(?:$|[^_A-Za-z0-9\x80-\xff])/', $string);
1030
1100
  }
1031
1101
 
1032
- protected function encapsedContainsEndLabel(array $parts, $label) {
1102
+ /** @param (Expr|Node\InterpolatedStringPart)[] $parts */
1103
+ protected function encapsedContainsEndLabel(array $parts, string $label): bool {
1033
1104
  foreach ($parts as $i => $part) {
1034
- $atStart = $i === 0;
1035
- $atEnd = $i === count($parts) - 1;
1036
- if ($part instanceof Scalar\EncapsedStringPart
1037
- && $this->containsEndLabel($part->value, $label, $atStart, $atEnd)
1105
+ if ($part instanceof Node\InterpolatedStringPart
1106
+ && $this->containsEndLabel($this->escapeString($part->value, null), $label, $i === 0)
1038
1107
  ) {
1039
1108
  return true;
1040
1109
  }
@@ -1042,32 +1111,42 @@ class Standard extends PrettyPrinterAbstract
1042
1111
  return false;
1043
1112
  }
1044
1113
 
1045
- protected function pDereferenceLhs(Node $node) {
1114
+ protected function pDereferenceLhs(Node $node): string {
1046
1115
  if (!$this->dereferenceLhsRequiresParens($node)) {
1047
1116
  return $this->p($node);
1048
- } else {
1117
+ } else {
1118
+ return '(' . $this->p($node) . ')';
1119
+ }
1120
+ }
1121
+
1122
+ protected function pStaticDereferenceLhs(Node $node): string {
1123
+ if (!$this->staticDereferenceLhsRequiresParens($node)) {
1124
+ return $this->p($node);
1125
+ } else {
1049
1126
  return '(' . $this->p($node) . ')';
1050
1127
  }
1051
1128
  }
1052
1129
 
1053
- protected function pCallLhs(Node $node) {
1130
+ protected function pCallLhs(Node $node): string {
1054
1131
  if (!$this->callLhsRequiresParens($node)) {
1055
1132
  return $this->p($node);
1056
- } else {
1133
+ } else {
1057
1134
  return '(' . $this->p($node) . ')';
1058
1135
  }
1059
1136
  }
1060
1137
 
1061
- protected function pNewVariable(Node $node) {
1062
- // TODO: This is not fully accurate.
1063
- return $this->pDereferenceLhs($node);
1138
+ protected function pNewOperand(Node $node): string {
1139
+ if (!$this->newOperandRequiresParens($node)) {
1140
+ return $this->p($node);
1141
+ } else {
1142
+ return '(' . $this->p($node) . ')';
1143
+ }
1064
1144
  }
1065
1145
 
1066
1146
  /**
1067
1147
  * @param Node[] $nodes
1068
- * @return bool
1069
1148
  */
1070
- protected function hasNodeWithComments(array $nodes) {
1149
+ protected function hasNodeWithComments(array $nodes): bool {
1071
1150
  foreach ($nodes as $node) {
1072
1151
  if ($node && $node->getComments()) {
1073
1152
  return true;
@@ -1076,7 +1155,8 @@ class Standard extends PrettyPrinterAbstract
1076
1155
  return false;
1077
1156
  }
1078
1157
 
1079
- protected function pMaybeMultiline(array $nodes, bool $trailingComma = false) {
1158
+ /** @param Node[] $nodes */
1159
+ protected function pMaybeMultiline(array $nodes, bool $trailingComma = false): string {
1080
1160
  if (!$this->hasNodeWithComments($nodes)) {
1081
1161
  return $this->pCommaSeparated($nodes);
1082
1162
  } else {
@@ -1084,6 +1164,7 @@ class Standard extends PrettyPrinterAbstract
1084
1164
  }
1085
1165
  }
1086
1166
 
1167
+ /** @param Node\AttributeGroup[] $nodes */
1087
1168
  protected function pAttrGroups(array $nodes, bool $inline = false): string {
1088
1169
  $result = '';
1089
1170
  $sep = $inline ? ' ' : $this->nl;