@mpeggroup/mpeg-sdl-parser 4.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 (375) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +337 -0
  3. package/bun.lock +65 -0
  4. package/dist/index.js +11829 -0
  5. package/grammar/sdl.ebnf.grammar +399 -0
  6. package/grammar/sdl.lezer.grammar +629 -0
  7. package/index.ts +83 -0
  8. package/package.json +61 -0
  9. package/src/analyser/checks/check-array-definition.ts +90 -0
  10. package/src/analyser/checks/check-array-element-access.ts +31 -0
  11. package/src/analyser/checks/check-class-declaration.ts +417 -0
  12. package/src/analyser/checks/check-computed-array-definition.ts +44 -0
  13. package/src/analyser/checks/check-computed-elementary-type-definition.ts +45 -0
  14. package/src/analyser/checks/check-elementary-type-definition.ts +167 -0
  15. package/src/analyser/checks/check-expression-binary.ts +242 -0
  16. package/src/analyser/checks/check-expression-lengthof.ts +34 -0
  17. package/src/analyser/checks/check-expression-unary.ts +166 -0
  18. package/src/analyser/checks/check-identifier.ts +71 -0
  19. package/src/analyser/checks/check-if-statement.ts +164 -0
  20. package/src/analyser/checks/check-map-declaration.ts +180 -0
  21. package/src/analyser/checks/check-map-definition.ts +118 -0
  22. package/src/analyser/checks/check-number-literal-float.ts +28 -0
  23. package/src/analyser/checks/check-parameter-list.ts +42 -0
  24. package/src/analyser/checks/check-specification.ts +53 -0
  25. package/src/analyser/checks/check-switch-statement.ts +206 -0
  26. package/src/analyser/checks/check.ts +20 -0
  27. package/src/analyser/create-sdl-analyser.ts +85 -0
  28. package/src/analyser/node-handler/abstract-analysis-node-handler.ts +626 -0
  29. package/src/analyser/node-handler/build-symbol-table-node-handler.ts +649 -0
  30. package/src/analyser/node-handler/specific-check-node-handler.ts +46 -0
  31. package/src/analyser/node-handler/validate-scope-node-handler.ts +290 -0
  32. package/src/analyser/node-handler/validate-type-node-handler.ts +497 -0
  33. package/src/analyser/sdl-analyser.ts +119 -0
  34. package/src/analyser/symbol-table.ts +388 -0
  35. package/src/analyser/util/symbol-table-utils.ts +458 -0
  36. package/src/analyser/util/type-utils.ts +238 -0
  37. package/src/ast/build/consume/consume-abstract-node.ts +199 -0
  38. package/src/ast/build/consume/consume-ast-node.ts +400 -0
  39. package/src/ast/build/consume/consume-primitive.ts +59 -0
  40. package/src/ast/build/consume/consume-trivia.ts +96 -0
  41. package/src/ast/build/consume/consume-white-space-and-missing-errors.ts +27 -0
  42. package/src/ast/build/node/build-aggregate-output-value.ts +57 -0
  43. package/src/ast/build/node/build-aligned-modifier.ts +99 -0
  44. package/src/ast/build/node/build-array-definition.ts +131 -0
  45. package/src/ast/build/node/build-array-element-access.ts +45 -0
  46. package/src/ast/build/node/build-base64-string-literal.ts +41 -0
  47. package/src/ast/build/node/build-binary-expression.ts +113 -0
  48. package/src/ast/build/node/build-binary-literal.ts +37 -0
  49. package/src/ast/build/node/build-bit-modifier.ts +86 -0
  50. package/src/ast/build/node/build-case-clause.ts +101 -0
  51. package/src/ast/build/node/build-class-declaration.ts +124 -0
  52. package/src/ast/build/node/build-class-definition.ts +56 -0
  53. package/src/ast/build/node/build-class-id-range.ts +32 -0
  54. package/src/ast/build/node/build-class-id.ts +19 -0
  55. package/src/ast/build/node/build-class-member-access.ts +27 -0
  56. package/src/ast/build/node/build-compound-statement.ts +33 -0
  57. package/src/ast/build/node/build-computed-array-definition.ts +53 -0
  58. package/src/ast/build/node/build-computed-elementary-type-definition.ts +100 -0
  59. package/src/ast/build/node/build-decimal-literal.ts +15 -0
  60. package/src/ast/build/node/build-default-clause.ts +76 -0
  61. package/src/ast/build/node/build-do-statement.ts +71 -0
  62. package/src/ast/build/node/build-elementary-type-definition.ts +164 -0
  63. package/src/ast/build/node/build-elementary-type-output-value.ts +25 -0
  64. package/src/ast/build/node/build-elementary-type.ts +36 -0
  65. package/src/ast/build/node/build-expandable-modifier.ts +68 -0
  66. package/src/ast/build/node/build-explicit-array-dimension.ts +37 -0
  67. package/src/ast/build/node/build-expression-statement.ts +31 -0
  68. package/src/ast/build/node/build-extended-class-id-range.ts +27 -0
  69. package/src/ast/build/node/build-extends-modifier.ts +41 -0
  70. package/src/ast/build/node/build-floating-point-literal.ts +15 -0
  71. package/src/ast/build/node/build-for-statement.ts +117 -0
  72. package/src/ast/build/node/build-hexadecimal-literal.ts +38 -0
  73. package/src/ast/build/node/build-identifier.ts +8 -0
  74. package/src/ast/build/node/build-if-statement.ts +82 -0
  75. package/src/ast/build/node/build-implicit-array-dimension.ts +78 -0
  76. package/src/ast/build/node/build-integer-literal.ts +15 -0
  77. package/src/ast/build/node/build-length-attribute.ts +48 -0
  78. package/src/ast/build/node/build-lengthof-expression.ts +45 -0
  79. package/src/ast/build/node/build-map-declaration.ts +110 -0
  80. package/src/ast/build/node/build-map-definition.ts +103 -0
  81. package/src/ast/build/node/build-map-entry.ts +33 -0
  82. package/src/ast/build/node/build-missing-error.ts +10 -0
  83. package/src/ast/build/node/build-multiple-character-literal.ts +65 -0
  84. package/src/ast/build/node/build-parameter-list.ts +50 -0
  85. package/src/ast/build/node/build-parameter-value-list.ts +54 -0
  86. package/src/ast/build/node/build-parameter.ts +47 -0
  87. package/src/ast/build/node/build-partial-array-dimension.ts +55 -0
  88. package/src/ast/build/node/build-specification.ts +24 -0
  89. package/src/ast/build/node/build-string-definition.ts +106 -0
  90. package/src/ast/build/node/build-switch-statement.ts +84 -0
  91. package/src/ast/build/node/build-token.ts +26 -0
  92. package/src/ast/build/node/build-unary-expression.ts +109 -0
  93. package/src/ast/build/node/build-unexpected-error.ts +14 -0
  94. package/src/ast/build/node/build-utf-string-literal.ts +110 -0
  95. package/src/ast/build/node/build-while-statement.ts +55 -0
  96. package/src/ast/build/util/array-dimension-kind-by-token-type-id-map.ts +167 -0
  97. package/src/ast/build/util/binary-operator-kind-by-token-type-id-map.ts +152 -0
  98. package/src/ast/build/util/build-context.ts +36 -0
  99. package/src/ast/build/util/class-id-kind-by-token-type-id-map.ts +160 -0
  100. package/src/ast/build/util/expression-kind-by-token-type-id-map.ts +168 -0
  101. package/src/ast/build/util/fetch-node.ts +433 -0
  102. package/src/ast/build/util/node-kind-by-token-type-id-map.ts +202 -0
  103. package/src/ast/build/util/statement-kind-by-token-type-id-map.ts +210 -0
  104. package/src/ast/build/util/string-literal-kind-by-token-type-id-map.ts +162 -0
  105. package/src/ast/build/util/token-kind-by-token-type-id-map.ts +337 -0
  106. package/src/ast/build-ast.ts +114 -0
  107. package/src/ast/node/abstract-array-definition.ts +17 -0
  108. package/src/ast/node/abstract-array-dimension.ts +20 -0
  109. package/src/ast/node/abstract-class-id.ts +13 -0
  110. package/src/ast/node/abstract-composite-node.ts +58 -0
  111. package/src/ast/node/abstract-elementary-type-definition.ts +29 -0
  112. package/src/ast/node/abstract-expression.ts +13 -0
  113. package/src/ast/node/abstract-leaf-node.ts +10 -0
  114. package/src/ast/node/abstract-node.ts +16 -0
  115. package/src/ast/node/abstract-statement.ts +13 -0
  116. package/src/ast/node/aggregate-output-value.ts +28 -0
  117. package/src/ast/node/aligned-modifier.ts +21 -0
  118. package/src/ast/node/array-definition.ts +44 -0
  119. package/src/ast/node/array-element-access.ts +24 -0
  120. package/src/ast/node/binary-expression.ts +28 -0
  121. package/src/ast/node/bit-modifier.ts +24 -0
  122. package/src/ast/node/case-clause.ts +30 -0
  123. package/src/ast/node/class-declaration.ts +39 -0
  124. package/src/ast/node/class-definition.ts +23 -0
  125. package/src/ast/node/class-id-range.ts +17 -0
  126. package/src/ast/node/class-id.ts +14 -0
  127. package/src/ast/node/class-member-access.ts +19 -0
  128. package/src/ast/node/compound-statement.ts +19 -0
  129. package/src/ast/node/computed-array-definition.ts +26 -0
  130. package/src/ast/node/computed-elementary-type-definition.ts +34 -0
  131. package/src/ast/node/default-clause.ts +26 -0
  132. package/src/ast/node/do-statement.ts +28 -0
  133. package/src/ast/node/elementary-type-definition.ts +49 -0
  134. package/src/ast/node/elementary-type-output-value.ts +19 -0
  135. package/src/ast/node/elementary-type.ts +18 -0
  136. package/src/ast/node/enum/array-dimension-kind.ts +11 -0
  137. package/src/ast/node/enum/binary-operator-kind.ts +41 -0
  138. package/src/ast/node/enum/class-id-kind.ts +12 -0
  139. package/src/ast/node/enum/elementary-type-kind.ts +13 -0
  140. package/src/ast/node/enum/expression-kind.ts +11 -0
  141. package/src/ast/node/enum/node-kind.ts +57 -0
  142. package/src/ast/node/enum/number-literal-kind.ts +17 -0
  143. package/src/ast/node/enum/statement-kind.ts +37 -0
  144. package/src/ast/node/enum/string-literal-kind.ts +13 -0
  145. package/src/ast/node/enum/string-variable-kind.ts +25 -0
  146. package/src/ast/node/enum/token-kind.ts +87 -0
  147. package/src/ast/node/expandable-modifier.ts +21 -0
  148. package/src/ast/node/explicit-array-dimension.ts +26 -0
  149. package/src/ast/node/expression-statement.ts +23 -0
  150. package/src/ast/node/extended-class-id-range.ts +20 -0
  151. package/src/ast/node/extends-modifier.ts +21 -0
  152. package/src/ast/node/for-statement.ts +29 -0
  153. package/src/ast/node/identifier.ts +12 -0
  154. package/src/ast/node/if-statement.ts +28 -0
  155. package/src/ast/node/implicit-array-dimension.ts +34 -0
  156. package/src/ast/node/length-attribute.ts +24 -0
  157. package/src/ast/node/length-of-expression.ts +21 -0
  158. package/src/ast/node/map-declaration.ts +34 -0
  159. package/src/ast/node/map-definition.ts +27 -0
  160. package/src/ast/node/map-entry.ts +18 -0
  161. package/src/ast/node/missing-error.ts +9 -0
  162. package/src/ast/node/number-literal.ts +18 -0
  163. package/src/ast/node/parameter-list.ts +25 -0
  164. package/src/ast/node/parameter-value-list.ts +29 -0
  165. package/src/ast/node/parameter.ts +20 -0
  166. package/src/ast/node/partial-array-dimension.ts +28 -0
  167. package/src/ast/node/specification.ts +21 -0
  168. package/src/ast/node/string-definition.ts +28 -0
  169. package/src/ast/node/string-literal.ts +21 -0
  170. package/src/ast/node/switch-statement.ts +32 -0
  171. package/src/ast/node/token.ts +20 -0
  172. package/src/ast/node/trivia.ts +13 -0
  173. package/src/ast/node/unary-expression.ts +31 -0
  174. package/src/ast/node/unexpected-error.ts +12 -0
  175. package/src/ast/node/while-statement.ts +26 -0
  176. package/src/ast/util/types.ts +138 -0
  177. package/src/ast/visitor/node-handler.ts +15 -0
  178. package/src/ast/visitor/node-visitor.ts +13 -0
  179. package/src/ast/visitor/traversing-visitor.ts +69 -0
  180. package/src/completion/completion-rules.ts +447 -0
  181. package/src/completion/get-potential-syntactic-tokens.ts +54 -0
  182. package/src/completion/get-potential-token-type-ids.ts +116 -0
  183. package/src/completion/hierarchical-map.ts +43 -0
  184. package/src/completion/rules/abstract-types.ts +174 -0
  185. package/src/completion/rules/aggregate-output-value-rules.ts +48 -0
  186. package/src/completion/rules/aligned-modifier-rules.ts +45 -0
  187. package/src/completion/rules/array-definition-rules.ts +87 -0
  188. package/src/completion/rules/array-element-access-rules.ts +22 -0
  189. package/src/completion/rules/assignment-expression-rules.ts +19 -0
  190. package/src/completion/rules/binary-expression-rules.ts +23 -0
  191. package/src/completion/rules/bit-modifier-rules.ts +25 -0
  192. package/src/completion/rules/case-clause-rules.ts +39 -0
  193. package/src/completion/rules/class-declaration-rules.ts +81 -0
  194. package/src/completion/rules/class-definition-rules.ts +28 -0
  195. package/src/completion/rules/class-id-range-rules.ts +17 -0
  196. package/src/completion/rules/class-id-rules.ts +9 -0
  197. package/src/completion/rules/class-member-access-rules.ts +7 -0
  198. package/src/completion/rules/compound-statement-rules.ts +25 -0
  199. package/src/completion/rules/computed-array-definition-rules.ts +25 -0
  200. package/src/completion/rules/computed-elementary-type-rules.ts +44 -0
  201. package/src/completion/rules/default-clause-rules.ts +23 -0
  202. package/src/completion/rules/do-statement-rules.ts +38 -0
  203. package/src/completion/rules/elementary-type-definition-rules.ts +62 -0
  204. package/src/completion/rules/elementary-type-output-value-rules.ts +13 -0
  205. package/src/completion/rules/elementary-type-rules.ts +18 -0
  206. package/src/completion/rules/expandable-modifier-rules.ts +21 -0
  207. package/src/completion/rules/explicit-array-dimension-rules.ts +22 -0
  208. package/src/completion/rules/expression-statement-rules.ts +22 -0
  209. package/src/completion/rules/extended-class-id-range-rules.ts +17 -0
  210. package/src/completion/rules/extends-modifier-rules.ts +17 -0
  211. package/src/completion/rules/for-statement-rules.ts +51 -0
  212. package/src/completion/rules/if-statement-rules.ts +42 -0
  213. package/src/completion/rules/implicit-array-dimension-rules.ts +21 -0
  214. package/src/completion/rules/length-attribute-rules.ts +19 -0
  215. package/src/completion/rules/lengthof-expression-rules.ts +23 -0
  216. package/src/completion/rules/map-declaration-rules.ts +45 -0
  217. package/src/completion/rules/map-definition-rules.ts +46 -0
  218. package/src/completion/rules/map-entry-rules.ts +17 -0
  219. package/src/completion/rules/parameter-list-rules.ts +21 -0
  220. package/src/completion/rules/parameter-rules.ts +17 -0
  221. package/src/completion/rules/parameter-value-list-rules.ts +27 -0
  222. package/src/completion/rules/partial-array-dimension-rules.ts +33 -0
  223. package/src/completion/rules/specification-rules.ts +37 -0
  224. package/src/completion/rules/string-definition-rules.ts +103 -0
  225. package/src/completion/rules/switch-statement-rules.ts +50 -0
  226. package/src/completion/rules/unary-expression-rules.ts +41 -0
  227. package/src/completion/rules/utf-string-literal-rules.ts +17 -0
  228. package/src/completion/rules/while-statement-rules.ts +38 -0
  229. package/src/lezer/context-tracker.ts +45 -0
  230. package/src/lezer/create-sdl-parser.ts +88 -0
  231. package/src/lezer/create-syntax-error-from-text-and-cursor.ts +110 -0
  232. package/src/lezer/create-syntax-error-from-text-and-position.ts +36 -0
  233. package/src/lezer/parser.terms.ts +129 -0
  234. package/src/lezer/parser.ts +63 -0
  235. package/src/lezer/props/fold-node-prop-source.ts +27 -0
  236. package/src/lezer/props/primitive-node-prop-source.ts +19 -0
  237. package/src/lezer/props/style-tags-node-prop-source.ts +188 -0
  238. package/src/lezer/props/syntactic-token-node-prop-source.ts +298 -0
  239. package/src/lezer/sdl-string-input.ts +46 -0
  240. package/src/location.ts +13 -0
  241. package/src/parse-helper.ts +93 -0
  242. package/src/prettier/prettier-plugin-sdl.ts +89 -0
  243. package/src/prettier/print-abstract-array-dimension.ts +84 -0
  244. package/src/prettier/print-abstract-class-id.ts +53 -0
  245. package/src/prettier/print-abstract-expression.ts +168 -0
  246. package/src/prettier/print-abstract-node.ts +224 -0
  247. package/src/prettier/print-abstract-statement.ts +124 -0
  248. package/src/prettier/print-aggregate-output-value.ts +35 -0
  249. package/src/prettier/print-aligned-modifier.ts +50 -0
  250. package/src/prettier/print-array-definition.ts +95 -0
  251. package/src/prettier/print-array-element-access.ts +14 -0
  252. package/src/prettier/print-bit-modifier.ts +48 -0
  253. package/src/prettier/print-case-clause.ts +58 -0
  254. package/src/prettier/print-class-declaration.ts +99 -0
  255. package/src/prettier/print-class-definition.ts +44 -0
  256. package/src/prettier/print-class-member-access.ts +13 -0
  257. package/src/prettier/print-computed-array-definition.ts +33 -0
  258. package/src/prettier/print-computed-elementary-type-definition.ts +60 -0
  259. package/src/prettier/print-default-clause.ts +39 -0
  260. package/src/prettier/print-do-statement.ts +31 -0
  261. package/src/prettier/print-elementary-type-definition.ts +108 -0
  262. package/src/prettier/print-elementary-type-output-value.ts +13 -0
  263. package/src/prettier/print-elementary-type.ts +28 -0
  264. package/src/prettier/print-expandable-modifier.ts +41 -0
  265. package/src/prettier/print-extends-modifier.ts +29 -0
  266. package/src/prettier/print-for-statement.ts +64 -0
  267. package/src/prettier/print-identifier.ts +10 -0
  268. package/src/prettier/print-if-statement.ts +76 -0
  269. package/src/prettier/print-length-attribute.ts +14 -0
  270. package/src/prettier/print-map-declaration.ts +75 -0
  271. package/src/prettier/print-map-definition.ts +67 -0
  272. package/src/prettier/print-map-entry.ts +22 -0
  273. package/src/prettier/print-number-literal.ts +84 -0
  274. package/src/prettier/print-parameter-list.ts +20 -0
  275. package/src/prettier/print-parameter-value-list.ts +20 -0
  276. package/src/prettier/print-parameter.ts +34 -0
  277. package/src/prettier/print-specification.ts +51 -0
  278. package/src/prettier/print-string-definition.ts +114 -0
  279. package/src/prettier/print-string-literal.ts +57 -0
  280. package/src/prettier/print-switch-statement.ts +46 -0
  281. package/src/prettier/print-token.ts +7 -0
  282. package/src/prettier/print-unexpected-error.ts +10 -0
  283. package/src/prettier/print-while-statement.ts +26 -0
  284. package/src/prettier/util/print-utils.ts +607 -0
  285. package/src/prettier/util/types.ts +40 -0
  286. package/src/scanner-error.ts +65 -0
  287. package/src/util/location-utils.ts +16 -0
  288. package/src/util/logger.ts +165 -0
  289. package/tests/analyser/create-sdl-analyser.test.ts +54 -0
  290. package/tests/analyser/get-sdl-analyser-test-scenarios.ts +80 -0
  291. package/tests/analyser/sdl-analyser-scenarios.test.ts +67 -0
  292. package/tests/analyser/semantic-error-scenarios.test.ts +40 -0
  293. package/tests/analyser/symbol-table.test.ts +188 -0
  294. package/tests/analyser/test-cases/array_definition.txt +50 -0
  295. package/tests/analyser/test-cases/class_declaration.txt +112 -0
  296. package/tests/analyser/test-cases/class_definition.txt +60 -0
  297. package/tests/analyser/test-cases/compound_statement.txt +63 -0
  298. package/tests/analyser/test-cases/computed_array_definition.txt +12 -0
  299. package/tests/analyser/test-cases/computed_elementary_type_definition.txt +39 -0
  300. package/tests/analyser/test-cases/do_statement.txt +16 -0
  301. package/tests/analyser/test-cases/elementary_type_definition.txt +58 -0
  302. package/tests/analyser/test-cases/expression.txt +159 -0
  303. package/tests/analyser/test-cases/for_statement.txt +55 -0
  304. package/tests/analyser/test-cases/if_statement.txt +57 -0
  305. package/tests/analyser/test-cases/map_declaration.txt +89 -0
  306. package/tests/analyser/test-cases/map_definition.txt +35 -0
  307. package/tests/analyser/test-cases/number_literal.txt +31 -0
  308. package/tests/analyser/test-cases/parameter_list.txt +16 -0
  309. package/tests/analyser/test-cases/scopes.txt +239 -0
  310. package/tests/analyser/test-cases/specification.txt +28 -0
  311. package/tests/analyser/test-cases/string_definition.txt +40 -0
  312. package/tests/analyser/test-cases/switch_statement.txt +96 -0
  313. package/tests/analyser/test-cases/while_statement.txt +16 -0
  314. package/tests/analyser/util/symbol-table-utils.test.ts +65 -0
  315. package/tests/ast/__snapshots__/build-ast.test.ts.snap +38897 -0
  316. package/tests/ast/build-ast.test.ts +463 -0
  317. package/tests/ast/visitor/traversing-visitor.test.ts +36 -0
  318. package/tests/completion/get-potential-syntactic-tokens.test.ts +89 -0
  319. package/tests/completion/get-potential-token-type-ids.test.ts +76 -0
  320. package/tests/completion/test-potential-syntactic-tokens-scenario.ts +24 -0
  321. package/tests/completion/test-potential-token-type-ids-scenario.ts +33 -0
  322. package/tests/fixtures/history-recording-node-handler.ts +232 -0
  323. package/tests/lezer/create-parse-error-from-text-and-position.test.ts +129 -0
  324. package/tests/lezer/create-sdl-parser.test.ts +15 -0
  325. package/tests/lezer/sdl-parser-scenarios.test.ts +24 -0
  326. package/tests/lezer/sdl-string-input.test.ts +12 -0
  327. package/tests/lezer/syntax-error-scenarios.test.ts +114 -0
  328. package/tests/lezer/test-cases/array_definition.txt +109 -0
  329. package/tests/lezer/test-cases/class_declaration.txt +141 -0
  330. package/tests/lezer/test-cases/class_definition.txt +89 -0
  331. package/tests/lezer/test-cases/comment.txt +335 -0
  332. package/tests/lezer/test-cases/compound_statement.txt +109 -0
  333. package/tests/lezer/test-cases/computed_array_definition.txt +33 -0
  334. package/tests/lezer/test-cases/computed_elementary_type_definition.txt +59 -0
  335. package/tests/lezer/test-cases/do_statement.txt +48 -0
  336. package/tests/lezer/test-cases/elementary_type_definition.txt +158 -0
  337. package/tests/lezer/test-cases/expression.txt +1203 -0
  338. package/tests/lezer/test-cases/for_statement.txt +183 -0
  339. package/tests/lezer/test-cases/if_statement.txt +183 -0
  340. package/tests/lezer/test-cases/invalid.txt +97 -0
  341. package/tests/lezer/test-cases/map_declaration.txt +152 -0
  342. package/tests/lezer/test-cases/map_definition.txt +59 -0
  343. package/tests/lezer/test-cases/number_literal.txt +273 -0
  344. package/tests/lezer/test-cases/specification.txt +38 -0
  345. package/tests/lezer/test-cases/string_definition.txt +263 -0
  346. package/tests/lezer/test-cases/string_literal.txt +303 -0
  347. package/tests/lezer/test-cases/switch_statement.txt +407 -0
  348. package/tests/lezer/test-cases/while_statement.txt +45 -0
  349. package/tests/parse-helper.test.ts +361 -0
  350. package/tests/prettier/__snapshots__/prettier-plugin-sdl.test.ts.snap +127 -0
  351. package/tests/prettier/prettier-plugin-sdl.test.ts +58 -0
  352. package/tests/prettier/print-array.test.ts +29 -0
  353. package/tests/prettier/print-class.test.ts +15 -0
  354. package/tests/prettier/print-do.test.ts +25 -0
  355. package/tests/prettier/print-elementary-type.test.ts +62 -0
  356. package/tests/prettier/print-error.test.ts +40 -0
  357. package/tests/prettier/print-expression.test.ts +17 -0
  358. package/tests/prettier/print-for.test.ts +23 -0
  359. package/tests/prettier/print-if.test.ts +71 -0
  360. package/tests/prettier/print-number-literal.test.ts +28 -0
  361. package/tests/prettier/print-specification.test.ts +54 -0
  362. package/tests/prettier/print-string.test.ts +36 -0
  363. package/tests/prettier/print-switch.test.ts +69 -0
  364. package/tests/prettier/print-while.test.ts +23 -0
  365. package/tests/prettier/test-prettier-scenario.ts +41 -0
  366. package/tests/prettier/util/print-utils.test.ts +665 -0
  367. package/tests/prettier/util/types.test.ts +38 -0
  368. package/tests/sample-specifications/invalid.sdl +24 -0
  369. package/tests/sample-specifications/prettified-invalid.sdl +28 -0
  370. package/tests/sample-specifications/prettified-various-elements-narrow.sdl +97 -0
  371. package/tests/sample-specifications/prettified-various-elements.sdl +90 -0
  372. package/tests/sample-specifications/sample.sdl +24 -0
  373. package/tests/sample-specifications/various-elements.sdl +88 -0
  374. package/tests/util/logger.test.ts +36 -0
  375. package/tsconfig.json +29 -0
@@ -0,0 +1,10 @@
1
+ import type { AstPath, Doc } from "prettier";
2
+ import type { UnexpectedError } from "../ast/node/unexpected-error.ts";
3
+ import type { AbstractNode } from "../ast/node/abstract-node.ts";
4
+
5
+ export function printUnexpectedError(
6
+ path: AstPath<UnexpectedError>,
7
+ print: (path: AstPath<AbstractNode>) => Doc,
8
+ ): Doc {
9
+ return path.call(print, "unexpectedToken");
10
+ }
@@ -0,0 +1,26 @@
1
+ import { AstPath, type Doc } from "prettier";
2
+ import { addNonBreakingWhitespace } from "./util/print-utils.ts";
3
+ import type { AbstractNode } from "../ast/node/abstract-node.ts";
4
+ import type { WhileStatement } from "../ast/node/while-statement.ts";
5
+
6
+ export function printWhileStatement(
7
+ path: AstPath<WhileStatement>,
8
+ print: (path: AstPath<AbstractNode>) => Doc,
9
+ ): Doc {
10
+ const doc: Doc = [];
11
+
12
+ doc.push(path.call(print, "whileKeyword"));
13
+ addNonBreakingWhitespace(doc);
14
+
15
+ doc.push([
16
+ path.call(print, "openParenthesisPunctuator"),
17
+ path.call(print, "condition"),
18
+ path.call(print, "closeParenthesisPunctuator"),
19
+ ]);
20
+
21
+ addNonBreakingWhitespace(doc);
22
+
23
+ doc.push(path.call(print, "statement"));
24
+
25
+ return doc;
26
+ }
@@ -0,0 +1,607 @@
1
+ import { type Doc, doc } from "prettier";
2
+ import type { Trivia } from "../../ast/node/trivia.ts";
3
+ import type { AbstractNode } from "../../ast/node/abstract-node.ts";
4
+ import {
5
+ isBreakParent,
6
+ isFill,
7
+ isHardline,
8
+ isIndent,
9
+ isLabel,
10
+ } from "./types.ts";
11
+ import { InternalScannerError } from "../../scanner-error.ts";
12
+
13
+ const { hardline, ifBreak, label, line, indent } = doc.builders;
14
+
15
+ function getCommentString(trivia: Trivia): string {
16
+ if (!trivia.text.startsWith("//")) {
17
+ throw new InternalScannerError(
18
+ "Logic Error: Expected comment to start with // : " +
19
+ JSON.stringify(trivia),
20
+ );
21
+ }
22
+ // Remove leading "//" from the comment text
23
+ return "// " + trivia.text.replace(/^\s*\/\/\s*/, "").trim();
24
+ }
25
+
26
+ function addTrivia(doc: Doc, trivia: Trivia): Doc[] {
27
+ let commentDoc: Doc = [];
28
+
29
+ if (trivia.text === "\n") {
30
+ commentDoc = "";
31
+ } else {
32
+ commentDoc = getCommentString(trivia);
33
+ }
34
+ if (Array.isArray(doc)) {
35
+ doc.push(commentDoc);
36
+ } else {
37
+ doc = [doc, commentDoc];
38
+ }
39
+
40
+ return doc;
41
+ }
42
+
43
+ /**
44
+ * Gets the leading trivia doc for the given node if it has any leading trivia.
45
+ */
46
+ export function getLeadingTriviaDoc(node: AbstractNode): Doc | undefined {
47
+ if (!node || !node.leadingTrivia || (node.leadingTrivia.length === 0)) {
48
+ return undefined;
49
+ }
50
+
51
+ let doc: Doc = [];
52
+
53
+ node.leadingTrivia.forEach((trivia) => {
54
+ doc = addTrivia(doc, trivia);
55
+ doc.push(hardline);
56
+ });
57
+
58
+ return label("leadingTrivia", doc);
59
+ }
60
+
61
+ /**
62
+ * Gets the trailing trivia doc for the given node if it has any trailing trivia.
63
+ */
64
+ export function getTrailingTriviaDoc(node: AbstractNode): Doc | undefined {
65
+ if (!node || !node.trailingTrivia || (node.trailingTrivia.length === 0)) {
66
+ return undefined;
67
+ }
68
+
69
+ let doc: Doc = [];
70
+
71
+ node.trailingTrivia.forEach((trivia) => {
72
+ doc = addTrivia(doc, trivia);
73
+ doc.push(hardline);
74
+ });
75
+
76
+ return label("trailingTrivia", doc);
77
+ }
78
+
79
+ /**
80
+ * Adds the trailing trivia doc to the given doc.
81
+ */
82
+ export function addTrailingTriviaDoc(
83
+ doc: Doc,
84
+ trailingTriviaDoc: Doc,
85
+ ): Doc {
86
+ if (Array.isArray(doc)) {
87
+ if (doc.length === 0) {
88
+ doc = [
89
+ trailingTriviaDoc,
90
+ ];
91
+
92
+ return doc;
93
+ }
94
+
95
+ // find last element which is not a break-parent and not a hardline
96
+ let i = doc.length - 1;
97
+ while ((i >= 0) && (isBreakParent(doc[i]) || isHardline(doc[i]))) {
98
+ i--;
99
+ }
100
+
101
+ if (i < 0) {
102
+ return doc;
103
+ }
104
+ const lastNonBreakParentElement = doc[i];
105
+
106
+ if (Array.isArray(lastNonBreakParentElement)) {
107
+ doc[i] = addTrailingTriviaDoc(
108
+ lastNonBreakParentElement,
109
+ trailingTriviaDoc,
110
+ );
111
+
112
+ return doc;
113
+ }
114
+
115
+ // element might be an indent or label
116
+ if (
117
+ isIndent(lastNonBreakParentElement) ||
118
+ isLabel(lastNonBreakParentElement)
119
+ ) {
120
+ lastNonBreakParentElement.contents = addTrailingTriviaDoc(
121
+ lastNonBreakParentElement.contents,
122
+ trailingTriviaDoc,
123
+ );
124
+ } // element might be a fill
125
+ else if (isFill(lastNonBreakParentElement)) {
126
+ lastNonBreakParentElement.parts = addTrailingTriviaDoc(
127
+ lastNonBreakParentElement.parts,
128
+ trailingTriviaDoc,
129
+ ) as Doc[];
130
+ } // otherwise we found the last element to add trivia after
131
+ // behavior is different if the token is a close brace
132
+ else if (lastNonBreakParentElement === "}") {
133
+ doc[i] = [
134
+ lastNonBreakParentElement,
135
+ ifBreak([line, ""], " "),
136
+ trailingTriviaDoc,
137
+ ];
138
+ } else {
139
+ doc[i] = [
140
+ lastNonBreakParentElement,
141
+ ifBreak([line, " "], " "),
142
+ trailingTriviaDoc,
143
+ ];
144
+ }
145
+
146
+ return doc;
147
+ }
148
+
149
+ if (isIndent(doc) || isLabel(doc)) {
150
+ doc.contents = addTrailingTriviaDoc(doc.contents, trailingTriviaDoc);
151
+ } else if (isFill(doc)) {
152
+ doc.parts = addTrailingTriviaDoc(doc.parts, trailingTriviaDoc) as Doc[];
153
+ }
154
+
155
+ return doc;
156
+ }
157
+
158
+ /**
159
+ * Determines whether the given doc ends with a hardline, ignoring trailing break-parents.
160
+ */
161
+ export function endsWithHardline(doc: Doc): boolean {
162
+ if (Array.isArray(doc)) {
163
+ // can't end with hardline if empty array
164
+ if (doc.length === 0) {
165
+ return false;
166
+ }
167
+
168
+ // potential hardline as hardline is an array of [HardlineWithoutBreakParent, BreakParent]
169
+ if (isHardline(doc)) {
170
+ return true;
171
+ }
172
+
173
+ // find last element which is not a break-parent as we ignore trailing break-parents
174
+ let i = doc.length - 1;
175
+ while ((i >= 0) && isBreakParent(doc[i])) {
176
+ i--;
177
+ }
178
+
179
+ if (i < 0) {
180
+ return false;
181
+ }
182
+
183
+ // recurse
184
+ return endsWithHardline(doc[i]);
185
+ }
186
+
187
+ // recurse
188
+ if (isIndent(doc) || isLabel(doc)) {
189
+ return endsWithHardline(doc.contents);
190
+ }
191
+
192
+ // recurse
193
+ if (isFill(doc)) {
194
+ return endsWithHardline(doc.parts);
195
+ }
196
+
197
+ return false;
198
+ }
199
+
200
+ /**
201
+ * Determines whether the given doc starts with a blank line i.e. ["", hardline, ...]
202
+ */
203
+ export function startsWithBlankLine(doc: Doc): boolean {
204
+ if (Array.isArray(doc)) {
205
+ // can't contain leading blankline if empty array
206
+ if (doc.length === 0) {
207
+ return false;
208
+ }
209
+
210
+ // check if the array starts with ["", hardline, ...]
211
+ if (doc.length >= 2) {
212
+ if ((doc[0] === "") && isHardline(doc[1])) {
213
+ return true;
214
+ }
215
+ }
216
+
217
+ // recurse
218
+ return startsWithBlankLine(doc[0]);
219
+ }
220
+
221
+ // recurse
222
+ if (isIndent(doc) || isLabel(doc)) {
223
+ return startsWithBlankLine(doc.contents);
224
+ }
225
+ if (isFill(doc)) {
226
+ return startsWithBlankLine(doc.parts);
227
+ }
228
+
229
+ return false;
230
+ }
231
+
232
+ function removeLeadingBlankline(doc: Doc): Doc {
233
+ if (Array.isArray(doc)) {
234
+ // can't contain leading blankline if empty array
235
+ if (doc.length === 0) {
236
+ return doc;
237
+ }
238
+
239
+ // check if the array starts with ["", hardline, ...]
240
+ if (doc.length >= 2) {
241
+ if ((doc[0] === "") && isHardline(doc[1])) {
242
+ // remove the first two elements
243
+ doc.splice(0, 2);
244
+
245
+ // don't return a single item array
246
+ if (doc.length === 1) {
247
+ return doc[0];
248
+ }
249
+
250
+ return doc;
251
+ }
252
+ }
253
+
254
+ // recurse
255
+ const firstItem = removeLeadingBlankline(doc[0]);
256
+
257
+ // don't leave an empty array at the start
258
+ if (Array.isArray(firstItem) && (firstItem.length === 0)) {
259
+ doc.splice(0, 1);
260
+ } else {
261
+ doc[0] = firstItem;
262
+ }
263
+
264
+ // don't return a single item array
265
+ if (doc.length === 1) {
266
+ return doc[0];
267
+ }
268
+
269
+ return doc;
270
+ }
271
+
272
+ // recurse
273
+ if (isIndent(doc) || isLabel(doc)) {
274
+ doc.contents = removeLeadingBlankline(doc.contents);
275
+
276
+ if (
277
+ (doc.contents === "") ||
278
+ (Array.isArray(doc.contents) && (doc.contents.length === 0))
279
+ ) {
280
+ doc = "";
281
+ }
282
+ } else if (isFill(doc)) {
283
+ doc.parts = removeLeadingBlankline(doc.parts) as Doc[];
284
+
285
+ if (doc.parts.length === 0) {
286
+ doc = "";
287
+ }
288
+ }
289
+
290
+ return doc;
291
+ }
292
+
293
+ /**
294
+ * Removes leading blanklines i.e. ["", hardline, ...] from the given doc if they exist.
295
+ */
296
+ export function removeLeadingBlanklines(doc: Doc): Doc {
297
+ while (startsWithBlankLine(doc)) {
298
+ doc = removeLeadingBlankline(doc);
299
+ }
300
+ return doc;
301
+ }
302
+
303
+ /**
304
+ * Removes a trailing blankline i.e. [..., "", hardline] from the given doc if it exists.
305
+ */
306
+ export function removeTrailingBlankline(doc: Doc): Doc {
307
+ if (Array.isArray(doc)) {
308
+ // can't contain trailing blankline if empty array
309
+ if (doc.length === 0) {
310
+ return doc;
311
+ }
312
+
313
+ // check if the array ends with [..., "", hardline]
314
+ if (doc.length >= 2) {
315
+ if ((doc[doc.length - 2] === "") && isHardline(doc[doc.length - 1])) {
316
+ // remove the last two elements
317
+ doc.splice(doc.length - 2, 2);
318
+
319
+ // don't return a single item array
320
+ if (doc.length === 1) {
321
+ return doc[0];
322
+ }
323
+
324
+ return doc;
325
+ }
326
+ }
327
+
328
+ // recurse
329
+ let lastItem = doc[doc.length - 1];
330
+
331
+ lastItem = removeTrailingBlankline(lastItem);
332
+
333
+ // don't leave an empty array at the end
334
+ if (Array.isArray(lastItem) && (lastItem.length === 0)) {
335
+ doc.splice(doc.length - 1, 1);
336
+ } else {
337
+ doc[doc.length - 1] = lastItem;
338
+ }
339
+
340
+ // don't return a single item array
341
+ if (doc.length === 1) {
342
+ return doc[0];
343
+ }
344
+
345
+ return doc;
346
+ }
347
+
348
+ // recurse
349
+ if (isIndent(doc) || isLabel(doc)) {
350
+ doc.contents = removeTrailingBlankline(doc.contents);
351
+
352
+ if (
353
+ (doc.contents === "") ||
354
+ (Array.isArray(doc.contents) && (doc.contents.length === 0))
355
+ ) {
356
+ doc = "";
357
+ }
358
+ } else if (isFill(doc)) {
359
+ doc.parts = removeTrailingBlankline(doc.parts) as Doc[];
360
+
361
+ if (doc.parts.length === 0) {
362
+ doc = "";
363
+ }
364
+ }
365
+
366
+ return doc;
367
+ }
368
+
369
+ /**
370
+ * Removes a trailing hardline from the given doc if it exists.
371
+ */
372
+ export function removeTrailingHardline(doc: Doc): Doc {
373
+ if (Array.isArray(doc)) {
374
+ if (doc.length === 0) {
375
+ return doc;
376
+ }
377
+
378
+ // array might be a hardline itself
379
+ if (isHardline(doc)) {
380
+ return "";
381
+ }
382
+
383
+ let lastElement = doc[doc.length - 1];
384
+
385
+ // recurse
386
+ lastElement = removeTrailingHardline(lastElement);
387
+
388
+ // don't store empty element
389
+ if (lastElement !== "") {
390
+ doc[doc.length - 1] = lastElement;
391
+ } else {
392
+ doc.splice(doc.length - 1, 1);
393
+ }
394
+
395
+ // don't return a single item array
396
+ if (doc.length === 1) {
397
+ doc = doc[0];
398
+ }
399
+
400
+ // don't return an empty array
401
+ if ((doc as Doc[]).length === 0) {
402
+ doc = "";
403
+ }
404
+
405
+ return doc;
406
+ }
407
+
408
+ // recurse
409
+ if (isIndent(doc) || isLabel(doc)) {
410
+ doc.contents = removeTrailingHardline(doc.contents);
411
+
412
+ if (
413
+ (doc.contents === "") ||
414
+ (Array.isArray(doc.contents) && (doc.contents.length === 0))
415
+ ) {
416
+ doc = "";
417
+ }
418
+ } else if (isFill(doc)) {
419
+ let parts = removeTrailingHardline(doc.parts);
420
+
421
+ if (!Array.isArray(parts)) {
422
+ if (parts === "") {
423
+ return "";
424
+ }
425
+ parts = [parts];
426
+ }
427
+
428
+ doc.parts = parts;
429
+
430
+ if (doc.parts.length === 0) {
431
+ doc = "";
432
+ }
433
+ }
434
+
435
+ return doc;
436
+ }
437
+
438
+ /**
439
+ * Adds a trailing hardline to the given doc if it does not already end with a hardline.
440
+ */
441
+ export function addTrailingHardline(doc: Doc): Doc {
442
+ if (!endsWithHardline(doc)) {
443
+ if (Array.isArray(doc)) {
444
+ doc.push(hardline);
445
+ return doc;
446
+ }
447
+
448
+ return [doc, hardline];
449
+ }
450
+
451
+ return doc;
452
+ }
453
+
454
+ /**
455
+ * Adds indented statement docs to the given doc,
456
+ * optionally with opening and closing brace punctuator docs.
457
+ */
458
+ export function addIndentedStatements(
459
+ doc: Doc[],
460
+ statementDocs: Doc[],
461
+ openBracePunctuatorDoc?: Doc,
462
+ closeBracePunctuatorDoc?: Doc,
463
+ ): Doc[] {
464
+ let indentedDoc: Doc = [];
465
+
466
+ if (openBracePunctuatorDoc) {
467
+ // remove blankline before opening brace
468
+ openBracePunctuatorDoc = removeLeadingBlanklines(openBracePunctuatorDoc);
469
+
470
+ indentedDoc.push(openBracePunctuatorDoc);
471
+ }
472
+
473
+ // indented block should have a hardline before statements
474
+ if (statementDocs.length > 0) {
475
+ indentedDoc = addTrailingHardline(indentedDoc);
476
+ if (!Array.isArray(indentedDoc)) {
477
+ indentedDoc = [indentedDoc];
478
+ }
479
+ }
480
+
481
+ for (let i = 0; i < statementDocs.length; i++) {
482
+ let statementDoc = statementDocs[i];
483
+
484
+ // remove blank lines above first statement
485
+ if (i === 0) {
486
+ statementDoc = removeLeadingBlanklines(statementDoc);
487
+ }
488
+
489
+ indentedDoc.push(statementDoc);
490
+ if ((i < statementDocs.length - 1) && !endsWithHardline(indentedDoc)) {
491
+ indentedDoc.push(hardline);
492
+ }
493
+ }
494
+
495
+ if (Array.isArray(closeBracePunctuatorDoc)) {
496
+ // look for leading trivia element and remove it from closeBracePunctuatorDoc array
497
+ let firstElement = closeBracePunctuatorDoc[0];
498
+
499
+ if (isLabel(firstElement) && (firstElement.label === "leadingTrivia")) {
500
+ // remove leading trivia from closeBracePunctuatorDoc to inside indented block
501
+ closeBracePunctuatorDoc.splice(0, 1);
502
+
503
+ if (closeBracePunctuatorDoc.length === 1) {
504
+ closeBracePunctuatorDoc = closeBracePunctuatorDoc[0];
505
+ }
506
+
507
+ // remove blank line before closing brace i.e. any blank line of trivia above the brace
508
+ firstElement = removeTrailingBlankline(firstElement);
509
+ firstElement = removeTrailingHardline(firstElement);
510
+
511
+ // check if anything remains
512
+ if (firstElement !== "") {
513
+ if (!endsWithHardline(indentedDoc)) {
514
+ indentedDoc.push(hardline);
515
+ }
516
+ indentedDoc.push(firstElement);
517
+ }
518
+ }
519
+ }
520
+
521
+ if (indentedDoc.length > 0) {
522
+ // remove blank line before closing brace
523
+ indentedDoc = removeTrailingBlankline(indentedDoc);
524
+ indentedDoc = removeTrailingHardline(indentedDoc);
525
+ doc.push(indent(indentedDoc));
526
+ doc.push(hardline);
527
+ }
528
+
529
+ if (closeBracePunctuatorDoc) {
530
+ doc.push(closeBracePunctuatorDoc);
531
+ }
532
+
533
+ return doc;
534
+ }
535
+
536
+ function addWhitespace(doc: Doc, isBreaking: boolean): Doc[] {
537
+ let separatorDoc: Doc;
538
+
539
+ if (!endsWithHardline(doc)) {
540
+ separatorDoc = isBreaking ? ifBreak([line, " "], " ") : " ";
541
+ } else {
542
+ separatorDoc = " ";
543
+ }
544
+
545
+ if (Array.isArray(doc)) {
546
+ doc.push(separatorDoc);
547
+ } else {
548
+ doc = [doc, separatorDoc];
549
+ }
550
+
551
+ return doc;
552
+ }
553
+
554
+ /**
555
+ * Adds a breaking whitespace to the given doc or an indent if it ends with a hardline.
556
+ */
557
+ export function addBreakingWhitespace(doc: Doc): Doc[] {
558
+ return addWhitespace(doc, true);
559
+ }
560
+
561
+ /**
562
+ * Adds a non-breaking whitespace to the given doc or an indent if it ends with a hardline.
563
+ */
564
+ export function addNonBreakingWhitespace(doc: Doc): Doc[] {
565
+ return addWhitespace(doc, false);
566
+ }
567
+
568
+ /**
569
+ * Interleaves the given value docs with the given comma separator docs and adds breaking whitespace after each comma separator.
570
+ */
571
+ export function interleaveCommaSeparatorDocs(
572
+ valueDocs: Doc[],
573
+ commaSeparatorDocs: Doc[],
574
+ ): Doc {
575
+ if (commaSeparatorDocs.length === 0) {
576
+ if (valueDocs.length > 1) {
577
+ throw new InternalScannerError(
578
+ `Logic Error: Number of values: ${valueDocs.length} and no comma separators provided`,
579
+ );
580
+ }
581
+ return valueDocs;
582
+ }
583
+
584
+ if (valueDocs.length !== commaSeparatorDocs.length + 1) {
585
+ throw new InternalScannerError(
586
+ `Logic Error: Number of values: ${valueDocs.length} and comma separators: ${commaSeparatorDocs.length} are not as expected`,
587
+ );
588
+ }
589
+
590
+ const doc: Doc = [];
591
+ for (let i = 0; i < valueDocs.length; i++) {
592
+ if (i < commaSeparatorDocs.length) {
593
+ let subDoc: Doc = [];
594
+
595
+ subDoc.push(valueDocs[i]);
596
+ subDoc.push(commaSeparatorDocs[i]);
597
+
598
+ subDoc = addBreakingWhitespace(subDoc);
599
+
600
+ doc.push(subDoc);
601
+ } else {
602
+ doc.push(valueDocs[i]);
603
+ }
604
+ }
605
+
606
+ return doc;
607
+ }
@@ -0,0 +1,40 @@
1
+ import { type Doc, doc } from "prettier";
2
+
3
+ type Fill = doc.builders.Fill;
4
+ type Label = doc.builders.Label;
5
+ type Indent = doc.builders.Indent;
6
+ type Hardline = doc.builders.Hardline;
7
+ type BreakParent = doc.builders.BreakParent;
8
+
9
+ export function isIndent(
10
+ doc: Doc,
11
+ ): doc is Indent {
12
+ return (doc as Indent).type === "indent";
13
+ }
14
+
15
+ export function isFill(
16
+ doc: Doc,
17
+ ): doc is Fill {
18
+ return (doc as Fill).type === "fill";
19
+ }
20
+
21
+ export function isLabel(
22
+ doc: Doc,
23
+ ): doc is Label {
24
+ return (doc as Label).type === "label";
25
+ }
26
+
27
+ export function isBreakParent(
28
+ doc: Doc,
29
+ ): doc is BreakParent {
30
+ return (doc as BreakParent).type === "break-parent";
31
+ }
32
+
33
+ export function isHardline(
34
+ doc: Doc,
35
+ ): doc is Hardline {
36
+ return Array.isArray(doc) && (doc.length === 2) &&
37
+ ((doc as Hardline)[0].type === "line") &&
38
+ ((doc as Hardline)[0].hard === true) &&
39
+ ((doc as Hardline)[1].type === "break-parent");
40
+ }