@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.
- package/LICENSE +21 -0
- package/README.md +337 -0
- package/bun.lock +65 -0
- package/dist/index.js +11829 -0
- package/grammar/sdl.ebnf.grammar +399 -0
- package/grammar/sdl.lezer.grammar +629 -0
- package/index.ts +83 -0
- package/package.json +61 -0
- package/src/analyser/checks/check-array-definition.ts +90 -0
- package/src/analyser/checks/check-array-element-access.ts +31 -0
- package/src/analyser/checks/check-class-declaration.ts +417 -0
- package/src/analyser/checks/check-computed-array-definition.ts +44 -0
- package/src/analyser/checks/check-computed-elementary-type-definition.ts +45 -0
- package/src/analyser/checks/check-elementary-type-definition.ts +167 -0
- package/src/analyser/checks/check-expression-binary.ts +242 -0
- package/src/analyser/checks/check-expression-lengthof.ts +34 -0
- package/src/analyser/checks/check-expression-unary.ts +166 -0
- package/src/analyser/checks/check-identifier.ts +71 -0
- package/src/analyser/checks/check-if-statement.ts +164 -0
- package/src/analyser/checks/check-map-declaration.ts +180 -0
- package/src/analyser/checks/check-map-definition.ts +118 -0
- package/src/analyser/checks/check-number-literal-float.ts +28 -0
- package/src/analyser/checks/check-parameter-list.ts +42 -0
- package/src/analyser/checks/check-specification.ts +53 -0
- package/src/analyser/checks/check-switch-statement.ts +206 -0
- package/src/analyser/checks/check.ts +20 -0
- package/src/analyser/create-sdl-analyser.ts +85 -0
- package/src/analyser/node-handler/abstract-analysis-node-handler.ts +626 -0
- package/src/analyser/node-handler/build-symbol-table-node-handler.ts +649 -0
- package/src/analyser/node-handler/specific-check-node-handler.ts +46 -0
- package/src/analyser/node-handler/validate-scope-node-handler.ts +290 -0
- package/src/analyser/node-handler/validate-type-node-handler.ts +497 -0
- package/src/analyser/sdl-analyser.ts +119 -0
- package/src/analyser/symbol-table.ts +388 -0
- package/src/analyser/util/symbol-table-utils.ts +458 -0
- package/src/analyser/util/type-utils.ts +238 -0
- package/src/ast/build/consume/consume-abstract-node.ts +199 -0
- package/src/ast/build/consume/consume-ast-node.ts +400 -0
- package/src/ast/build/consume/consume-primitive.ts +59 -0
- package/src/ast/build/consume/consume-trivia.ts +96 -0
- package/src/ast/build/consume/consume-white-space-and-missing-errors.ts +27 -0
- package/src/ast/build/node/build-aggregate-output-value.ts +57 -0
- package/src/ast/build/node/build-aligned-modifier.ts +99 -0
- package/src/ast/build/node/build-array-definition.ts +131 -0
- package/src/ast/build/node/build-array-element-access.ts +45 -0
- package/src/ast/build/node/build-base64-string-literal.ts +41 -0
- package/src/ast/build/node/build-binary-expression.ts +113 -0
- package/src/ast/build/node/build-binary-literal.ts +37 -0
- package/src/ast/build/node/build-bit-modifier.ts +86 -0
- package/src/ast/build/node/build-case-clause.ts +101 -0
- package/src/ast/build/node/build-class-declaration.ts +124 -0
- package/src/ast/build/node/build-class-definition.ts +56 -0
- package/src/ast/build/node/build-class-id-range.ts +32 -0
- package/src/ast/build/node/build-class-id.ts +19 -0
- package/src/ast/build/node/build-class-member-access.ts +27 -0
- package/src/ast/build/node/build-compound-statement.ts +33 -0
- package/src/ast/build/node/build-computed-array-definition.ts +53 -0
- package/src/ast/build/node/build-computed-elementary-type-definition.ts +100 -0
- package/src/ast/build/node/build-decimal-literal.ts +15 -0
- package/src/ast/build/node/build-default-clause.ts +76 -0
- package/src/ast/build/node/build-do-statement.ts +71 -0
- package/src/ast/build/node/build-elementary-type-definition.ts +164 -0
- package/src/ast/build/node/build-elementary-type-output-value.ts +25 -0
- package/src/ast/build/node/build-elementary-type.ts +36 -0
- package/src/ast/build/node/build-expandable-modifier.ts +68 -0
- package/src/ast/build/node/build-explicit-array-dimension.ts +37 -0
- package/src/ast/build/node/build-expression-statement.ts +31 -0
- package/src/ast/build/node/build-extended-class-id-range.ts +27 -0
- package/src/ast/build/node/build-extends-modifier.ts +41 -0
- package/src/ast/build/node/build-floating-point-literal.ts +15 -0
- package/src/ast/build/node/build-for-statement.ts +117 -0
- package/src/ast/build/node/build-hexadecimal-literal.ts +38 -0
- package/src/ast/build/node/build-identifier.ts +8 -0
- package/src/ast/build/node/build-if-statement.ts +82 -0
- package/src/ast/build/node/build-implicit-array-dimension.ts +78 -0
- package/src/ast/build/node/build-integer-literal.ts +15 -0
- package/src/ast/build/node/build-length-attribute.ts +48 -0
- package/src/ast/build/node/build-lengthof-expression.ts +45 -0
- package/src/ast/build/node/build-map-declaration.ts +110 -0
- package/src/ast/build/node/build-map-definition.ts +103 -0
- package/src/ast/build/node/build-map-entry.ts +33 -0
- package/src/ast/build/node/build-missing-error.ts +10 -0
- package/src/ast/build/node/build-multiple-character-literal.ts +65 -0
- package/src/ast/build/node/build-parameter-list.ts +50 -0
- package/src/ast/build/node/build-parameter-value-list.ts +54 -0
- package/src/ast/build/node/build-parameter.ts +47 -0
- package/src/ast/build/node/build-partial-array-dimension.ts +55 -0
- package/src/ast/build/node/build-specification.ts +24 -0
- package/src/ast/build/node/build-string-definition.ts +106 -0
- package/src/ast/build/node/build-switch-statement.ts +84 -0
- package/src/ast/build/node/build-token.ts +26 -0
- package/src/ast/build/node/build-unary-expression.ts +109 -0
- package/src/ast/build/node/build-unexpected-error.ts +14 -0
- package/src/ast/build/node/build-utf-string-literal.ts +110 -0
- package/src/ast/build/node/build-while-statement.ts +55 -0
- package/src/ast/build/util/array-dimension-kind-by-token-type-id-map.ts +167 -0
- package/src/ast/build/util/binary-operator-kind-by-token-type-id-map.ts +152 -0
- package/src/ast/build/util/build-context.ts +36 -0
- package/src/ast/build/util/class-id-kind-by-token-type-id-map.ts +160 -0
- package/src/ast/build/util/expression-kind-by-token-type-id-map.ts +168 -0
- package/src/ast/build/util/fetch-node.ts +433 -0
- package/src/ast/build/util/node-kind-by-token-type-id-map.ts +202 -0
- package/src/ast/build/util/statement-kind-by-token-type-id-map.ts +210 -0
- package/src/ast/build/util/string-literal-kind-by-token-type-id-map.ts +162 -0
- package/src/ast/build/util/token-kind-by-token-type-id-map.ts +337 -0
- package/src/ast/build-ast.ts +114 -0
- package/src/ast/node/abstract-array-definition.ts +17 -0
- package/src/ast/node/abstract-array-dimension.ts +20 -0
- package/src/ast/node/abstract-class-id.ts +13 -0
- package/src/ast/node/abstract-composite-node.ts +58 -0
- package/src/ast/node/abstract-elementary-type-definition.ts +29 -0
- package/src/ast/node/abstract-expression.ts +13 -0
- package/src/ast/node/abstract-leaf-node.ts +10 -0
- package/src/ast/node/abstract-node.ts +16 -0
- package/src/ast/node/abstract-statement.ts +13 -0
- package/src/ast/node/aggregate-output-value.ts +28 -0
- package/src/ast/node/aligned-modifier.ts +21 -0
- package/src/ast/node/array-definition.ts +44 -0
- package/src/ast/node/array-element-access.ts +24 -0
- package/src/ast/node/binary-expression.ts +28 -0
- package/src/ast/node/bit-modifier.ts +24 -0
- package/src/ast/node/case-clause.ts +30 -0
- package/src/ast/node/class-declaration.ts +39 -0
- package/src/ast/node/class-definition.ts +23 -0
- package/src/ast/node/class-id-range.ts +17 -0
- package/src/ast/node/class-id.ts +14 -0
- package/src/ast/node/class-member-access.ts +19 -0
- package/src/ast/node/compound-statement.ts +19 -0
- package/src/ast/node/computed-array-definition.ts +26 -0
- package/src/ast/node/computed-elementary-type-definition.ts +34 -0
- package/src/ast/node/default-clause.ts +26 -0
- package/src/ast/node/do-statement.ts +28 -0
- package/src/ast/node/elementary-type-definition.ts +49 -0
- package/src/ast/node/elementary-type-output-value.ts +19 -0
- package/src/ast/node/elementary-type.ts +18 -0
- package/src/ast/node/enum/array-dimension-kind.ts +11 -0
- package/src/ast/node/enum/binary-operator-kind.ts +41 -0
- package/src/ast/node/enum/class-id-kind.ts +12 -0
- package/src/ast/node/enum/elementary-type-kind.ts +13 -0
- package/src/ast/node/enum/expression-kind.ts +11 -0
- package/src/ast/node/enum/node-kind.ts +57 -0
- package/src/ast/node/enum/number-literal-kind.ts +17 -0
- package/src/ast/node/enum/statement-kind.ts +37 -0
- package/src/ast/node/enum/string-literal-kind.ts +13 -0
- package/src/ast/node/enum/string-variable-kind.ts +25 -0
- package/src/ast/node/enum/token-kind.ts +87 -0
- package/src/ast/node/expandable-modifier.ts +21 -0
- package/src/ast/node/explicit-array-dimension.ts +26 -0
- package/src/ast/node/expression-statement.ts +23 -0
- package/src/ast/node/extended-class-id-range.ts +20 -0
- package/src/ast/node/extends-modifier.ts +21 -0
- package/src/ast/node/for-statement.ts +29 -0
- package/src/ast/node/identifier.ts +12 -0
- package/src/ast/node/if-statement.ts +28 -0
- package/src/ast/node/implicit-array-dimension.ts +34 -0
- package/src/ast/node/length-attribute.ts +24 -0
- package/src/ast/node/length-of-expression.ts +21 -0
- package/src/ast/node/map-declaration.ts +34 -0
- package/src/ast/node/map-definition.ts +27 -0
- package/src/ast/node/map-entry.ts +18 -0
- package/src/ast/node/missing-error.ts +9 -0
- package/src/ast/node/number-literal.ts +18 -0
- package/src/ast/node/parameter-list.ts +25 -0
- package/src/ast/node/parameter-value-list.ts +29 -0
- package/src/ast/node/parameter.ts +20 -0
- package/src/ast/node/partial-array-dimension.ts +28 -0
- package/src/ast/node/specification.ts +21 -0
- package/src/ast/node/string-definition.ts +28 -0
- package/src/ast/node/string-literal.ts +21 -0
- package/src/ast/node/switch-statement.ts +32 -0
- package/src/ast/node/token.ts +20 -0
- package/src/ast/node/trivia.ts +13 -0
- package/src/ast/node/unary-expression.ts +31 -0
- package/src/ast/node/unexpected-error.ts +12 -0
- package/src/ast/node/while-statement.ts +26 -0
- package/src/ast/util/types.ts +138 -0
- package/src/ast/visitor/node-handler.ts +15 -0
- package/src/ast/visitor/node-visitor.ts +13 -0
- package/src/ast/visitor/traversing-visitor.ts +69 -0
- package/src/completion/completion-rules.ts +447 -0
- package/src/completion/get-potential-syntactic-tokens.ts +54 -0
- package/src/completion/get-potential-token-type-ids.ts +116 -0
- package/src/completion/hierarchical-map.ts +43 -0
- package/src/completion/rules/abstract-types.ts +174 -0
- package/src/completion/rules/aggregate-output-value-rules.ts +48 -0
- package/src/completion/rules/aligned-modifier-rules.ts +45 -0
- package/src/completion/rules/array-definition-rules.ts +87 -0
- package/src/completion/rules/array-element-access-rules.ts +22 -0
- package/src/completion/rules/assignment-expression-rules.ts +19 -0
- package/src/completion/rules/binary-expression-rules.ts +23 -0
- package/src/completion/rules/bit-modifier-rules.ts +25 -0
- package/src/completion/rules/case-clause-rules.ts +39 -0
- package/src/completion/rules/class-declaration-rules.ts +81 -0
- package/src/completion/rules/class-definition-rules.ts +28 -0
- package/src/completion/rules/class-id-range-rules.ts +17 -0
- package/src/completion/rules/class-id-rules.ts +9 -0
- package/src/completion/rules/class-member-access-rules.ts +7 -0
- package/src/completion/rules/compound-statement-rules.ts +25 -0
- package/src/completion/rules/computed-array-definition-rules.ts +25 -0
- package/src/completion/rules/computed-elementary-type-rules.ts +44 -0
- package/src/completion/rules/default-clause-rules.ts +23 -0
- package/src/completion/rules/do-statement-rules.ts +38 -0
- package/src/completion/rules/elementary-type-definition-rules.ts +62 -0
- package/src/completion/rules/elementary-type-output-value-rules.ts +13 -0
- package/src/completion/rules/elementary-type-rules.ts +18 -0
- package/src/completion/rules/expandable-modifier-rules.ts +21 -0
- package/src/completion/rules/explicit-array-dimension-rules.ts +22 -0
- package/src/completion/rules/expression-statement-rules.ts +22 -0
- package/src/completion/rules/extended-class-id-range-rules.ts +17 -0
- package/src/completion/rules/extends-modifier-rules.ts +17 -0
- package/src/completion/rules/for-statement-rules.ts +51 -0
- package/src/completion/rules/if-statement-rules.ts +42 -0
- package/src/completion/rules/implicit-array-dimension-rules.ts +21 -0
- package/src/completion/rules/length-attribute-rules.ts +19 -0
- package/src/completion/rules/lengthof-expression-rules.ts +23 -0
- package/src/completion/rules/map-declaration-rules.ts +45 -0
- package/src/completion/rules/map-definition-rules.ts +46 -0
- package/src/completion/rules/map-entry-rules.ts +17 -0
- package/src/completion/rules/parameter-list-rules.ts +21 -0
- package/src/completion/rules/parameter-rules.ts +17 -0
- package/src/completion/rules/parameter-value-list-rules.ts +27 -0
- package/src/completion/rules/partial-array-dimension-rules.ts +33 -0
- package/src/completion/rules/specification-rules.ts +37 -0
- package/src/completion/rules/string-definition-rules.ts +103 -0
- package/src/completion/rules/switch-statement-rules.ts +50 -0
- package/src/completion/rules/unary-expression-rules.ts +41 -0
- package/src/completion/rules/utf-string-literal-rules.ts +17 -0
- package/src/completion/rules/while-statement-rules.ts +38 -0
- package/src/lezer/context-tracker.ts +45 -0
- package/src/lezer/create-sdl-parser.ts +88 -0
- package/src/lezer/create-syntax-error-from-text-and-cursor.ts +110 -0
- package/src/lezer/create-syntax-error-from-text-and-position.ts +36 -0
- package/src/lezer/parser.terms.ts +129 -0
- package/src/lezer/parser.ts +63 -0
- package/src/lezer/props/fold-node-prop-source.ts +27 -0
- package/src/lezer/props/primitive-node-prop-source.ts +19 -0
- package/src/lezer/props/style-tags-node-prop-source.ts +188 -0
- package/src/lezer/props/syntactic-token-node-prop-source.ts +298 -0
- package/src/lezer/sdl-string-input.ts +46 -0
- package/src/location.ts +13 -0
- package/src/parse-helper.ts +93 -0
- package/src/prettier/prettier-plugin-sdl.ts +89 -0
- package/src/prettier/print-abstract-array-dimension.ts +84 -0
- package/src/prettier/print-abstract-class-id.ts +53 -0
- package/src/prettier/print-abstract-expression.ts +168 -0
- package/src/prettier/print-abstract-node.ts +224 -0
- package/src/prettier/print-abstract-statement.ts +124 -0
- package/src/prettier/print-aggregate-output-value.ts +35 -0
- package/src/prettier/print-aligned-modifier.ts +50 -0
- package/src/prettier/print-array-definition.ts +95 -0
- package/src/prettier/print-array-element-access.ts +14 -0
- package/src/prettier/print-bit-modifier.ts +48 -0
- package/src/prettier/print-case-clause.ts +58 -0
- package/src/prettier/print-class-declaration.ts +99 -0
- package/src/prettier/print-class-definition.ts +44 -0
- package/src/prettier/print-class-member-access.ts +13 -0
- package/src/prettier/print-computed-array-definition.ts +33 -0
- package/src/prettier/print-computed-elementary-type-definition.ts +60 -0
- package/src/prettier/print-default-clause.ts +39 -0
- package/src/prettier/print-do-statement.ts +31 -0
- package/src/prettier/print-elementary-type-definition.ts +108 -0
- package/src/prettier/print-elementary-type-output-value.ts +13 -0
- package/src/prettier/print-elementary-type.ts +28 -0
- package/src/prettier/print-expandable-modifier.ts +41 -0
- package/src/prettier/print-extends-modifier.ts +29 -0
- package/src/prettier/print-for-statement.ts +64 -0
- package/src/prettier/print-identifier.ts +10 -0
- package/src/prettier/print-if-statement.ts +76 -0
- package/src/prettier/print-length-attribute.ts +14 -0
- package/src/prettier/print-map-declaration.ts +75 -0
- package/src/prettier/print-map-definition.ts +67 -0
- package/src/prettier/print-map-entry.ts +22 -0
- package/src/prettier/print-number-literal.ts +84 -0
- package/src/prettier/print-parameter-list.ts +20 -0
- package/src/prettier/print-parameter-value-list.ts +20 -0
- package/src/prettier/print-parameter.ts +34 -0
- package/src/prettier/print-specification.ts +51 -0
- package/src/prettier/print-string-definition.ts +114 -0
- package/src/prettier/print-string-literal.ts +57 -0
- package/src/prettier/print-switch-statement.ts +46 -0
- package/src/prettier/print-token.ts +7 -0
- package/src/prettier/print-unexpected-error.ts +10 -0
- package/src/prettier/print-while-statement.ts +26 -0
- package/src/prettier/util/print-utils.ts +607 -0
- package/src/prettier/util/types.ts +40 -0
- package/src/scanner-error.ts +65 -0
- package/src/util/location-utils.ts +16 -0
- package/src/util/logger.ts +165 -0
- package/tests/analyser/create-sdl-analyser.test.ts +54 -0
- package/tests/analyser/get-sdl-analyser-test-scenarios.ts +80 -0
- package/tests/analyser/sdl-analyser-scenarios.test.ts +67 -0
- package/tests/analyser/semantic-error-scenarios.test.ts +40 -0
- package/tests/analyser/symbol-table.test.ts +188 -0
- package/tests/analyser/test-cases/array_definition.txt +50 -0
- package/tests/analyser/test-cases/class_declaration.txt +112 -0
- package/tests/analyser/test-cases/class_definition.txt +60 -0
- package/tests/analyser/test-cases/compound_statement.txt +63 -0
- package/tests/analyser/test-cases/computed_array_definition.txt +12 -0
- package/tests/analyser/test-cases/computed_elementary_type_definition.txt +39 -0
- package/tests/analyser/test-cases/do_statement.txt +16 -0
- package/tests/analyser/test-cases/elementary_type_definition.txt +58 -0
- package/tests/analyser/test-cases/expression.txt +159 -0
- package/tests/analyser/test-cases/for_statement.txt +55 -0
- package/tests/analyser/test-cases/if_statement.txt +57 -0
- package/tests/analyser/test-cases/map_declaration.txt +89 -0
- package/tests/analyser/test-cases/map_definition.txt +35 -0
- package/tests/analyser/test-cases/number_literal.txt +31 -0
- package/tests/analyser/test-cases/parameter_list.txt +16 -0
- package/tests/analyser/test-cases/scopes.txt +239 -0
- package/tests/analyser/test-cases/specification.txt +28 -0
- package/tests/analyser/test-cases/string_definition.txt +40 -0
- package/tests/analyser/test-cases/switch_statement.txt +96 -0
- package/tests/analyser/test-cases/while_statement.txt +16 -0
- package/tests/analyser/util/symbol-table-utils.test.ts +65 -0
- package/tests/ast/__snapshots__/build-ast.test.ts.snap +38897 -0
- package/tests/ast/build-ast.test.ts +463 -0
- package/tests/ast/visitor/traversing-visitor.test.ts +36 -0
- package/tests/completion/get-potential-syntactic-tokens.test.ts +89 -0
- package/tests/completion/get-potential-token-type-ids.test.ts +76 -0
- package/tests/completion/test-potential-syntactic-tokens-scenario.ts +24 -0
- package/tests/completion/test-potential-token-type-ids-scenario.ts +33 -0
- package/tests/fixtures/history-recording-node-handler.ts +232 -0
- package/tests/lezer/create-parse-error-from-text-and-position.test.ts +129 -0
- package/tests/lezer/create-sdl-parser.test.ts +15 -0
- package/tests/lezer/sdl-parser-scenarios.test.ts +24 -0
- package/tests/lezer/sdl-string-input.test.ts +12 -0
- package/tests/lezer/syntax-error-scenarios.test.ts +114 -0
- package/tests/lezer/test-cases/array_definition.txt +109 -0
- package/tests/lezer/test-cases/class_declaration.txt +141 -0
- package/tests/lezer/test-cases/class_definition.txt +89 -0
- package/tests/lezer/test-cases/comment.txt +335 -0
- package/tests/lezer/test-cases/compound_statement.txt +109 -0
- package/tests/lezer/test-cases/computed_array_definition.txt +33 -0
- package/tests/lezer/test-cases/computed_elementary_type_definition.txt +59 -0
- package/tests/lezer/test-cases/do_statement.txt +48 -0
- package/tests/lezer/test-cases/elementary_type_definition.txt +158 -0
- package/tests/lezer/test-cases/expression.txt +1203 -0
- package/tests/lezer/test-cases/for_statement.txt +183 -0
- package/tests/lezer/test-cases/if_statement.txt +183 -0
- package/tests/lezer/test-cases/invalid.txt +97 -0
- package/tests/lezer/test-cases/map_declaration.txt +152 -0
- package/tests/lezer/test-cases/map_definition.txt +59 -0
- package/tests/lezer/test-cases/number_literal.txt +273 -0
- package/tests/lezer/test-cases/specification.txt +38 -0
- package/tests/lezer/test-cases/string_definition.txt +263 -0
- package/tests/lezer/test-cases/string_literal.txt +303 -0
- package/tests/lezer/test-cases/switch_statement.txt +407 -0
- package/tests/lezer/test-cases/while_statement.txt +45 -0
- package/tests/parse-helper.test.ts +361 -0
- package/tests/prettier/__snapshots__/prettier-plugin-sdl.test.ts.snap +127 -0
- package/tests/prettier/prettier-plugin-sdl.test.ts +58 -0
- package/tests/prettier/print-array.test.ts +29 -0
- package/tests/prettier/print-class.test.ts +15 -0
- package/tests/prettier/print-do.test.ts +25 -0
- package/tests/prettier/print-elementary-type.test.ts +62 -0
- package/tests/prettier/print-error.test.ts +40 -0
- package/tests/prettier/print-expression.test.ts +17 -0
- package/tests/prettier/print-for.test.ts +23 -0
- package/tests/prettier/print-if.test.ts +71 -0
- package/tests/prettier/print-number-literal.test.ts +28 -0
- package/tests/prettier/print-specification.test.ts +54 -0
- package/tests/prettier/print-string.test.ts +36 -0
- package/tests/prettier/print-switch.test.ts +69 -0
- package/tests/prettier/print-while.test.ts +23 -0
- package/tests/prettier/test-prettier-scenario.ts +41 -0
- package/tests/prettier/util/print-utils.test.ts +665 -0
- package/tests/prettier/util/types.test.ts +38 -0
- package/tests/sample-specifications/invalid.sdl +24 -0
- package/tests/sample-specifications/prettified-invalid.sdl +28 -0
- package/tests/sample-specifications/prettified-various-elements-narrow.sdl +97 -0
- package/tests/sample-specifications/prettified-various-elements.sdl +90 -0
- package/tests/sample-specifications/sample.sdl +24 -0
- package/tests/sample-specifications/various-elements.sdl +88 -0
- package/tests/util/logger.test.ts +36 -0
- 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
|
+
}
|