semantifold 0.2.0 → 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 +37 -12
- package/build/index.js +2 -2
- package/build/src/acceptance.d.ts +10 -0
- package/build/src/acceptance.d.ts.map +1 -1
- package/build/src/acceptance.js +24 -5
- 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 +71 -2
- package/build/src/backends/index.d.ts.map +1 -1
- package/build/src/backends/index.js +9 -1
- 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/scalars.d.ts.map +1 -1
- package/build/src/backends/scalars.js +7 -2
- package/build/src/backends/shared.d.ts.map +1 -1
- package/build/src/backends/shared.js +59 -14
- 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/scalars.d.ts.map +1 -1
- package/build/src/frontends/scalars.js +16 -1
- package/build/src/language-registry.d.ts.map +1 -1
- package/build/src/language-registry.js +51 -2
- package/build/src/mapping.js +2 -2
- package/build/src/semantic/provenance.js +3 -3
- package/build/src/semantic/types.d.ts +4 -4
- package/build/src/semantic/types.d.ts.map +1 -1
- package/build/src/semantic/types.js +3 -3
- package/build/src/subprocess.d.ts +10 -1
- package/build/src/subprocess.d.ts.map +1 -1
- package/build/src/subprocess.js +29 -3
- package/build/src/toolchains.d.ts +24 -0
- package/build/src/toolchains.d.ts.map +1 -1
- package/build/src/toolchains.js +6 -2
- package/docs/architecture.md +20 -6
- package/docs/c.md +60 -0
- package/docs/cpp.md +61 -0
- package/docs/goals.md +4 -2
- package/docs/language-support.md +27 -8
- package/docs/parser-qualification.md +153 -4
- package/docs/plans/2026-09-05-standard-library-portability.md +46 -0
- package/docs/source-maps.md +11 -5
- package/docs/standard-library-portability.md +190 -0
- package/docs/testing.md +113 -4
- package/index.js +1 -1
- 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 +21 -5
- package/src/acceptance.js +25 -4
- 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 +72 -1
- package/src/backends/index.js +7 -0
- package/src/backends/native-validation.js +64 -0
- package/src/backends/ordered-expressions.js +161 -0
- package/src/backends/scalars.js +7 -1
- package/src/backends/shared.js +56 -12
- 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/scalars.js +15 -0
- package/src/language-registry.js +52 -1
- package/src/mapping.js +1 -1
- package/src/semantic/provenance.js +2 -2
- package/src/semantic/types.js +2 -2
- package/src/subprocess.js +31 -2
- package/src/toolchains.js +5 -1
|
@@ -0,0 +1,770 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import Parser from "tree-sitter"
|
|
4
|
+
import GoLanguage from "tree-sitter-go/bindings/node/index.js"
|
|
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 {validateParsedModule} from "../semantic/validate.js"
|
|
11
|
+
import {sourceScalarType} from "./scalars.js"
|
|
12
|
+
|
|
13
|
+
const parser = new Parser()
|
|
14
|
+
|
|
15
|
+
parser.setLanguage(/** @type {import("tree-sitter").Language} */ (/** @type {unknown} */ (GoLanguage)))
|
|
16
|
+
|
|
17
|
+
const immutableMarker = "// @semantifold-immutable"
|
|
18
|
+
const goKeywords = new Set([
|
|
19
|
+
"break", "default", "func", "interface", "select", "case", "defer", "go", "map", "struct", "chan",
|
|
20
|
+
"else", "goto", "package", "switch", "const", "fallthrough", "if", "range", "type", "continue",
|
|
21
|
+
"for", "import", "return", "var"
|
|
22
|
+
])
|
|
23
|
+
const functionReserved = new Set(["main", "init", "fmt", "int64", "bool", "string", "true", "false"])
|
|
24
|
+
const bindingReserved = new Set(["fmt", "int64", "bool", "string", "true", "false"])
|
|
25
|
+
const binaryOperations = new Map([
|
|
26
|
+
["+", "Add"], ["-", "Subtract"], ["*", "Multiply"], ["==", "Equal"], ["!=", "NotEqual"],
|
|
27
|
+
["<", "LessThan"], ["<=", "LessThanOrEqual"], [">", "GreaterThan"], [">=", "GreaterThanOrEqual"],
|
|
28
|
+
["&&", "And"], ["||", "Or"]
|
|
29
|
+
])
|
|
30
|
+
|
|
31
|
+
/** @typedef {{comments: import("tree-sitter").SyntaxNode[], usedMarkers: Set<import("tree-sitter").SyntaxNode>, assignmentTargets: Set<string>}} GoContext */
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Verifies one binding UTF-16 index through the shared byte converter.
|
|
35
|
+
* @param {string} source Complete source.
|
|
36
|
+
* @param {number} index Binding-reported UTF-16 index.
|
|
37
|
+
* @returns {number} Verified UTF-16 offset.
|
|
38
|
+
*/
|
|
39
|
+
function bindingIndexToUtf16Offset(source, index) {
|
|
40
|
+
if (!Number.isInteger(index) || index < 0 || index > source.length ||
|
|
41
|
+
index > 0 && index < source.length && /[\uD800-\uDBFF]/u.test(source[index - 1]) && /[\uDC00-\uDFFF]/u.test(source[index])) {
|
|
42
|
+
throw new RangeError("Invalid Tree-sitter source index: " + index)
|
|
43
|
+
}
|
|
44
|
+
return utf8ByteOffsetToUtf16Offset(source, new TextEncoder().encode(source.slice(0, index)).length)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Finds an unpaired UTF-16 surrogate.
|
|
49
|
+
* @param {string} source Complete source.
|
|
50
|
+
* @returns {number} Invalid offset or -1.
|
|
51
|
+
*/
|
|
52
|
+
function firstLoneSurrogateOffset(source) {
|
|
53
|
+
for (let index = 0; index < source.length; index += 1) {
|
|
54
|
+
const unit = source.charCodeAt(index)
|
|
55
|
+
|
|
56
|
+
if (unit >= 0xD800 && unit <= 0xDBFF) {
|
|
57
|
+
const next = source.charCodeAt(index + 1)
|
|
58
|
+
|
|
59
|
+
if (next >= 0xDC00 && next <= 0xDFFF) index += 1
|
|
60
|
+
else return index
|
|
61
|
+
} else if (unit >= 0xDC00 && unit <= 0xDFFF) return index
|
|
62
|
+
}
|
|
63
|
+
return -1
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Converts one CST range.
|
|
68
|
+
* @param {import("tree-sitter").SyntaxNode} node CST node.
|
|
69
|
+
* @param {string} filename Source filename.
|
|
70
|
+
* @param {string} source Complete source.
|
|
71
|
+
* @returns {import("../semantic/types.js").SourceLocation} Exact location.
|
|
72
|
+
*/
|
|
73
|
+
function nodeLocation(node, filename, source) {
|
|
74
|
+
return locationFromOffsets(filename, source, bindingIndexToUtf16Offset(source, node.startIndex),
|
|
75
|
+
bindingIndexToUtf16Offset(source, node.endIndex))
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Requires one grammar field.
|
|
80
|
+
* @param {import("tree-sitter").SyntaxNode} node Field owner.
|
|
81
|
+
* @param {string} field Field name.
|
|
82
|
+
* @param {string} filename Source filename.
|
|
83
|
+
* @param {string} source Complete source.
|
|
84
|
+
* @returns {import("tree-sitter").SyntaxNode} Required child.
|
|
85
|
+
*/
|
|
86
|
+
function requiredField(node, field, filename, source) {
|
|
87
|
+
const child = node.childForFieldName(field)
|
|
88
|
+
|
|
89
|
+
if (!child) return unsupportedSyntax("go", node.type + " without " + field, nodeLocation(node, filename, source))
|
|
90
|
+
return child
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Traverses every named and anonymous node before conversion.
|
|
95
|
+
* @param {import("tree-sitter").SyntaxNode} node Current node.
|
|
96
|
+
* @param {string} filename Source filename.
|
|
97
|
+
* @param {string} source Complete source.
|
|
98
|
+
* @returns {void}
|
|
99
|
+
*/
|
|
100
|
+
function validateParserTree(node, filename, source) {
|
|
101
|
+
if (node.hasError || node.isError || node.isMissing) {
|
|
102
|
+
throw new SemantifoldDiagnostic({
|
|
103
|
+
code: "PARSE_ERROR",
|
|
104
|
+
language: "go",
|
|
105
|
+
location: nodeLocation(node, filename, source),
|
|
106
|
+
message: "Tree-sitter exposed recovery at '" + node.type + "'."
|
|
107
|
+
})
|
|
108
|
+
}
|
|
109
|
+
if (!node.isNamed && node.type == ";") {
|
|
110
|
+
return unsupportedSyntax("go", "explicit semicolon", nodeLocation(node, filename, source))
|
|
111
|
+
}
|
|
112
|
+
for (let index = 0; index < node.childCount; index += 1) {
|
|
113
|
+
const child = node.child(index)
|
|
114
|
+
|
|
115
|
+
if (!child) throw new Error("Tree-sitter omitted child " + index + " of " + node.type + ".")
|
|
116
|
+
validateParserTree(child, filename, source)
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Selects semantic children while retaining comments for metadata validation.
|
|
122
|
+
* @param {import("tree-sitter").SyntaxNode} node Parent node.
|
|
123
|
+
* @returns {import("tree-sitter").SyntaxNode[]} Non-comment named children.
|
|
124
|
+
*/
|
|
125
|
+
function semanticChildren(node) {
|
|
126
|
+
return node.namedChildren.filter((child) => child.type != "comment")
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Validates one Go identifier.
|
|
131
|
+
* @param {import("tree-sitter").SyntaxNode} node Identifier node.
|
|
132
|
+
* @param {"function" | "parameter" | "local" | "assignment target" | "reference" | "callee"} role Identifier role.
|
|
133
|
+
* @param {string} filename Source filename.
|
|
134
|
+
* @param {string} source Complete source.
|
|
135
|
+
* @returns {string} Accepted spelling.
|
|
136
|
+
*/
|
|
137
|
+
function identifier(node, role, filename, source) {
|
|
138
|
+
const name = node.text
|
|
139
|
+
const reserved = ["function", "callee"].includes(role) ? functionReserved : ["parameter", "local", "assignment target"].includes(role)
|
|
140
|
+
? bindingReserved
|
|
141
|
+
: new Set()
|
|
142
|
+
|
|
143
|
+
if (node.type != "identifier" || !/^[A-Za-z_][A-Za-z0-9_]*$/u.test(name) || name == "_" ||
|
|
144
|
+
goKeywords.has(name) || reserved.has(name)) {
|
|
145
|
+
return unsupportedSyntax("go", role + " identifier '" + name + "'", nodeLocation(node, filename, source))
|
|
146
|
+
}
|
|
147
|
+
return name
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Converts an explicit scalar.
|
|
152
|
+
* @param {import("tree-sitter").SyntaxNode | null} node Type node.
|
|
153
|
+
* @param {string} subject Diagnostic subject.
|
|
154
|
+
* @param {import("../semantic/types.js").SourceLocation} ownerLocation Owner location.
|
|
155
|
+
* @param {string} filename Source filename.
|
|
156
|
+
* @param {string} source Complete source.
|
|
157
|
+
* @returns {import("../semantic/types.js").TypeReference} Semantic type.
|
|
158
|
+
*/
|
|
159
|
+
function convertType(node, subject, ownerLocation, filename, source) {
|
|
160
|
+
if (!node) return missingType("go", subject, ownerLocation)
|
|
161
|
+
const location = nodeLocation(node, filename, source)
|
|
162
|
+
const type = sourceScalarType("go", node.text, location)
|
|
163
|
+
|
|
164
|
+
if (!type || node.type != "type_identifier") {
|
|
165
|
+
return unsupportedSyntax("go", "unsupported scalar type '" + node.text + "'", location)
|
|
166
|
+
}
|
|
167
|
+
return type
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Finds exactly one accepted operator token.
|
|
172
|
+
* @param {import("tree-sitter").SyntaxNode} node Operation node.
|
|
173
|
+
* @param {Set<string>} spellings Accepted spellings.
|
|
174
|
+
* @param {string} filename Source filename.
|
|
175
|
+
* @param {string} source Complete source.
|
|
176
|
+
* @returns {import("tree-sitter").SyntaxNode} Operator token.
|
|
177
|
+
*/
|
|
178
|
+
function operatorToken(node, spellings, filename, source) {
|
|
179
|
+
const field = node.childForFieldName("operator")
|
|
180
|
+
const candidates = field ? [field] : node.children.filter((child) => !child.isNamed && spellings.has(child.type))
|
|
181
|
+
|
|
182
|
+
if (candidates.length != 1 || !spellings.has(candidates[0].type)) {
|
|
183
|
+
return unsupportedSyntax("go", node.type + " operator", nodeLocation(node, filename, source))
|
|
184
|
+
}
|
|
185
|
+
return candidates[0]
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Requires one expression in an expression list.
|
|
190
|
+
* @param {import("tree-sitter").SyntaxNode} node Expression list.
|
|
191
|
+
* @param {string} subject Diagnostic subject.
|
|
192
|
+
* @param {string} filename Source filename.
|
|
193
|
+
* @param {string} source Complete source.
|
|
194
|
+
* @returns {import("tree-sitter").SyntaxNode} Sole expression.
|
|
195
|
+
*/
|
|
196
|
+
function soleExpression(node, subject, filename, source) {
|
|
197
|
+
const children = semanticChildren(node)
|
|
198
|
+
|
|
199
|
+
if (node.type != "expression_list" || children.length != 1) {
|
|
200
|
+
return unsupportedSyntax("go", subject, nodeLocation(node, filename, source))
|
|
201
|
+
}
|
|
202
|
+
return children[0]
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Converts one expression.
|
|
207
|
+
* @param {import("tree-sitter").SyntaxNode} node Expression node.
|
|
208
|
+
* @param {string} filename Source filename.
|
|
209
|
+
* @param {string} source Complete source.
|
|
210
|
+
* @returns {import("../semantic/types.js").Expression} Semantic expression.
|
|
211
|
+
*/
|
|
212
|
+
function convertExpression(node, filename, source) {
|
|
213
|
+
const location = nodeLocation(node, filename, source)
|
|
214
|
+
|
|
215
|
+
if (node.type == "parenthesized_expression") {
|
|
216
|
+
const children = semanticChildren(node)
|
|
217
|
+
|
|
218
|
+
if (children.length != 1) return unsupportedSyntax("go", node.type, location)
|
|
219
|
+
return convertExpression(children[0], filename, source)
|
|
220
|
+
}
|
|
221
|
+
if (node.type == "identifier") {
|
|
222
|
+
const name = identifier(node, "reference", filename, source)
|
|
223
|
+
|
|
224
|
+
return withParserRanges({kind: /** @type {const} */ ("IdentifierExpression"), location, name}, {name: location})
|
|
225
|
+
}
|
|
226
|
+
if (node.type == "int_literal") {
|
|
227
|
+
if (!/^(?:0|[1-9][0-9]*)$/u.test(node.text)) return unsupportedSyntax("go", "noncanonical integer literal", location)
|
|
228
|
+
const value = Number(BigInt(node.text))
|
|
229
|
+
|
|
230
|
+
if (!Number.isSafeInteger(value)) return unsupportedSyntax("go", "non-safe integer literal", location)
|
|
231
|
+
return withParserRanges({kind: /** @type {const} */ ("IntegerLiteral"), location, value}, {literal: location})
|
|
232
|
+
}
|
|
233
|
+
if (node.type == "true" || node.type == "false") {
|
|
234
|
+
return withParserRanges({kind: /** @type {const} */ ("BooleanLiteral"), location, value: node.type == "true"}, {literal: location})
|
|
235
|
+
}
|
|
236
|
+
if (node.type == "interpreted_string_literal") {
|
|
237
|
+
return withParserRanges({kind: /** @type {const} */ ("StringLiteral"), location, value: decodeString(node, filename, source)}, {
|
|
238
|
+
literal: location
|
|
239
|
+
})
|
|
240
|
+
}
|
|
241
|
+
if (node.type == "unary_expression") {
|
|
242
|
+
const operand = requiredField(node, "operand", filename, source)
|
|
243
|
+
const operator = operatorToken(node, new Set(["!", "-"]), filename, source)
|
|
244
|
+
|
|
245
|
+
if (semanticChildren(node).length != 1) return unsupportedSyntax("go", "unary expression shape", location)
|
|
246
|
+
return /** @type {import("../semantic/types.js").Expression} */ (/** @type {unknown} */ (withAdaptedOperation(withParserRanges({
|
|
247
|
+
kind: "UnaryExpression",
|
|
248
|
+
location,
|
|
249
|
+
operand: convertExpression(operand, filename, source)
|
|
250
|
+
}, {operator: nodeLocation(operator, filename, source)}), operator.type == "!" ? "Not" : "Negate")))
|
|
251
|
+
}
|
|
252
|
+
if (node.type == "binary_expression") {
|
|
253
|
+
const left = requiredField(node, "left", filename, source)
|
|
254
|
+
const right = requiredField(node, "right", filename, source)
|
|
255
|
+
const operator = operatorToken(node, new Set(binaryOperations.keys()), filename, source)
|
|
256
|
+
const adapted = binaryOperations.get(operator.type)
|
|
257
|
+
|
|
258
|
+
if (!adapted || semanticChildren(node).length != 2) return unsupportedSyntax("go", "binary expression shape", location)
|
|
259
|
+
return /** @type {import("../semantic/types.js").Expression} */ (/** @type {unknown} */ (withAdaptedOperation(withParserRanges({
|
|
260
|
+
kind: "BinaryExpression",
|
|
261
|
+
left: convertExpression(left, filename, source),
|
|
262
|
+
location,
|
|
263
|
+
right: convertExpression(right, filename, source)
|
|
264
|
+
}, {operator: nodeLocation(operator, filename, source)}), /** @type {import("../semantic/operators.js").AdaptedOperation} */ (adapted))))
|
|
265
|
+
}
|
|
266
|
+
if (node.type == "call_expression") {
|
|
267
|
+
const calleeNode = requiredField(node, "function", filename, source)
|
|
268
|
+
const argumentsNode = requiredField(node, "arguments", filename, source)
|
|
269
|
+
|
|
270
|
+
if (calleeNode.type != "identifier" || argumentsNode.type != "argument_list" || semanticChildren(node).length != 2) {
|
|
271
|
+
return unsupportedSyntax("go", "qualified or dynamic call", location)
|
|
272
|
+
}
|
|
273
|
+
const callee = identifier(calleeNode, "callee", filename, source)
|
|
274
|
+
const arguments_ = semanticChildren(argumentsNode).map((argument) => convertExpression(argument, filename, source))
|
|
275
|
+
|
|
276
|
+
return withParserRanges({arguments: arguments_, callee, kind: /** @type {const} */ ("CallExpression"), location}, {
|
|
277
|
+
callee: nodeLocation(calleeNode, filename, source)
|
|
278
|
+
})
|
|
279
|
+
}
|
|
280
|
+
return unsupportedSyntax("go", node.type, location)
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Decodes an interpreted Go string to valid Unicode scalar text.
|
|
285
|
+
* @param {import("tree-sitter").SyntaxNode} node Literal node.
|
|
286
|
+
* @param {string} filename Source filename.
|
|
287
|
+
* @param {string} source Complete source.
|
|
288
|
+
* @returns {string} Decoded value.
|
|
289
|
+
*/
|
|
290
|
+
function decodeString(node, filename, source) {
|
|
291
|
+
const location = nodeLocation(node, filename, source)
|
|
292
|
+
const text = node.text
|
|
293
|
+
|
|
294
|
+
if (!text.startsWith('"') || !text.endsWith('"') || /[\r\n]/u.test(text)) {
|
|
295
|
+
return unsupportedSyntax("go", "noncanonical interpreted string literal", location)
|
|
296
|
+
}
|
|
297
|
+
/** @type {number[]} */
|
|
298
|
+
const bytes = []
|
|
299
|
+
/**
|
|
300
|
+
* Appends one UTF-8 text segment.
|
|
301
|
+
* @param {string} value Text segment.
|
|
302
|
+
* @returns {number} New byte length.
|
|
303
|
+
*/
|
|
304
|
+
const appendText = (value) => bytes.push(...new TextEncoder().encode(value))
|
|
305
|
+
const simple = new Map([
|
|
306
|
+
["a", 7], ["b", 8], ["f", 12], ["n", 10], ["r", 13], ["t", 9], ["v", 11], ["\\", 92], ['"', 34]
|
|
307
|
+
])
|
|
308
|
+
|
|
309
|
+
for (let index = 1; index < text.length - 1; index += 1) {
|
|
310
|
+
const character = text[index]
|
|
311
|
+
|
|
312
|
+
if (character != "\\") {
|
|
313
|
+
const codePoint = text.codePointAt(index)
|
|
314
|
+
|
|
315
|
+
if (codePoint === undefined) return unsupportedSyntax("go", "invalid string literal", location)
|
|
316
|
+
appendText(String.fromCodePoint(codePoint))
|
|
317
|
+
if (codePoint > 0xFFFF) index += 1
|
|
318
|
+
continue
|
|
319
|
+
}
|
|
320
|
+
const escape = text[++index]
|
|
321
|
+
|
|
322
|
+
if (escape === undefined) return unsupportedSyntax("go", "invalid string escape", location)
|
|
323
|
+
if (simple.has(escape)) {
|
|
324
|
+
bytes.push(/** @type {number} */ (simple.get(escape)))
|
|
325
|
+
continue
|
|
326
|
+
}
|
|
327
|
+
if (escape == "x") {
|
|
328
|
+
const digits = text.slice(index + 1, index + 3)
|
|
329
|
+
|
|
330
|
+
if (!/^[0-9A-Fa-f]{2}$/u.test(digits)) return unsupportedSyntax("go", "invalid byte escape", location)
|
|
331
|
+
bytes.push(Number.parseInt(digits, 16))
|
|
332
|
+
index += 2
|
|
333
|
+
continue
|
|
334
|
+
}
|
|
335
|
+
if (/[0-7]/u.test(escape)) {
|
|
336
|
+
const digits = text.slice(index, index + 3)
|
|
337
|
+
|
|
338
|
+
if (!/^[0-7]{3}$/u.test(digits)) return unsupportedSyntax("go", "invalid octal escape", location)
|
|
339
|
+
const value = Number.parseInt(digits, 8)
|
|
340
|
+
|
|
341
|
+
if (value > 255) return unsupportedSyntax("go", "octal escape outside byte range", location)
|
|
342
|
+
bytes.push(value)
|
|
343
|
+
index += 2
|
|
344
|
+
continue
|
|
345
|
+
}
|
|
346
|
+
const width = escape == "u" ? 4 : escape == "U" ? 8 : 0
|
|
347
|
+
const digits = text.slice(index + 1, index + 1 + width)
|
|
348
|
+
|
|
349
|
+
if (!width || digits.length != width || !/^[0-9A-Fa-f]+$/u.test(digits)) {
|
|
350
|
+
return unsupportedSyntax("go", "unsupported string escape", location)
|
|
351
|
+
}
|
|
352
|
+
const value = Number.parseInt(digits, 16)
|
|
353
|
+
|
|
354
|
+
if (value > 0x10FFFF || value >= 0xD800 && value <= 0xDFFF) {
|
|
355
|
+
return unsupportedSyntax("go", "invalid Unicode string escape", location)
|
|
356
|
+
}
|
|
357
|
+
appendText(String.fromCodePoint(value))
|
|
358
|
+
index += width
|
|
359
|
+
}
|
|
360
|
+
let decoded
|
|
361
|
+
|
|
362
|
+
try {
|
|
363
|
+
decoded = new TextDecoder("utf-8", {fatal: true}).decode(Uint8Array.from(bytes))
|
|
364
|
+
} catch {
|
|
365
|
+
return unsupportedSyntax("go", "string byte escapes do not form valid UTF-8", location)
|
|
366
|
+
}
|
|
367
|
+
if (!hasOnlyUnicodeScalars(decoded)) return unsupportedSyntax("go", "invalid Unicode string literal", location)
|
|
368
|
+
return decoded
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Collects plain assignment targets in one root function.
|
|
373
|
+
* @param {import("tree-sitter").SyntaxNode} body Root body.
|
|
374
|
+
* @returns {Set<string>} Assigned names.
|
|
375
|
+
*/
|
|
376
|
+
function collectAssignmentTargets(body) {
|
|
377
|
+
const names = new Set()
|
|
378
|
+
|
|
379
|
+
for (const assignment of body.descendantsOfType("assignment_statement")) {
|
|
380
|
+
const left = assignment.childForFieldName("left")
|
|
381
|
+
const children = left ? semanticChildren(left) : []
|
|
382
|
+
|
|
383
|
+
if (left?.type == "expression_list" && children.length == 1 && children[0].type == "identifier") {
|
|
384
|
+
names.add(children[0].text)
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
return names
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* Claims an exact adjacent immutable marker.
|
|
392
|
+
* @param {import("tree-sitter").SyntaxNode} node Local declaration.
|
|
393
|
+
* @param {GoContext} context Comment context.
|
|
394
|
+
* @returns {boolean} Whether marked immutable.
|
|
395
|
+
*/
|
|
396
|
+
function takeImmutableMarker(node, context) {
|
|
397
|
+
const marker = context.comments.find((comment) => comment.text == immutableMarker &&
|
|
398
|
+
comment.endPosition.row + 1 == node.startPosition.row && comment.startPosition.column == node.startPosition.column)
|
|
399
|
+
|
|
400
|
+
if (!marker) return false
|
|
401
|
+
context.usedMarkers.add(marker)
|
|
402
|
+
return true
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Converts one exact initialized local.
|
|
407
|
+
* @param {import("tree-sitter").SyntaxNode} node Declaration node.
|
|
408
|
+
* @param {GoContext} context Function context.
|
|
409
|
+
* @param {string} filename Source filename.
|
|
410
|
+
* @param {string} source Complete source.
|
|
411
|
+
* @returns {import("../semantic/types.js").LocalDeclaration} Semantic local.
|
|
412
|
+
*/
|
|
413
|
+
function convertLocal(node, context, filename, source) {
|
|
414
|
+
const location = nodeLocation(node, filename, source)
|
|
415
|
+
const children = semanticChildren(node)
|
|
416
|
+
|
|
417
|
+
if (children.length != 1 || children[0].type != "var_spec") return unsupportedSyntax("go", "local declaration shape", location)
|
|
418
|
+
const spec = children[0]
|
|
419
|
+
const nameNode = requiredField(spec, "name", filename, source)
|
|
420
|
+
const typeNode = spec.childForFieldName("type")
|
|
421
|
+
const valueNode = requiredField(spec, "value", filename, source)
|
|
422
|
+
|
|
423
|
+
if (semanticChildren(spec).length != (typeNode ? 3 : 2)) return unsupportedSyntax("go", "local declaration shape", location)
|
|
424
|
+
const expressionNode = soleExpression(valueNode, "local initializer count", filename, source)
|
|
425
|
+
const name = identifier(nameNode, "local", filename, source)
|
|
426
|
+
const markedImmutable = takeImmutableMarker(node, context)
|
|
427
|
+
const operator = operatorToken(spec, new Set(["="]), filename, source)
|
|
428
|
+
|
|
429
|
+
return withParserRanges({
|
|
430
|
+
initializer: convertExpression(expressionNode, filename, source),
|
|
431
|
+
kind: /** @type {const} */ ("LocalDeclaration"),
|
|
432
|
+
location,
|
|
433
|
+
mutable: !markedImmutable && context.assignmentTargets.has(name),
|
|
434
|
+
name,
|
|
435
|
+
type: convertType(typeNode, "Local '" + name + "'", location, filename, source)
|
|
436
|
+
}, {name: nodeLocation(nameNode, filename, source), operator: nodeLocation(operator, filename, source)})
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* Converts one plain assignment.
|
|
441
|
+
* @param {import("tree-sitter").SyntaxNode} node Assignment node.
|
|
442
|
+
* @param {string} filename Source filename.
|
|
443
|
+
* @param {string} source Complete source.
|
|
444
|
+
* @returns {import("../semantic/types.js").AssignmentStatement} Semantic assignment.
|
|
445
|
+
*/
|
|
446
|
+
function convertAssignment(node, filename, source) {
|
|
447
|
+
const location = nodeLocation(node, filename, source)
|
|
448
|
+
const leftList = requiredField(node, "left", filename, source)
|
|
449
|
+
const rightList = requiredField(node, "right", filename, source)
|
|
450
|
+
const operator = operatorToken(node, new Set(["="]), filename, source)
|
|
451
|
+
const left = soleExpression(leftList, "assignment target count", filename, source)
|
|
452
|
+
const right = soleExpression(rightList, "assignment value count", filename, source)
|
|
453
|
+
|
|
454
|
+
if (left.type != "identifier" || semanticChildren(node).length != 2) {
|
|
455
|
+
return unsupportedSyntax("go", "assignment shape", location)
|
|
456
|
+
}
|
|
457
|
+
const name = identifier(left, "assignment target", filename, source)
|
|
458
|
+
const nameLocation = nodeLocation(left, filename, source)
|
|
459
|
+
|
|
460
|
+
return withParserRanges({
|
|
461
|
+
expression: convertExpression(right, filename, source),
|
|
462
|
+
kind: /** @type {const} */ ("AssignmentStatement"),
|
|
463
|
+
location,
|
|
464
|
+
target: withParserRanges({kind: /** @type {const} */ ("IdentifierExpression"), location: nameLocation, name}, {name: nameLocation})
|
|
465
|
+
}, {operator: nodeLocation(operator, filename, source)})
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* Recognizes exact fmt.Println.
|
|
470
|
+
* @param {import("tree-sitter").SyntaxNode} node Candidate selector.
|
|
471
|
+
* @returns {boolean} Exact print receiver.
|
|
472
|
+
*/
|
|
473
|
+
function isPrintReceiver(node) {
|
|
474
|
+
return node.type == "selector_expression" && semanticChildren(node).length == 2 &&
|
|
475
|
+
node.childForFieldName("operand")?.type == "identifier" && node.childForFieldName("operand")?.text == "fmt" &&
|
|
476
|
+
node.childForFieldName("field")?.type == "field_identifier" && node.childForFieldName("field")?.text == "Println"
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* Converts one print expression statement.
|
|
481
|
+
* @param {import("tree-sitter").SyntaxNode} node Expression statement.
|
|
482
|
+
* @param {string} filename Source filename.
|
|
483
|
+
* @param {string} source Complete source.
|
|
484
|
+
* @returns {import("../semantic/types.js").PrintStatement} Semantic print.
|
|
485
|
+
*/
|
|
486
|
+
function convertPrint(node, filename, source) {
|
|
487
|
+
const location = nodeLocation(node, filename, source)
|
|
488
|
+
const children = semanticChildren(node)
|
|
489
|
+
|
|
490
|
+
if (children.length != 1 || children[0].type != "call_expression") {
|
|
491
|
+
return unsupportedSyntax("go", "expression statement other than print", location)
|
|
492
|
+
}
|
|
493
|
+
const call = children[0]
|
|
494
|
+
const callee = requiredField(call, "function", filename, source)
|
|
495
|
+
const argumentsNode = requiredField(call, "arguments", filename, source)
|
|
496
|
+
const arguments_ = semanticChildren(argumentsNode)
|
|
497
|
+
|
|
498
|
+
if (!isPrintReceiver(callee) || semanticChildren(call).length != 2 || argumentsNode.type != "argument_list" ||
|
|
499
|
+
arguments_.length != 1) {
|
|
500
|
+
return unsupportedSyntax("go", "print call shape", nodeLocation(call, filename, source))
|
|
501
|
+
}
|
|
502
|
+
return {expression: convertExpression(arguments_[0], filename, source), kind: /** @type {const} */ ("PrintStatement"), location}
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* Converts one conditional.
|
|
507
|
+
* @param {import("tree-sitter").SyntaxNode} node If node.
|
|
508
|
+
* @param {GoContext} context Function context.
|
|
509
|
+
* @param {string} filename Source filename.
|
|
510
|
+
* @param {string} source Complete source.
|
|
511
|
+
* @returns {import("../semantic/types.js").IfStatement} Semantic conditional.
|
|
512
|
+
*/
|
|
513
|
+
function convertIf(node, context, filename, source) {
|
|
514
|
+
const location = nodeLocation(node, filename, source)
|
|
515
|
+
const condition = requiredField(node, "condition", filename, source)
|
|
516
|
+
const consequence = requiredField(node, "consequence", filename, source)
|
|
517
|
+
const alternative = node.childForFieldName("alternative")
|
|
518
|
+
const expectedChildren = alternative ? 3 : 2
|
|
519
|
+
|
|
520
|
+
if (semanticChildren(node).length != expectedChildren) return unsupportedSyntax("go", "if initializer or shape", location)
|
|
521
|
+
return {
|
|
522
|
+
...(alternative ? {alternate: alternative.type == "if_statement"
|
|
523
|
+
? {kind: /** @type {const} */ ("Block"), location: nodeLocation(alternative, filename, source),
|
|
524
|
+
statements: [convertIf(alternative, context, filename, source)]}
|
|
525
|
+
: convertBlock(alternative, context, filename, source)} : {}),
|
|
526
|
+
condition: convertExpression(condition, filename, source),
|
|
527
|
+
consequent: convertBlock(consequence, context, filename, source),
|
|
528
|
+
kind: /** @type {const} */ ("IfStatement"),
|
|
529
|
+
location
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
* Converts one supported statement.
|
|
535
|
+
* @param {import("tree-sitter").SyntaxNode} node Statement node.
|
|
536
|
+
* @param {GoContext} context Function context.
|
|
537
|
+
* @param {string} filename Source filename.
|
|
538
|
+
* @param {string} source Complete source.
|
|
539
|
+
* @returns {import("../semantic/types.js").Statement} Semantic statement.
|
|
540
|
+
*/
|
|
541
|
+
function convertStatement(node, context, filename, source) {
|
|
542
|
+
const location = nodeLocation(node, filename, source)
|
|
543
|
+
|
|
544
|
+
if (node.type == "var_declaration") return convertLocal(node, context, filename, source)
|
|
545
|
+
if (node.type == "assignment_statement") return convertAssignment(node, filename, source)
|
|
546
|
+
if (node.type == "if_statement") return convertIf(node, context, filename, source)
|
|
547
|
+
if (node.type == "expression_statement") return convertPrint(node, filename, source)
|
|
548
|
+
if (node.type == "return_statement") {
|
|
549
|
+
const children = semanticChildren(node)
|
|
550
|
+
|
|
551
|
+
if (children.length != 1) return unsupportedSyntax("go", "return without one expression", location)
|
|
552
|
+
return {
|
|
553
|
+
expression: convertExpression(soleExpression(children[0], "return expression count", filename, source), filename, source),
|
|
554
|
+
kind: /** @type {const} */ ("ReturnStatement"),
|
|
555
|
+
location
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
return unsupportedSyntax("go", node.type, location)
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
/**
|
|
562
|
+
* Converts one lexical block.
|
|
563
|
+
* @param {import("tree-sitter").SyntaxNode} node Block node.
|
|
564
|
+
* @param {GoContext} context Function context.
|
|
565
|
+
* @param {string} filename Source filename.
|
|
566
|
+
* @param {string} source Complete source.
|
|
567
|
+
* @returns {import("../semantic/types.js").Block} Semantic block.
|
|
568
|
+
*/
|
|
569
|
+
function convertBlock(node, context, filename, source) {
|
|
570
|
+
const location = nodeLocation(node, filename, source)
|
|
571
|
+
const children = semanticChildren(node)
|
|
572
|
+
|
|
573
|
+
if (node.type != "block" || children.length > 1 || children[0]?.type != "statement_list") {
|
|
574
|
+
if (!(node.type == "block" && children.length == 0)) return unsupportedSyntax("go", "block shape", location)
|
|
575
|
+
}
|
|
576
|
+
const statements = children.length == 0 ? [] : semanticChildren(children[0])
|
|
577
|
+
|
|
578
|
+
return {kind: /** @type {const} */ ("Block"), location,
|
|
579
|
+
statements: statements.map((statement) => convertStatement(statement, context, filename, source))}
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
/**
|
|
583
|
+
* Converts one parameter.
|
|
584
|
+
* @param {import("tree-sitter").SyntaxNode} node Parameter node.
|
|
585
|
+
* @param {string} filename Source filename.
|
|
586
|
+
* @param {string} source Complete source.
|
|
587
|
+
* @returns {import("../semantic/types.js").Parameter} Semantic parameter.
|
|
588
|
+
*/
|
|
589
|
+
function convertParameter(node, filename, source) {
|
|
590
|
+
const location = nodeLocation(node, filename, source)
|
|
591
|
+
const nameNode = requiredField(node, "name", filename, source)
|
|
592
|
+
const typeNode = node.childForFieldName("type")
|
|
593
|
+
|
|
594
|
+
if (node.type != "parameter_declaration" || semanticChildren(node).length != 2) {
|
|
595
|
+
return unsupportedSyntax("go", "parameter shape", location)
|
|
596
|
+
}
|
|
597
|
+
const name = identifier(nameNode, "parameter", filename, source)
|
|
598
|
+
|
|
599
|
+
return withParserRanges({
|
|
600
|
+
kind: /** @type {const} */ ("Parameter"),
|
|
601
|
+
location,
|
|
602
|
+
name,
|
|
603
|
+
type: convertType(typeNode, "Parameter '" + name + "'", location, filename, source)
|
|
604
|
+
}, {name: nodeLocation(nameNode, filename, source)})
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
/**
|
|
608
|
+
* Converts one semantic function.
|
|
609
|
+
* @param {import("tree-sitter").SyntaxNode} node Function node.
|
|
610
|
+
* @param {GoContext} baseContext File context.
|
|
611
|
+
* @param {string} filename Source filename.
|
|
612
|
+
* @param {string} source Complete source.
|
|
613
|
+
* @returns {import("../semantic/types.js").FunctionDeclaration} Semantic function.
|
|
614
|
+
*/
|
|
615
|
+
function convertFunction(node, baseContext, filename, source) {
|
|
616
|
+
const location = nodeLocation(node, filename, source)
|
|
617
|
+
const nameNode = requiredField(node, "name", filename, source)
|
|
618
|
+
const parametersNode = requiredField(node, "parameters", filename, source)
|
|
619
|
+
const resultNode = node.childForFieldName("result")
|
|
620
|
+
const bodyNode = requiredField(node, "body", filename, source)
|
|
621
|
+
|
|
622
|
+
if (node.type != "function_declaration" || semanticChildren(node).length != (resultNode ? 4 : 3) ||
|
|
623
|
+
node.childForFieldName("receiver") || node.childForFieldName("type_parameters")) {
|
|
624
|
+
return unsupportedSyntax("go", "function declaration shape", location)
|
|
625
|
+
}
|
|
626
|
+
const name = identifier(nameNode, "function", filename, source)
|
|
627
|
+
const parameterNodes = semanticChildren(parametersNode)
|
|
628
|
+
|
|
629
|
+
if (parameterNodes.length != 2 || parameterNodes.some((parameter) => parameter.type != "parameter_declaration")) {
|
|
630
|
+
return unsupportedSyntax("go", "function parameter count or shape", nodeLocation(parametersNode, filename, source))
|
|
631
|
+
}
|
|
632
|
+
const context = {...baseContext, assignmentTargets: collectAssignmentTargets(bodyNode)}
|
|
633
|
+
|
|
634
|
+
return withParserRanges({
|
|
635
|
+
body: convertBlock(bodyNode, context, filename, source),
|
|
636
|
+
kind: /** @type {const} */ ("FunctionDeclaration"),
|
|
637
|
+
location,
|
|
638
|
+
name,
|
|
639
|
+
parameters: parameterNodes.map((parameter) => convertParameter(parameter, filename, source)),
|
|
640
|
+
returnType: convertType(resultNode, "Function '" + name + "' return", location, filename, source)
|
|
641
|
+
}, {name: nodeLocation(nameNode, filename, source)})
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
/**
|
|
645
|
+
* Converts the exact final func main() entry.
|
|
646
|
+
* @param {import("tree-sitter").SyntaxNode} node Main node.
|
|
647
|
+
* @param {GoContext} baseContext File context.
|
|
648
|
+
* @param {string} filename Source filename.
|
|
649
|
+
* @param {string} source Complete source.
|
|
650
|
+
* @returns {import("../semantic/types.js").EntryPoint} Semantic entry.
|
|
651
|
+
*/
|
|
652
|
+
function convertMain(node, baseContext, filename, source) {
|
|
653
|
+
const location = nodeLocation(node, filename, source)
|
|
654
|
+
const name = requiredField(node, "name", filename, source)
|
|
655
|
+
const parameters = requiredField(node, "parameters", filename, source)
|
|
656
|
+
const body = requiredField(node, "body", filename, source)
|
|
657
|
+
|
|
658
|
+
if (semanticChildren(node).length != 3 || name.text != "main" || semanticChildren(parameters).length != 0 ||
|
|
659
|
+
node.childForFieldName("result") || node.childForFieldName("receiver") || node.childForFieldName("type_parameters")) {
|
|
660
|
+
return unsupportedSyntax("go", "main scaffolding", location)
|
|
661
|
+
}
|
|
662
|
+
const context = {...baseContext, assignmentTargets: collectAssignmentTargets(body)}
|
|
663
|
+
|
|
664
|
+
return {body: convertBlock(body, context, filename, source), kind: /** @type {const} */ ("EntryPoint"), location}
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
/**
|
|
668
|
+
* Reports whether any print exists.
|
|
669
|
+
* @param {import("../semantic/types.js").SemanticModule} module Module.
|
|
670
|
+
* @returns {boolean} Print presence.
|
|
671
|
+
*/
|
|
672
|
+
function hasPrint(module) {
|
|
673
|
+
/**
|
|
674
|
+
* Reports whether one nested block prints.
|
|
675
|
+
* @type {(block: import("../semantic/types.js").Block) => boolean}
|
|
676
|
+
*/
|
|
677
|
+
const blockHasPrint = (block) => block.statements.some((statement) => statement.kind == "PrintStatement" ||
|
|
678
|
+
statement.kind == "IfStatement" && (blockHasPrint(statement.consequent) || Boolean(statement.alternate && blockHasPrint(statement.alternate))))
|
|
679
|
+
|
|
680
|
+
return module.functions.some(({body}) => blockHasPrint(body)) || blockHasPrint(module.entryPoint.body)
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
/**
|
|
684
|
+
* Parses the strict Task 024 Go profile.
|
|
685
|
+
* @param {{filename: string, source: string}} input Parser input.
|
|
686
|
+
* @returns {import("../semantic/types.js").SemanticModule} Semantic module.
|
|
687
|
+
*/
|
|
688
|
+
export function parseGo({filename, source}) {
|
|
689
|
+
if (!hasOnlyUnicodeScalars(source)) {
|
|
690
|
+
const offset = firstLoneSurrogateOffset(source)
|
|
691
|
+
|
|
692
|
+
throw new SemantifoldDiagnostic({
|
|
693
|
+
code: "PARSE_ERROR",
|
|
694
|
+
language: "go",
|
|
695
|
+
location: locationFromOffsets(filename, source, offset, offset + 1),
|
|
696
|
+
message: "Go source contains an invalid lone UTF-16 surrogate."
|
|
697
|
+
})
|
|
698
|
+
}
|
|
699
|
+
let tree
|
|
700
|
+
|
|
701
|
+
try {
|
|
702
|
+
tree = parser.parse(source)
|
|
703
|
+
} catch (error) {
|
|
704
|
+
return parseFailure("go", error)
|
|
705
|
+
}
|
|
706
|
+
const root = tree.rootNode
|
|
707
|
+
|
|
708
|
+
validateParserTree(root, filename, source)
|
|
709
|
+
if (root.type != "source_file") throw new Error("Tree-sitter returned Go root '" + root.type + "'.")
|
|
710
|
+
const location = moduleLocation(filename, source)
|
|
711
|
+
const comments = root.descendantsOfType("comment")
|
|
712
|
+
|
|
713
|
+
for (const comment of comments) {
|
|
714
|
+
if (/^\/\/go:/u.test(comment.text) || /^\/\/ \+build(?:\s|$)/u.test(comment.text) ||
|
|
715
|
+
/^\/\/line(?:\s|$)/u.test(comment.text) || /^\/\*line(?:\s|$)/u.test(comment.text)) {
|
|
716
|
+
return unsupportedSyntax("go", "source directive", nodeLocation(comment, filename, source))
|
|
717
|
+
}
|
|
718
|
+
if (comment.text.includes("@semantifold") && comment.text != immutableMarker) {
|
|
719
|
+
return unsupportedSyntax("go", "invalid Semantifold metadata comment", nodeLocation(comment, filename, source))
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
const children = semanticChildren(root)
|
|
723
|
+
|
|
724
|
+
if (children.length < 3 || children[0].type != "package_clause") {
|
|
725
|
+
return unsupportedSyntax("go", "compilation-unit scaffolding", location)
|
|
726
|
+
}
|
|
727
|
+
const packageChildren = semanticChildren(children[0])
|
|
728
|
+
|
|
729
|
+
if (packageChildren.length != 1 || packageChildren[0].type != "package_identifier" || packageChildren[0].text != "main") {
|
|
730
|
+
return unsupportedSyntax("go", "package main scaffolding", nodeLocation(children[0], filename, source))
|
|
731
|
+
}
|
|
732
|
+
let memberStart = 1
|
|
733
|
+
let hasFmtImport = false
|
|
734
|
+
|
|
735
|
+
if (children[1]?.type == "import_declaration") {
|
|
736
|
+
const declaration = children[1]
|
|
737
|
+
const imports = semanticChildren(declaration)
|
|
738
|
+
|
|
739
|
+
if (imports.length != 1 || imports[0].type != "import_spec" || semanticChildren(imports[0]).length != 1 ||
|
|
740
|
+
imports[0].childForFieldName("path")?.type != "interpreted_string_literal" ||
|
|
741
|
+
imports[0].childForFieldName("path")?.text != '"fmt"') {
|
|
742
|
+
return unsupportedSyntax("go", "fmt import scaffolding", nodeLocation(declaration, filename, source))
|
|
743
|
+
}
|
|
744
|
+
hasFmtImport = true
|
|
745
|
+
memberStart = 2
|
|
746
|
+
}
|
|
747
|
+
const members = children.slice(memberStart)
|
|
748
|
+
|
|
749
|
+
if (members.length < 2 || members.some((member) => member.type != "function_declaration")) {
|
|
750
|
+
return unsupportedSyntax("go", "top-level declarations", location)
|
|
751
|
+
}
|
|
752
|
+
const mainNodes = members.filter((member) => member.childForFieldName("name")?.text == "main")
|
|
753
|
+
|
|
754
|
+
if (mainNodes.length != 1 || members.at(-1)?.id != mainNodes[0].id) {
|
|
755
|
+
return unsupportedSyntax("go", "main ordering", location)
|
|
756
|
+
}
|
|
757
|
+
const baseContext = {assignmentTargets: new Set(), comments, usedMarkers: new Set()}
|
|
758
|
+
const module = {
|
|
759
|
+
entryPoint: convertMain(mainNodes[0], baseContext, filename, source),
|
|
760
|
+
functions: members.slice(0, -1).map((member) => convertFunction(member, baseContext, filename, source)),
|
|
761
|
+
kind: /** @type {const} */ ("Module"),
|
|
762
|
+
location
|
|
763
|
+
}
|
|
764
|
+
const invalidMarker = comments.find((comment) => comment.text == immutableMarker && !baseContext.usedMarkers.has(comment))
|
|
765
|
+
|
|
766
|
+
if (invalidMarker) return unsupportedSyntax("go", "unattached immutable marker", nodeLocation(invalidMarker, filename, source))
|
|
767
|
+
if (hasFmtImport != hasPrint(module)) return unsupportedSyntax("go", "fmt import and print usage mismatch", location)
|
|
768
|
+
validateParsedModule(module, "go")
|
|
769
|
+
return module
|
|
770
|
+
}
|