semantifold 0.1.1 → 0.3.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/README.md +42 -10
- package/build/index.d.ts +32 -3
- package/build/index.d.ts.map +1 -1
- package/build/index.js +99 -4
- package/build/src/acceptance.d.ts +32 -0
- package/build/src/acceptance.d.ts.map +1 -0
- package/build/src/acceptance.js +358 -0
- package/build/src/array.d.ts +7 -0
- package/build/src/array.d.ts.map +1 -0
- package/build/src/array.js +18 -0
- package/build/src/artifact-path.d.ts +13 -0
- package/build/src/artifact-path.d.ts.map +1 -0
- package/build/src/artifact-path.js +30 -0
- package/build/src/artifacts.d.ts +7 -0
- package/build/src/artifacts.d.ts.map +1 -0
- package/build/src/artifacts.js +389 -0
- package/build/src/backends/c-runtime.d.ts +3 -0
- package/build/src/backends/c-runtime.d.ts.map +1 -0
- package/build/src/backends/c-runtime.js +151 -0
- package/build/src/backends/c-validation.d.ts +12 -0
- package/build/src/backends/c-validation.d.ts.map +1 -0
- package/build/src/backends/c-validation.js +85 -0
- package/build/src/backends/c.d.ts +31 -0
- package/build/src/backends/c.d.ts.map +1 -0
- package/build/src/backends/c.js +308 -0
- package/build/src/backends/cpp-runtime.d.ts +3 -0
- package/build/src/backends/cpp-runtime.d.ts.map +1 -0
- package/build/src/backends/cpp-runtime.js +99 -0
- package/build/src/backends/cpp-validation.d.ts +9 -0
- package/build/src/backends/cpp-validation.d.ts.map +1 -0
- package/build/src/backends/cpp-validation.js +74 -0
- package/build/src/backends/cpp.d.ts +16 -0
- package/build/src/backends/cpp.d.ts.map +1 -0
- package/build/src/backends/cpp.js +285 -0
- package/build/src/backends/csharp.d.ts +20 -0
- package/build/src/backends/csharp.d.ts.map +1 -0
- package/build/src/backends/csharp.js +259 -0
- package/build/src/backends/go.d.ts +20 -0
- package/build/src/backends/go.d.ts.map +1 -0
- package/build/src/backends/go.js +374 -0
- package/build/src/backends/identifiers.d.ts +12 -0
- package/build/src/backends/identifiers.d.ts.map +1 -1
- package/build/src/backends/identifiers.js +79 -2
- package/build/src/backends/index.d.ts.map +1 -1
- package/build/src/backends/index.js +27 -37
- package/build/src/backends/native-validation.d.ts +9 -0
- package/build/src/backends/native-validation.d.ts.map +1 -0
- package/build/src/backends/native-validation.js +59 -0
- package/build/src/backends/ordered-expressions.d.ts +74 -0
- package/build/src/backends/ordered-expressions.d.ts.map +1 -0
- package/build/src/backends/ordered-expressions.js +159 -0
- package/build/src/backends/python.d.ts +8 -0
- package/build/src/backends/python.d.ts.map +1 -0
- package/build/src/backends/python.js +162 -0
- package/build/src/backends/scalars.d.ts.map +1 -1
- package/build/src/backends/scalars.js +8 -2
- package/build/src/backends/shared.d.ts.map +1 -1
- package/build/src/backends/shared.js +67 -19
- package/build/src/binary-mapping.d.ts +32 -0
- package/build/src/binary-mapping.d.ts.map +1 -0
- package/build/src/binary-mapping.js +285 -0
- package/build/src/diagnostic.d.ts +36 -4
- package/build/src/diagnostic.d.ts.map +1 -1
- package/build/src/diagnostic.js +42 -3
- package/build/src/frontends/c-parser.d.ts +20 -0
- package/build/src/frontends/c-parser.d.ts.map +1 -0
- package/build/src/frontends/c-parser.js +14 -0
- package/build/src/frontends/c.d.ts +220 -0
- package/build/src/frontends/c.d.ts.map +1 -0
- package/build/src/frontends/c.js +750 -0
- package/build/src/frontends/cpp-parser.d.ts +11 -0
- package/build/src/frontends/cpp-parser.d.ts.map +1 -0
- package/build/src/frontends/cpp-parser.js +15 -0
- package/build/src/frontends/cpp.d.ts +227 -0
- package/build/src/frontends/cpp.d.ts.map +1 -0
- package/build/src/frontends/cpp.js +784 -0
- package/build/src/frontends/csharp.d.ts +14 -0
- package/build/src/frontends/csharp.d.ts.map +1 -0
- package/build/src/frontends/csharp.js +708 -0
- package/build/src/frontends/go.d.ts +15 -0
- package/build/src/frontends/go.d.ts.map +1 -0
- package/build/src/frontends/go.js +712 -0
- package/build/src/frontends/index.d.ts.map +1 -1
- package/build/src/frontends/index.js +5 -23
- package/build/src/frontends/python.d.ts +14 -0
- package/build/src/frontends/python.d.ts.map +1 -0
- package/build/src/frontends/python.js +615 -0
- package/build/src/frontends/scalars.d.ts.map +1 -1
- package/build/src/frontends/scalars.js +21 -1
- package/build/src/language-registry.d.ts +113 -0
- package/build/src/language-registry.d.ts.map +1 -0
- package/build/src/language-registry.js +421 -0
- package/build/src/mapping.js +3 -2
- package/build/src/semantic/location.d.ts +7 -0
- package/build/src/semantic/location.d.ts.map +1 -1
- package/build/src/semantic/location.js +10 -1
- package/build/src/semantic/provenance.js +3 -3
- package/build/src/semantic/types.d.ts +399 -2
- package/build/src/semantic/types.d.ts.map +1 -1
- package/build/src/semantic/types.js +110 -2
- package/build/src/subprocess.d.ts +38 -0
- package/build/src/subprocess.d.ts.map +1 -0
- package/build/src/subprocess.js +233 -0
- package/build/src/timeout.d.ts +8 -0
- package/build/src/timeout.d.ts.map +1 -0
- package/build/src/timeout.js +11 -0
- package/build/src/toolchains.d.ts +107 -0
- package/build/src/toolchains.d.ts.map +1 -0
- package/build/src/toolchains.js +417 -0
- package/docs/architecture.md +23 -5
- package/docs/c.md +60 -0
- package/docs/cpp.md +61 -0
- package/docs/goals.md +4 -2
- package/docs/language-support.md +46 -6
- package/docs/parser-qualification.md +219 -0
- package/docs/plans/2026-09-05-standard-library-portability.md +46 -0
- package/docs/source-maps.md +38 -5
- package/docs/standard-library-portability.md +190 -0
- package/docs/testing.md +131 -3
- package/index.js +109 -4
- package/node_modules/node-addon-api/LICENSE.md +9 -0
- package/node_modules/node-addon-api/README.md +95 -0
- package/node_modules/node-addon-api/common.gypi +21 -0
- package/node_modules/node-addon-api/except.gypi +25 -0
- package/node_modules/node-addon-api/index.js +14 -0
- package/node_modules/node-addon-api/napi-inl.deprecated.h +186 -0
- package/node_modules/node-addon-api/napi-inl.h +7250 -0
- package/node_modules/node-addon-api/napi.h +3463 -0
- package/node_modules/node-addon-api/node_addon_api.gyp +42 -0
- package/node_modules/node-addon-api/node_api.gyp +9 -0
- package/node_modules/node-addon-api/noexcept.gypi +26 -0
- package/node_modules/node-addon-api/nothing.c +0 -0
- package/node_modules/node-addon-api/package-support.json +21 -0
- package/node_modules/node-addon-api/package.json +481 -0
- package/node_modules/node-addon-api/tools/README.md +73 -0
- package/node_modules/node-addon-api/tools/check-napi.js +99 -0
- package/node_modules/node-addon-api/tools/clang-format.js +71 -0
- package/node_modules/node-addon-api/tools/conversion.js +301 -0
- package/node_modules/node-gyp-build/LICENSE +21 -0
- package/node_modules/node-gyp-build/README.md +58 -0
- package/node_modules/node-gyp-build/SECURITY.md +5 -0
- package/node_modules/node-gyp-build/bin.js +84 -0
- package/node_modules/node-gyp-build/build-test.js +19 -0
- package/node_modules/node-gyp-build/index.js +6 -0
- package/node_modules/node-gyp-build/node-gyp-build.js +207 -0
- package/node_modules/node-gyp-build/optional.js +7 -0
- package/node_modules/node-gyp-build/package.json +43 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/LICENSE +15 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/README.md +7 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/LICENSE +21 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/README.md +90 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/binding.gyp +79 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/index.js +895 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/package.json +62 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/prebuilds/darwin-arm64/tree-sitter.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/prebuilds/darwin-x64/tree-sitter.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/prebuilds/linux-x64/tree-sitter.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/prebuilds/win32-x64/tree-sitter.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/addon_data.h +47 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/binding.cc +35 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/conversions.cc +140 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/conversions.h +22 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/language.cc +106 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/language.h +17 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/logger.cc +70 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/logger.h +19 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/lookaheaditerator.cc +122 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/lookaheaditerator.h +33 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/node.cc +1056 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/node.h +30 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/parser.cc +298 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/parser.h +35 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/query.cc +383 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/query.h +39 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/tree.cc +307 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/tree.h +45 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/tree_cursor.cc +213 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/tree_cursor.h +52 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/tree-sitter.d.ts +211 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/include/tree_sitter/api.h +1266 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/alloc.c +48 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/alloc.h +41 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/array.h +290 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/atomic.h +68 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/clock.h +146 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/error_costs.h +11 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/get_changed_ranges.c +501 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/get_changed_ranges.h +36 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/host.h +21 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/language.c +221 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/language.h +299 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/length.h +52 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lexer.c +419 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lexer.h +49 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lib.c +14 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/node.c +774 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/parser.c +2151 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/parser.h +230 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/point.h +62 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/query.c +4134 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/reduce_action.h +34 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/reusable_node.h +95 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/stack.c +899 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/stack.h +133 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/subtree.c +1060 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/subtree.h +382 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree.c +165 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree.h +31 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree_cursor.c +714 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree_cursor.h +48 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/ICU_SHA +1 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/LICENSE +414 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/README.md +29 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/ptypes.h +1 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/umachine.h +448 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/urename.h +1 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf.h +1 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf16.h +733 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf8.h +881 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode.h +50 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/stdlib-symbols.txt +23 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/stdlib.c +109 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/wasm-stdlib.h +1294 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm_store.c +1823 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm_store.h +31 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/LICENSE +21 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/README.md +18 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/binding.gyp +29 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/bindings/node/binding.cc +20 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/bindings/node/binding_test.js +9 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/bindings/node/index.d.ts +28 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/bindings/node/index.js +11 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/grammar.js +1470 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/package.json +60 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/prebuilds/darwin-arm64/tree-sitter-c.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/prebuilds/darwin-x64/tree-sitter-c.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/prebuilds/linux-arm64/tree-sitter-c.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/prebuilds/linux-x64/tree-sitter-c.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/prebuilds/win32-arm64/tree-sitter-c.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/prebuilds/win32-x64/tree-sitter-c.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/queries/highlights.scm +81 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/queries/tags.scm +9 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/src/grammar.json +9735 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/src/node-types.json +4614 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/src/parser.c +119615 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/src/tree_sitter/alloc.h +54 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/src/tree_sitter/array.h +290 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/src/tree_sitter/parser.h +266 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/tree-sitter-c.wasm +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/tree-sitter.json +43 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/LICENSE +21 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/README.md +22 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/binding.gyp +30 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/bindings/node/binding.cc +20 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/bindings/node/binding_test.js +9 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/bindings/node/index.d.ts +28 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/bindings/node/index.js +11 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/grammar.js +1436 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/package.json +61 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/prebuilds/darwin-arm64/tree-sitter-cpp.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/prebuilds/darwin-x64/tree-sitter-cpp.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/prebuilds/linux-arm64/tree-sitter-cpp.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/prebuilds/linux-x64/tree-sitter-cpp.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/prebuilds/win32-arm64/tree-sitter-cpp.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/prebuilds/win32-x64/tree-sitter-cpp.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/queries/highlights.scm +70 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/queries/injections.scm +3 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/queries/tags.scm +15 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/src/grammar.json +17084 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/src/node-types.json +7997 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/src/parser.c +530368 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/src/scanner.c +148 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/src/tree_sitter/alloc.h +54 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/src/tree_sitter/array.h +290 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/src/tree_sitter/parser.h +266 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/tree-sitter-cpp.wasm +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/tree-sitter.json +55 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/package.json +22 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/src/c.js +152 -0
- package/node_modules/tree-sitter/LICENSE +21 -0
- package/node_modules/tree-sitter/README.md +128 -0
- package/node_modules/tree-sitter/binding.gyp +88 -0
- package/node_modules/tree-sitter/index.js +950 -0
- package/node_modules/tree-sitter/package.json +76 -0
- package/node_modules/tree-sitter/prebuilds/darwin-arm64/tree-sitter.node +0 -0
- package/node_modules/tree-sitter/prebuilds/darwin-x64/tree-sitter.node +0 -0
- package/node_modules/tree-sitter/prebuilds/linux-arm64/tree-sitter.node +0 -0
- package/node_modules/tree-sitter/prebuilds/linux-x64/tree-sitter.node +0 -0
- package/node_modules/tree-sitter/prebuilds/win32-arm64/tree-sitter.node +0 -0
- package/node_modules/tree-sitter/prebuilds/win32-x64/tree-sitter.node +0 -0
- package/node_modules/tree-sitter/src/addon_data.h +47 -0
- package/node_modules/tree-sitter/src/binding.cc +35 -0
- package/node_modules/tree-sitter/src/conversions.cc +140 -0
- package/node_modules/tree-sitter/src/conversions.h +22 -0
- package/node_modules/tree-sitter/src/language.cc +105 -0
- package/node_modules/tree-sitter/src/language.h +17 -0
- package/node_modules/tree-sitter/src/logger.cc +70 -0
- package/node_modules/tree-sitter/src/logger.h +19 -0
- package/node_modules/tree-sitter/src/lookaheaditerator.cc +122 -0
- package/node_modules/tree-sitter/src/lookaheaditerator.h +33 -0
- package/node_modules/tree-sitter/src/node.cc +1088 -0
- package/node_modules/tree-sitter/src/node.h +30 -0
- package/node_modules/tree-sitter/src/parser.cc +332 -0
- package/node_modules/tree-sitter/src/parser.h +35 -0
- package/node_modules/tree-sitter/src/query.cc +425 -0
- package/node_modules/tree-sitter/src/query.h +40 -0
- package/node_modules/tree-sitter/src/tree.cc +316 -0
- package/node_modules/tree-sitter/src/tree.h +45 -0
- package/node_modules/tree-sitter/src/tree_cursor.cc +213 -0
- package/node_modules/tree-sitter/src/tree_cursor.h +52 -0
- package/node_modules/tree-sitter/tree-sitter.d.ts +1083 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/include/tree_sitter/api.h +1478 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/alloc.c +48 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/alloc.h +41 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/array.h +291 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/atomic.h +68 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/clock.h +146 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/error_costs.h +11 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/get_changed_ranges.c +523 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/get_changed_ranges.h +36 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/host.h +21 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/language.c +293 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/language.h +293 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/length.h +52 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lexer.c +483 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lexer.h +54 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lib.c +12 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/node.c +875 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/parser.c +2297 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/parser.h +286 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/point.h +48 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/portable/endian.h +241 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/query.c +4347 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/reduce_action.h +34 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/reusable_node.h +95 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/stack.c +912 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/stack.h +133 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/subtree.c +1034 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/subtree.h +399 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree.c +170 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree.h +31 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree_cursor.c +716 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree_cursor.h +48 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/ts_assert.h +11 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/ICU_SHA +1 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/LICENSE +414 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/README.md +29 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/ptypes.h +1 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/umachine.h +448 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/urename.h +1 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf.h +1 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf16.h +733 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf8.h +881 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode.h +75 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/stdlib-symbols.txt +24 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/stdlib.c +137 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/wasm-stdlib.h +1314 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm_store.c +1937 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm_store.h +31 -0
- package/package.json +24 -6
- package/src/acceptance.js +380 -0
- package/src/array.js +19 -0
- package/src/artifact-path.js +34 -0
- package/src/artifacts.js +420 -0
- package/src/backends/c-runtime.js +151 -0
- package/src/backends/c-validation.js +83 -0
- package/src/backends/c.js +308 -0
- package/src/backends/cpp-runtime.js +99 -0
- package/src/backends/cpp-validation.js +70 -0
- package/src/backends/cpp.js +285 -0
- package/src/backends/csharp.js +270 -0
- package/src/backends/go.js +383 -0
- package/src/backends/identifiers.js +80 -1
- package/src/backends/index.js +23 -32
- package/src/backends/native-validation.js +64 -0
- package/src/backends/ordered-expressions.js +161 -0
- package/src/backends/python.js +175 -0
- package/src/backends/scalars.js +8 -1
- package/src/backends/shared.js +64 -17
- package/src/binary-mapping.js +305 -0
- package/src/diagnostic.js +34 -2
- package/src/frontends/c-parser.js +17 -0
- package/src/frontends/c.js +780 -0
- package/src/frontends/cpp-parser.js +18 -0
- package/src/frontends/cpp.js +816 -0
- package/src/frontends/csharp.js +759 -0
- package/src/frontends/go.js +770 -0
- package/src/frontends/index.js +5 -20
- package/src/frontends/python.js +689 -0
- package/src/frontends/scalars.js +20 -0
- package/src/language-registry.js +454 -0
- package/src/mapping.js +2 -1
- package/src/semantic/location.js +10 -0
- package/src/semantic/provenance.js +2 -2
- package/src/semantic/types.js +124 -1
- package/src/subprocess.js +232 -0
- package/src/timeout.js +12 -0
- package/src/toolchains.js +448 -0
- package/tsconfig.json +1 -0
|
@@ -0,0 +1,689 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import Parser from "tree-sitter"
|
|
4
|
+
import PythonLanguage from "tree-sitter-python"
|
|
5
|
+
import {missingType, parseFailure, SemantifoldDiagnostic, unsupportedSyntax} from "../diagnostic.js"
|
|
6
|
+
import {locationFromOffsets, moduleLocation, utf8ByteOffsetToUtf16Offset} from "../semantic/location.js"
|
|
7
|
+
import {withAdaptedOperation} from "../semantic/operators.js"
|
|
8
|
+
import {withParserRanges} from "../semantic/provenance.js"
|
|
9
|
+
import {hasOnlyUnicodeScalars} from "../semantic/scalars.js"
|
|
10
|
+
import {requireSourceScalarType} from "./scalars.js"
|
|
11
|
+
|
|
12
|
+
const parser = new Parser()
|
|
13
|
+
|
|
14
|
+
parser.setLanguage(/** @type {import("tree-sitter").Language} */ (/** @type {unknown} */ (PythonLanguage)))
|
|
15
|
+
|
|
16
|
+
const immutableMarker = "# @semantifold-immutable"
|
|
17
|
+
const pythonReservedIdentifiers = new Set([
|
|
18
|
+
"False", "None", "True", "and", "as", "assert", "async", "await", "break", "case", "class", "continue",
|
|
19
|
+
"def", "del", "elif", "else", "except", "exec", "finally", "for", "from", "global", "if", "import", "in",
|
|
20
|
+
"is", "lambda", "match", "nonlocal", "not", "or", "pass", "print", "raise", "return", "try", "type",
|
|
21
|
+
"while", "with", "yield", "_", "__debug__", "int", "bool", "str"
|
|
22
|
+
])
|
|
23
|
+
const binaryOperations = new Map([
|
|
24
|
+
["+", "Add"],
|
|
25
|
+
["-", "Subtract"],
|
|
26
|
+
["*", "Multiply"]
|
|
27
|
+
])
|
|
28
|
+
const comparisonOperations = new Map([
|
|
29
|
+
["==", "Equal"],
|
|
30
|
+
["!=", "NotEqual"],
|
|
31
|
+
["<", "LessThan"],
|
|
32
|
+
["<=", "LessThanOrEqual"],
|
|
33
|
+
[">", "GreaterThan"],
|
|
34
|
+
[">=", "GreaterThanOrEqual"]
|
|
35
|
+
])
|
|
36
|
+
|
|
37
|
+
/** @typedef {{comments: import("tree-sitter").SyntaxNode[], usedImmutableMarkers: Set<import("tree-sitter").SyntaxNode>}} PythonContext */
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Routes the binding's UTF-16 index through the shared UTF-8 byte converter.
|
|
41
|
+
* node-tree-sitter parses JavaScript strings as UTF-16LE and exposes code-unit
|
|
42
|
+
* indexes even though the grammar's native coordinate contract is byte-based.
|
|
43
|
+
* @param {string} source - Complete source.
|
|
44
|
+
* @param {number} index - Binding UTF-16 index.
|
|
45
|
+
* @returns {number} Verified UTF-16 offset.
|
|
46
|
+
*/
|
|
47
|
+
function bindingIndexToUtf16Offset(source, index) {
|
|
48
|
+
if (!Number.isInteger(index) || index < 0 || index > source.length ||
|
|
49
|
+
index > 0 && index < source.length && /[\uD800-\uDBFF]/u.test(source[index - 1]) && /[\uDC00-\uDFFF]/u.test(source[index])) {
|
|
50
|
+
throw new RangeError(`Invalid Tree-sitter source index: ${index}`)
|
|
51
|
+
}
|
|
52
|
+
const byteOffset = new TextEncoder().encode(source.slice(0, index)).length
|
|
53
|
+
|
|
54
|
+
return utf8ByteOffsetToUtf16Offset(source, byteOffset)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Finds the first unpaired UTF-16 surrogate.
|
|
59
|
+
* @param {string} source - Complete source.
|
|
60
|
+
* @returns {number} Invalid offset, or -1.
|
|
61
|
+
*/
|
|
62
|
+
function firstLoneSurrogateOffset(source) {
|
|
63
|
+
for (let index = 0; index < source.length; index += 1) {
|
|
64
|
+
const unit = source.charCodeAt(index)
|
|
65
|
+
|
|
66
|
+
if (unit >= 0xD800 && unit <= 0xDBFF) {
|
|
67
|
+
const next = source.charCodeAt(index + 1)
|
|
68
|
+
|
|
69
|
+
if (next >= 0xDC00 && next <= 0xDFFF) index += 1
|
|
70
|
+
else return index
|
|
71
|
+
} else if (unit >= 0xDC00 && unit <= 0xDFFF) return index
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return -1
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Converts a Tree-sitter byte range into Semantifold's UTF-16 coordinates.
|
|
79
|
+
* @param {import("tree-sitter").SyntaxNode} node - Parser node.
|
|
80
|
+
* @param {string} filename - Source filename.
|
|
81
|
+
* @param {string} source - Complete source.
|
|
82
|
+
* @returns {import("../semantic/types.js").SourceLocation} Exact location.
|
|
83
|
+
*/
|
|
84
|
+
function nodeLocation(node, filename, source) {
|
|
85
|
+
return locationFromOffsets(
|
|
86
|
+
filename,
|
|
87
|
+
source,
|
|
88
|
+
bindingIndexToUtf16Offset(source, node.startIndex),
|
|
89
|
+
bindingIndexToUtf16Offset(source, node.endIndex)
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Requires one parser field.
|
|
95
|
+
* @param {import("tree-sitter").SyntaxNode} node - Field owner.
|
|
96
|
+
* @param {string} field - Grammar field name.
|
|
97
|
+
* @param {string} filename - Source filename.
|
|
98
|
+
* @param {string} source - Complete source.
|
|
99
|
+
* @returns {import("tree-sitter").SyntaxNode} Field node.
|
|
100
|
+
*/
|
|
101
|
+
function requiredField(node, field, filename, source) {
|
|
102
|
+
const child = node.childForFieldName(field)
|
|
103
|
+
|
|
104
|
+
if (!child) return unsupportedSyntax("python", `${node.type} without ${field}`, nodeLocation(node, filename, source))
|
|
105
|
+
|
|
106
|
+
return child
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Validates every named and anonymous parser child and rejects recovery.
|
|
111
|
+
* @param {import("tree-sitter").SyntaxNode} node - Current parser node.
|
|
112
|
+
* @param {string} filename - Source filename.
|
|
113
|
+
* @param {string} source - Complete source.
|
|
114
|
+
* @returns {void}
|
|
115
|
+
*/
|
|
116
|
+
function validateParserTree(node, filename, source) {
|
|
117
|
+
if (node.isError || node.isMissing) {
|
|
118
|
+
throw new SemantifoldDiagnostic({
|
|
119
|
+
code: "PARSE_ERROR",
|
|
120
|
+
language: "python",
|
|
121
|
+
location: nodeLocation(node, filename, source),
|
|
122
|
+
message: `Tree-sitter exposed ${node.isMissing ? "a missing" : "an error"} recovery node '${node.type}'.`
|
|
123
|
+
})
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
for (let index = 0; index < node.childCount; index += 1) {
|
|
127
|
+
const child = node.child(index)
|
|
128
|
+
|
|
129
|
+
if (!child) throw new Error(`Tree-sitter omitted child ${index} of ${node.type}.`)
|
|
130
|
+
validateParserTree(child, filename, source)
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Rejects Python identifiers that cannot safely participate in the exact profile.
|
|
136
|
+
* @param {import("tree-sitter").SyntaxNode} node - Identifier node.
|
|
137
|
+
* @param {string} role - Diagnostic role.
|
|
138
|
+
* @param {string} filename - Source filename.
|
|
139
|
+
* @param {string} source - Complete source.
|
|
140
|
+
* @returns {string} Accepted name.
|
|
141
|
+
*/
|
|
142
|
+
function identifier(node, role, filename, source) {
|
|
143
|
+
const name = node.text
|
|
144
|
+
|
|
145
|
+
if (node.type != "identifier" || pythonReservedIdentifiers.has(name) || name.normalize("NFKC") != name) {
|
|
146
|
+
return unsupportedSyntax("python", `${role} identifier '${name}'`, nodeLocation(node, filename, source))
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return name
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Converts one exact int/bool/str annotation.
|
|
154
|
+
* @param {import("tree-sitter").SyntaxNode | null} node - Type node, if present.
|
|
155
|
+
* @param {string} subject - Typed subject.
|
|
156
|
+
* @param {import("../semantic/types.js").SourceLocation} ownerLocation - Owning declaration.
|
|
157
|
+
* @param {string} filename - Source filename.
|
|
158
|
+
* @param {string} source - Complete source.
|
|
159
|
+
* @returns {import("../semantic/types.js").TypeReference} Semantic type.
|
|
160
|
+
*/
|
|
161
|
+
function convertType(node, subject, ownerLocation, filename, source) {
|
|
162
|
+
if (!node) return missingType("python", subject, ownerLocation)
|
|
163
|
+
const typeLocation = nodeLocation(node, filename, source)
|
|
164
|
+
const children = node.namedChildren.filter((child) => child.type != "comment")
|
|
165
|
+
|
|
166
|
+
if (node.type != "type" || children.length != 1 || children[0].type != "identifier" ||
|
|
167
|
+
!["int", "bool", "str"].includes(children[0].text) || node.text != children[0].text) {
|
|
168
|
+
return unsupportedSyntax("python", "unsupported scalar annotation", typeLocation)
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return requireSourceScalarType("python", children[0].text, subject, ownerLocation, typeLocation)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Finds exactly one anonymous operator token directly owned by a parser node.
|
|
176
|
+
* @param {import("tree-sitter").SyntaxNode} node - Operation node.
|
|
177
|
+
* @param {Set<string>} spellings - Accepted spellings.
|
|
178
|
+
* @param {string} filename - Source filename.
|
|
179
|
+
* @param {string} source - Complete source.
|
|
180
|
+
* @returns {import("tree-sitter").SyntaxNode} Operator token.
|
|
181
|
+
*/
|
|
182
|
+
function operatorToken(node, spellings, filename, source) {
|
|
183
|
+
const tokens = node.children.filter((child) => !child.isNamed && spellings.has(child.type))
|
|
184
|
+
|
|
185
|
+
if (tokens.length != 1) return unsupportedSyntax("python", `${node.type} operator`, nodeLocation(node, filename, source))
|
|
186
|
+
|
|
187
|
+
return tokens[0]
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Converts one supported Python expression.
|
|
192
|
+
* @param {import("tree-sitter").SyntaxNode} node - Expression node.
|
|
193
|
+
* @param {string} filename - Source filename.
|
|
194
|
+
* @param {string} source - Complete source.
|
|
195
|
+
* @returns {import("../semantic/types.js").Expression} Semantic expression.
|
|
196
|
+
*/
|
|
197
|
+
function convertExpression(node, filename, source) {
|
|
198
|
+
const location = nodeLocation(node, filename, source)
|
|
199
|
+
|
|
200
|
+
if (node.type == "parenthesized_expression") {
|
|
201
|
+
const expressions = node.namedChildren.filter((child) => child.type != "comment")
|
|
202
|
+
|
|
203
|
+
if (expressions.length != 1) return unsupportedSyntax("python", node.type, location)
|
|
204
|
+
|
|
205
|
+
return convertExpression(expressions[0], filename, source)
|
|
206
|
+
}
|
|
207
|
+
if (node.type == "identifier") {
|
|
208
|
+
const name = identifier(node, "reference", filename, source)
|
|
209
|
+
|
|
210
|
+
return withParserRanges({kind: /** @type {const} */ ("IdentifierExpression"), location, name}, {name: location})
|
|
211
|
+
}
|
|
212
|
+
if (node.type == "integer") {
|
|
213
|
+
let value
|
|
214
|
+
|
|
215
|
+
try {
|
|
216
|
+
value = Number(BigInt(node.text.replaceAll("_", "")))
|
|
217
|
+
} catch {
|
|
218
|
+
return unsupportedSyntax("python", "integer literal", location)
|
|
219
|
+
}
|
|
220
|
+
if (!Number.isSafeInteger(value)) return unsupportedSyntax("python", "non-safe integer literal", location)
|
|
221
|
+
|
|
222
|
+
return withParserRanges({kind: /** @type {const} */ ("IntegerLiteral"), location, value}, {literal: location})
|
|
223
|
+
}
|
|
224
|
+
if (node.type == "true" || node.type == "false") {
|
|
225
|
+
return withParserRanges({kind: /** @type {const} */ ("BooleanLiteral"), location, value: node.type == "true"}, {literal: location})
|
|
226
|
+
}
|
|
227
|
+
if (node.type == "string") {
|
|
228
|
+
return withParserRanges({kind: /** @type {const} */ ("StringLiteral"), location, value: decodeString(node, filename, source)}, {
|
|
229
|
+
literal: location
|
|
230
|
+
})
|
|
231
|
+
}
|
|
232
|
+
if (node.type == "concatenated_string") return unsupportedSyntax("python", "implicit string concatenation", location)
|
|
233
|
+
if (node.type == "unary_operator") {
|
|
234
|
+
const operandNode = requiredField(node, "argument", filename, source)
|
|
235
|
+
const operator = operatorToken(node, new Set(["-"]), filename, source)
|
|
236
|
+
const semantic = withAdaptedOperation(withParserRanges({
|
|
237
|
+
kind: "UnaryExpression",
|
|
238
|
+
location,
|
|
239
|
+
operand: convertExpression(operandNode, filename, source)
|
|
240
|
+
}, {operator: nodeLocation(operator, filename, source)}), "Negate")
|
|
241
|
+
|
|
242
|
+
return /** @type {import("../semantic/types.js").Expression} */ (/** @type {unknown} */ (semantic))
|
|
243
|
+
}
|
|
244
|
+
if (node.type == "not_operator") {
|
|
245
|
+
const operandNode = requiredField(node, "argument", filename, source)
|
|
246
|
+
const operator = operatorToken(node, new Set(["not"]), filename, source)
|
|
247
|
+
const semantic = withAdaptedOperation(withParserRanges({
|
|
248
|
+
kind: "UnaryExpression",
|
|
249
|
+
location,
|
|
250
|
+
operand: convertExpression(operandNode, filename, source)
|
|
251
|
+
}, {operator: nodeLocation(operator, filename, source)}), "Not")
|
|
252
|
+
|
|
253
|
+
return /** @type {import("../semantic/types.js").Expression} */ (/** @type {unknown} */ (semantic))
|
|
254
|
+
}
|
|
255
|
+
if (node.type == "binary_operator" || node.type == "comparison_operator" || node.type == "boolean_operator") {
|
|
256
|
+
const expressionChildren = node.namedChildren.filter((child) => child.type != "comment")
|
|
257
|
+
const leftNode = node.childForFieldName("left") ?? expressionChildren[0]
|
|
258
|
+
const rightNode = node.childForFieldName("right") ?? expressionChildren[1]
|
|
259
|
+
|
|
260
|
+
if (!leftNode || !rightNode) return unsupportedSyntax("python", node.type, location)
|
|
261
|
+
const operations = node.type == "binary_operator" ? binaryOperations : node.type == "comparison_operator"
|
|
262
|
+
? comparisonOperations : new Map([["and", "And"], ["or", "Or"]])
|
|
263
|
+
const operator = operatorToken(node, new Set(operations.keys()), filename, source)
|
|
264
|
+
const adapted = operations.get(operator.type)
|
|
265
|
+
|
|
266
|
+
if (!adapted || expressionChildren.length != 2) {
|
|
267
|
+
return unsupportedSyntax("python", node.type, location)
|
|
268
|
+
}
|
|
269
|
+
const semantic = withAdaptedOperation(withParserRanges({
|
|
270
|
+
kind: "BinaryExpression",
|
|
271
|
+
left: convertExpression(leftNode, filename, source),
|
|
272
|
+
location,
|
|
273
|
+
right: convertExpression(rightNode, filename, source)
|
|
274
|
+
}, {operator: nodeLocation(operator, filename, source)}), /** @type {import("../semantic/operators.js").AdaptedOperation} */ (adapted))
|
|
275
|
+
|
|
276
|
+
return /** @type {import("../semantic/types.js").Expression} */ (/** @type {unknown} */ (semantic))
|
|
277
|
+
}
|
|
278
|
+
if (node.type == "call") {
|
|
279
|
+
const calleeNode = requiredField(node, "function", filename, source)
|
|
280
|
+
const argumentsNode = requiredField(node, "arguments", filename, source)
|
|
281
|
+
|
|
282
|
+
if (calleeNode.type != "identifier" || argumentsNode.type != "argument_list") {
|
|
283
|
+
return unsupportedSyntax("python", "dynamic call", location)
|
|
284
|
+
}
|
|
285
|
+
const callee = identifier(calleeNode, "callee", filename, source)
|
|
286
|
+
const arguments_ = argumentsNode.namedChildren.filter((child) => child.type != "comment")
|
|
287
|
+
.map((argument) => convertExpression(argument, filename, source))
|
|
288
|
+
|
|
289
|
+
return withParserRanges({arguments: arguments_, callee, kind: /** @type {const} */ ("CallExpression"), location}, {
|
|
290
|
+
callee: nodeLocation(calleeNode, filename, source)
|
|
291
|
+
})
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
return unsupportedSyntax("python", node.type, location)
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Decodes one non-prefixed, non-triple Python string without evaluating source.
|
|
299
|
+
* @param {import("tree-sitter").SyntaxNode} node - String node.
|
|
300
|
+
* @param {string} filename - Source filename.
|
|
301
|
+
* @param {string} source - Complete source.
|
|
302
|
+
* @returns {string} Unicode scalar string.
|
|
303
|
+
*/
|
|
304
|
+
function decodeString(node, filename, source) {
|
|
305
|
+
const location = nodeLocation(node, filename, source)
|
|
306
|
+
const text = node.text
|
|
307
|
+
const quote = text[0]
|
|
308
|
+
|
|
309
|
+
if ((quote != "\"" && quote != "'") || text.at(-1) != quote || text.startsWith(`${quote}${quote}${quote}`)) {
|
|
310
|
+
return unsupportedSyntax("python", "prefixed or triple-quoted string", location)
|
|
311
|
+
}
|
|
312
|
+
let decoded = ""
|
|
313
|
+
|
|
314
|
+
for (let index = 1; index < text.length - 1; index += 1) {
|
|
315
|
+
const character = text[index]
|
|
316
|
+
|
|
317
|
+
if (character != "\\") {
|
|
318
|
+
decoded += character
|
|
319
|
+
continue
|
|
320
|
+
}
|
|
321
|
+
const escape = text[++index]
|
|
322
|
+
|
|
323
|
+
if (escape === undefined) return unsupportedSyntax("python", "invalid string escape", location)
|
|
324
|
+
const simple = new Map([
|
|
325
|
+
["\\", "\\"], ["'", "'"], ["\"", "\""], ["a", "\u0007"], ["b", "\b"], ["f", "\f"], ["n", "\n"],
|
|
326
|
+
["r", "\r"], ["t", "\t"], ["v", "\v"]
|
|
327
|
+
])
|
|
328
|
+
|
|
329
|
+
if (simple.has(escape)) {
|
|
330
|
+
decoded += simple.get(escape)
|
|
331
|
+
continue
|
|
332
|
+
}
|
|
333
|
+
if (/[0-7]/u.test(escape)) {
|
|
334
|
+
let digits = escape
|
|
335
|
+
|
|
336
|
+
while (digits.length < 3 && /[0-7]/u.test(text[index + 1] ?? "")) digits += text[++index]
|
|
337
|
+
decoded += String.fromCodePoint(Number.parseInt(digits, 8))
|
|
338
|
+
continue
|
|
339
|
+
}
|
|
340
|
+
const widths = new Map([["x", 2], ["u", 4], ["U", 8]])
|
|
341
|
+
const width = widths.get(escape)
|
|
342
|
+
|
|
343
|
+
if (!width) return unsupportedSyntax("python", `unsupported string escape \\${escape}`, location)
|
|
344
|
+
const digits = text.slice(index + 1, index + 1 + width)
|
|
345
|
+
if (digits.length != width || !/^[0-9A-Fa-f]+$/u.test(digits)) return unsupportedSyntax("python", "invalid string escape", location)
|
|
346
|
+
index += width
|
|
347
|
+
const codePoint = Number.parseInt(digits, 16)
|
|
348
|
+
|
|
349
|
+
if (codePoint > 0x10FFFF || codePoint >= 0xD800 && codePoint <= 0xDFFF) {
|
|
350
|
+
return unsupportedSyntax("python", "invalid Unicode string escape", location)
|
|
351
|
+
}
|
|
352
|
+
decoded += String.fromCodePoint(codePoint)
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
if (!hasOnlyUnicodeScalars(decoded)) return unsupportedSyntax("python", "invalid Unicode string literal", location)
|
|
356
|
+
|
|
357
|
+
return decoded
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Converts one annotated assignment or plain assignment.
|
|
362
|
+
* @param {import("tree-sitter").SyntaxNode} node - Assignment node.
|
|
363
|
+
* @param {PythonContext} context - Comment association state.
|
|
364
|
+
* @param {Set<string>} visible - Visible bindings in this lexical scope.
|
|
365
|
+
* @param {string} filename - Source filename.
|
|
366
|
+
* @param {string} source - Complete source.
|
|
367
|
+
* @returns {import("../semantic/types.js").LocalStatement} Semantic local statement.
|
|
368
|
+
*/
|
|
369
|
+
function convertAssignment(node, context, visible, filename, source) {
|
|
370
|
+
const location = nodeLocation(node, filename, source)
|
|
371
|
+
const left = requiredField(node, "left", filename, source)
|
|
372
|
+
const right = requiredField(node, "right", filename, source)
|
|
373
|
+
const typeNode = node.childForFieldName("type")
|
|
374
|
+
|
|
375
|
+
if (left.type != "identifier") return unsupportedSyntax("python", "non-identifier assignment target", nodeLocation(left, filename, source))
|
|
376
|
+
const name = identifier(left, typeNode ? "local" : "assignment target", filename, source)
|
|
377
|
+
const nameLocation = nodeLocation(left, filename, source)
|
|
378
|
+
const operator = operatorToken(node, new Set(["="]), filename, source)
|
|
379
|
+
|
|
380
|
+
if (!typeNode) {
|
|
381
|
+
if (!visible.has(name)) return missingType("python", `Local '${name}'`, location)
|
|
382
|
+
const target = withParserRanges({kind: /** @type {const} */ ("IdentifierExpression"), location: nameLocation, name}, {name: nameLocation})
|
|
383
|
+
|
|
384
|
+
return withParserRanges({
|
|
385
|
+
expression: convertExpression(right, filename, source),
|
|
386
|
+
kind: /** @type {const} */ ("AssignmentStatement"),
|
|
387
|
+
location,
|
|
388
|
+
target
|
|
389
|
+
}, {operator: nodeLocation(operator, filename, source)})
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
const declaration = withParserRanges({
|
|
393
|
+
initializer: convertExpression(right, filename, source),
|
|
394
|
+
kind: /** @type {const} */ ("LocalDeclaration"),
|
|
395
|
+
location,
|
|
396
|
+
mutable: !takeImmutableMarker(node, context),
|
|
397
|
+
name,
|
|
398
|
+
type: convertType(typeNode, `Local '${name}'`, location, filename, source)
|
|
399
|
+
}, {name: nameLocation, operator: nodeLocation(operator, filename, source)})
|
|
400
|
+
|
|
401
|
+
visible.add(name)
|
|
402
|
+
|
|
403
|
+
return declaration
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Associates the exact immediately preceding immutable marker with a local.
|
|
408
|
+
* @param {import("tree-sitter").SyntaxNode} node - Local assignment.
|
|
409
|
+
* @param {PythonContext} context - Comment state.
|
|
410
|
+
* @returns {boolean} Whether the local is immutable.
|
|
411
|
+
*/
|
|
412
|
+
function takeImmutableMarker(node, context) {
|
|
413
|
+
const marker = context.comments.find((comment) => comment.text == immutableMarker &&
|
|
414
|
+
comment.endPosition.row + 1 == node.startPosition.row && comment.startPosition.column == node.startPosition.column)
|
|
415
|
+
|
|
416
|
+
if (!marker) return false
|
|
417
|
+
context.usedImmutableMarkers.add(marker)
|
|
418
|
+
|
|
419
|
+
return true
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Converts one statement.
|
|
424
|
+
* @param {import("tree-sitter").SyntaxNode} node - Statement node.
|
|
425
|
+
* @param {PythonContext} context - Comment state.
|
|
426
|
+
* @param {Set<string>} visible - Visible bindings in this lexical scope.
|
|
427
|
+
* @param {string} filename - Source filename.
|
|
428
|
+
* @param {string} source - Complete source.
|
|
429
|
+
* @returns {import("../semantic/types.js").Statement} Semantic statement.
|
|
430
|
+
*/
|
|
431
|
+
function convertStatement(node, context, visible, filename, source) {
|
|
432
|
+
const location = nodeLocation(node, filename, source)
|
|
433
|
+
|
|
434
|
+
if (node.type == "return_statement") {
|
|
435
|
+
const expressions = node.namedChildren.filter((child) => child.type != "comment")
|
|
436
|
+
|
|
437
|
+
if (expressions.length != 1) return unsupportedSyntax("python", "return without one expression", location)
|
|
438
|
+
|
|
439
|
+
return {expression: convertExpression(expressions[0], filename, source), kind: "ReturnStatement", location}
|
|
440
|
+
}
|
|
441
|
+
if (node.type == "if_statement") return convertIf(node, context, visible, filename, source)
|
|
442
|
+
if (node.type == "expression_statement") {
|
|
443
|
+
const expressions = node.namedChildren.filter((child) => child.type != "comment")
|
|
444
|
+
|
|
445
|
+
if (expressions.length != 1) return unsupportedSyntax("python", node.type, location)
|
|
446
|
+
if (expressions[0].type == "assignment") return convertAssignment(expressions[0], context, visible, filename, source)
|
|
447
|
+
|
|
448
|
+
return convertPrint(expressions[0], filename, source, location)
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
return unsupportedSyntax("python", node.type, location)
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* Converts the exact print(expression) statement.
|
|
456
|
+
* @param {import("tree-sitter").SyntaxNode} node - Expression statement value.
|
|
457
|
+
* @param {string} filename - Source filename.
|
|
458
|
+
* @param {string} source - Complete source.
|
|
459
|
+
* @param {import("../semantic/types.js").SourceLocation} location - Whole statement location.
|
|
460
|
+
* @returns {import("../semantic/types.js").PrintStatement} Print statement.
|
|
461
|
+
*/
|
|
462
|
+
function convertPrint(node, filename, source, location) {
|
|
463
|
+
if (node.type != "call") return unsupportedSyntax("python", "entry expression other than print", nodeLocation(node, filename, source))
|
|
464
|
+
const callee = requiredField(node, "function", filename, source)
|
|
465
|
+
const argumentsNode = requiredField(node, "arguments", filename, source)
|
|
466
|
+
const arguments_ = argumentsNode.namedChildren.filter((child) => child.type != "comment")
|
|
467
|
+
|
|
468
|
+
if (callee.type != "identifier" || callee.text != "print" || argumentsNode.type != "argument_list" || arguments_.length != 1) {
|
|
469
|
+
return unsupportedSyntax("python", "print call shape", nodeLocation(node, filename, source))
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
return {expression: convertExpression(arguments_[0], filename, source), kind: "PrintStatement", location}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Converts one if/elif/else node into nested semantic blocks.
|
|
477
|
+
* @param {import("tree-sitter").SyntaxNode} node - If or elif node.
|
|
478
|
+
* @param {PythonContext} context - Comment state.
|
|
479
|
+
* @param {Set<string>} visible - Visible bindings in this lexical scope.
|
|
480
|
+
* @param {string} filename - Source filename.
|
|
481
|
+
* @param {string} source - Complete source.
|
|
482
|
+
* @returns {import("../semantic/types.js").IfStatement} Semantic branch.
|
|
483
|
+
*/
|
|
484
|
+
function convertIf(node, context, visible, filename, source) {
|
|
485
|
+
const location = nodeLocation(node, filename, source)
|
|
486
|
+
const conditionNode = requiredField(node, "condition", filename, source)
|
|
487
|
+
const consequenceNode = requiredField(node, "consequence", filename, source)
|
|
488
|
+
const alternativeNodes = node.namedChildren.filter((_child, index) => node.fieldNameForNamedChild(index) == "alternative")
|
|
489
|
+
const alternate = convertAlternatives(alternativeNodes, context, new Set(visible), filename, source)
|
|
490
|
+
|
|
491
|
+
return {
|
|
492
|
+
...(alternate ? {alternate} : {}),
|
|
493
|
+
condition: convertExpression(conditionNode, filename, source),
|
|
494
|
+
consequent: convertBlock(consequenceNode, context, new Set(visible), filename, source),
|
|
495
|
+
kind: "IfStatement",
|
|
496
|
+
location
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* Converts an else block or nests one elif inside its semantic alternate block.
|
|
502
|
+
* @param {import("tree-sitter").SyntaxNode[]} nodes - Ordered elif/else nodes.
|
|
503
|
+
* @param {PythonContext} context - Comment state.
|
|
504
|
+
* @param {Set<string>} visible - Visible bindings in this lexical scope.
|
|
505
|
+
* @param {string} filename - Source filename.
|
|
506
|
+
* @param {string} source - Complete source.
|
|
507
|
+
* @returns {import("../semantic/types.js").Block | undefined} Alternate block.
|
|
508
|
+
*/
|
|
509
|
+
function convertAlternatives(nodes, context, visible, filename, source) {
|
|
510
|
+
/** @type {import("../semantic/types.js").Block | undefined} */
|
|
511
|
+
let alternate
|
|
512
|
+
|
|
513
|
+
for (let index = nodes.length - 1; index >= 0; index -= 1) {
|
|
514
|
+
const node = nodes[index]
|
|
515
|
+
|
|
516
|
+
if (node.type == "else_clause") {
|
|
517
|
+
if (alternate) return unsupportedSyntax("python", "multiple else clauses", nodeLocation(node, filename, source))
|
|
518
|
+
alternate = convertBlock(requiredField(node, "body", filename, source), context, new Set(visible), filename, source)
|
|
519
|
+
continue
|
|
520
|
+
}
|
|
521
|
+
if (node.type != "elif_clause") return unsupportedSyntax("python", node.type, nodeLocation(node, filename, source))
|
|
522
|
+
const nested = convertIf(node, context, new Set(visible), filename, source)
|
|
523
|
+
|
|
524
|
+
if (alternate) nested.alternate = alternate
|
|
525
|
+
alternate = {kind: "Block", location: nodeLocation(node, filename, source), statements: [nested]}
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
return alternate
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
/**
|
|
532
|
+
* Converts one indentation block and permits pass only as its sole executable node.
|
|
533
|
+
* @param {import("tree-sitter").SyntaxNode} node - Block node.
|
|
534
|
+
* @param {PythonContext} context - Comment state.
|
|
535
|
+
* @param {Set<string>} visible - Visible bindings in this lexical scope.
|
|
536
|
+
* @param {string} filename - Source filename.
|
|
537
|
+
* @param {string} source - Complete source.
|
|
538
|
+
* @returns {import("../semantic/types.js").Block} Semantic block.
|
|
539
|
+
*/
|
|
540
|
+
function convertBlock(node, context, visible, filename, source) {
|
|
541
|
+
const location = nodeLocation(node, filename, source)
|
|
542
|
+
|
|
543
|
+
if (node.type != "block") return unsupportedSyntax("python", node.type, location)
|
|
544
|
+
const statements = node.namedChildren.filter((child) => child.type != "comment")
|
|
545
|
+
|
|
546
|
+
if (statements.some((statement) => statement.type == "pass_statement")) {
|
|
547
|
+
if (statements.length != 1) return unsupportedSyntax("python", "pass with executable siblings", location)
|
|
548
|
+
|
|
549
|
+
return {kind: "Block", location, statements: []}
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
return {kind: "Block", location, statements: statements.map((statement) => convertStatement(statement, context, visible, filename, source))}
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
/**
|
|
556
|
+
* Converts one exact synchronous top-level function.
|
|
557
|
+
* @param {import("tree-sitter").SyntaxNode} node - Function node.
|
|
558
|
+
* @param {PythonContext} context - Comment state.
|
|
559
|
+
* @param {string} filename - Source filename.
|
|
560
|
+
* @param {string} source - Complete source.
|
|
561
|
+
* @returns {import("../semantic/types.js").FunctionDeclaration} Semantic function.
|
|
562
|
+
*/
|
|
563
|
+
function convertFunction(node, context, filename, source) {
|
|
564
|
+
const location = nodeLocation(node, filename, source)
|
|
565
|
+
|
|
566
|
+
if (node.type != "function_definition" || node.children.some((child) => !child.isNamed && child.type == "async")) {
|
|
567
|
+
return unsupportedSyntax("python", node.type, location)
|
|
568
|
+
}
|
|
569
|
+
const typeParametersNode = node.childForFieldName("type_parameters")
|
|
570
|
+
|
|
571
|
+
if (typeParametersNode) {
|
|
572
|
+
return unsupportedSyntax("python", typeParametersNode.type, nodeLocation(typeParametersNode, filename, source))
|
|
573
|
+
}
|
|
574
|
+
const nameNode = requiredField(node, "name", filename, source)
|
|
575
|
+
const parametersNode = requiredField(node, "parameters", filename, source)
|
|
576
|
+
const returnNode = node.childForFieldName("return_type")
|
|
577
|
+
const bodyNode = requiredField(node, "body", filename, source)
|
|
578
|
+
const name = identifier(nameNode, "function", filename, source)
|
|
579
|
+
const parameterNodes = parametersNode.namedChildren.filter((child) => child.type != "comment")
|
|
580
|
+
|
|
581
|
+
if (parametersNode.children.some((child) => !child.isNamed && !["(", ")", ","].includes(child.type))) {
|
|
582
|
+
return unsupportedSyntax("python", "parameter separators", nodeLocation(parametersNode, filename, source))
|
|
583
|
+
}
|
|
584
|
+
const parameters = parameterNodes.map((parameterNode) => {
|
|
585
|
+
const parameterLocation = nodeLocation(parameterNode, filename, source)
|
|
586
|
+
|
|
587
|
+
if (parameterNode.type != "typed_parameter") {
|
|
588
|
+
if (parameterNode.type == "identifier") return missingType("python", `Parameter '${parameterNode.text}'`, parameterLocation)
|
|
589
|
+
|
|
590
|
+
return unsupportedSyntax("python", parameterNode.type, parameterLocation)
|
|
591
|
+
}
|
|
592
|
+
const parameterNameNode = parameterNode.namedChildren.find((child) => child.type == "identifier")
|
|
593
|
+
const typeNode = parameterNode.childForFieldName("type")
|
|
594
|
+
|
|
595
|
+
if (!parameterNameNode) return unsupportedSyntax("python", "parameter without identifier", parameterLocation)
|
|
596
|
+
const parameterName = identifier(parameterNameNode, "parameter", filename, source)
|
|
597
|
+
|
|
598
|
+
return withParserRanges({
|
|
599
|
+
kind: /** @type {const} */ ("Parameter"),
|
|
600
|
+
location: parameterLocation,
|
|
601
|
+
name: parameterName,
|
|
602
|
+
type: convertType(typeNode, `Parameter '${parameterName}'`, parameterLocation, filename, source)
|
|
603
|
+
}, {name: nodeLocation(parameterNameNode, filename, source)})
|
|
604
|
+
})
|
|
605
|
+
|
|
606
|
+
const visible = new Set(parameters.map((parameter) => parameter.name))
|
|
607
|
+
|
|
608
|
+
return withParserRanges({
|
|
609
|
+
body: convertBlock(bodyNode, context, visible, filename, source),
|
|
610
|
+
kind: "FunctionDeclaration",
|
|
611
|
+
location,
|
|
612
|
+
name,
|
|
613
|
+
parameters,
|
|
614
|
+
returnType: convertType(returnNode, `Function '${name}' return`, location, filename, source)
|
|
615
|
+
}, {name: nodeLocation(nameNode, filename, source)})
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
/**
|
|
619
|
+
* Parses the strict Task 016 Python profile.
|
|
620
|
+
* @param {{filename: string, source: string}} input - Parser input.
|
|
621
|
+
* @returns {import("../semantic/types.js").SemanticModule} Semantic module.
|
|
622
|
+
*/
|
|
623
|
+
export function parsePython({filename, source}) {
|
|
624
|
+
if (!hasOnlyUnicodeScalars(source)) {
|
|
625
|
+
const invalidOffset = firstLoneSurrogateOffset(source)
|
|
626
|
+
|
|
627
|
+
throw new SemantifoldDiagnostic({
|
|
628
|
+
code: "PARSE_ERROR",
|
|
629
|
+
language: "python",
|
|
630
|
+
location: locationFromOffsets(filename, source, invalidOffset, invalidOffset + 1),
|
|
631
|
+
message: "Python source contains an invalid lone UTF-16 surrogate."
|
|
632
|
+
})
|
|
633
|
+
}
|
|
634
|
+
let tree
|
|
635
|
+
|
|
636
|
+
try {
|
|
637
|
+
tree = parser.parse(source)
|
|
638
|
+
} catch (error) {
|
|
639
|
+
return parseFailure("python", error)
|
|
640
|
+
}
|
|
641
|
+
const root = tree.rootNode
|
|
642
|
+
|
|
643
|
+
validateParserTree(root, filename, source)
|
|
644
|
+
if (root.type != "module") throw new Error(`Tree-sitter returned Python root '${root.type}'.`)
|
|
645
|
+
|
|
646
|
+
const comments = root.descendantsOfType("comment")
|
|
647
|
+
const context = {comments, usedImmutableMarkers: new Set()}
|
|
648
|
+
const functions = []
|
|
649
|
+
const entryNodes = []
|
|
650
|
+
let sawEntry = false
|
|
651
|
+
|
|
652
|
+
for (const node of root.namedChildren) {
|
|
653
|
+
if (node.type == "comment") continue
|
|
654
|
+
if (node.type == "function_definition" && !sawEntry) functions.push(convertFunction(node, context, filename, source))
|
|
655
|
+
else {
|
|
656
|
+
sawEntry = true
|
|
657
|
+
entryNodes.push(node)
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
const location = moduleLocation(filename, source)
|
|
661
|
+
const entryLocation = entryNodes.length == 0 ? location : locationFromOffsets(
|
|
662
|
+
filename,
|
|
663
|
+
source,
|
|
664
|
+
bindingIndexToUtf16Offset(source, entryNodes[0].startIndex),
|
|
665
|
+
bindingIndexToUtf16Offset(source, entryNodes.at(-1)?.endIndex ?? root.endIndex)
|
|
666
|
+
)
|
|
667
|
+
const entryVisible = new Set()
|
|
668
|
+
const entryHasPass = entryNodes.some((node) => node.type == "pass_statement")
|
|
669
|
+
|
|
670
|
+
if (entryHasPass && entryNodes.length != 1) {
|
|
671
|
+
return unsupportedSyntax("python", "top-level pass with executable siblings", entryLocation)
|
|
672
|
+
}
|
|
673
|
+
const entryBlock = {
|
|
674
|
+
kind: /** @type {const} */ ("Block"),
|
|
675
|
+
location: entryLocation,
|
|
676
|
+
statements: entryHasPass ? [] : entryNodes.map((node) => convertStatement(node, context, entryVisible, filename, source))
|
|
677
|
+
}
|
|
678
|
+
const unusedMarker = comments.find((comment) => comment.text == immutableMarker && !context.usedImmutableMarkers.has(comment))
|
|
679
|
+
|
|
680
|
+
if (unusedMarker) return unsupportedSyntax("python", "unattached immutable marker", nodeLocation(unusedMarker, filename, source))
|
|
681
|
+
if (functions.length == 0) return unsupportedSyntax("python", "module without a function", location)
|
|
682
|
+
|
|
683
|
+
return {
|
|
684
|
+
entryPoint: {body: entryBlock, kind: "EntryPoint", location: entryLocation},
|
|
685
|
+
functions,
|
|
686
|
+
kind: "Module",
|
|
687
|
+
location
|
|
688
|
+
}
|
|
689
|
+
}
|