@soundscript/soundscript 0.1.12 → 0.1.15
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/package.json +15 -6
- package/project-transform/index.js +2 -0
- package/project-transform/index.ts +8 -0
- package/project-transform/src/annotation_syntax.js +948 -0
- package/project-transform/src/annotation_syntax.ts +1217 -0
- package/project-transform/src/build_package.js +475 -0
- package/project-transform/src/build_package.ts +683 -0
- package/project-transform/src/bundled/portable-web-globals.d.ts +153 -0
- package/project-transform/src/bundled/runtime_externs.js +220 -0
- package/project-transform/src/bundled/runtime_externs.ts +237 -0
- package/project-transform/src/bundled/sound-libs/lib.decorators.d.ts +385 -0
- package/project-transform/src/bundled/sound-libs/lib.decorators.legacy.d.ts +22 -0
- package/project-transform/src/bundled/sound-libs/lib.dom.asynciterable.d.ts +42 -0
- package/project-transform/src/bundled/sound-libs/lib.dom.d.ts +39440 -0
- package/project-transform/src/bundled/sound-libs/lib.es2015.collection.d.ts +149 -0
- package/project-transform/src/bundled/sound-libs/lib.es2015.core.d.ts +657 -0
- package/project-transform/src/bundled/sound-libs/lib.es2015.d.ts +28 -0
- package/project-transform/src/bundled/sound-libs/lib.es2015.generator.d.ts +77 -0
- package/project-transform/src/bundled/sound-libs/lib.es2015.iterable.d.ts +616 -0
- package/project-transform/src/bundled/sound-libs/lib.es2015.promise.d.ts +80 -0
- package/project-transform/src/bundled/sound-libs/lib.es2015.proxy.d.ts +128 -0
- package/project-transform/src/bundled/sound-libs/lib.es2015.reflect.d.ts +144 -0
- package/project-transform/src/bundled/sound-libs/lib.es2015.symbol.d.ts +46 -0
- package/project-transform/src/bundled/sound-libs/lib.es2015.symbol.wellknown.d.ts +170 -0
- package/project-transform/src/bundled/sound-libs/lib.es2016.array.include.d.ts +116 -0
- package/project-transform/src/bundled/sound-libs/lib.es2016.d.ts +21 -0
- package/project-transform/src/bundled/sound-libs/lib.es2017.arraybuffer.d.ts +21 -0
- package/project-transform/src/bundled/sound-libs/lib.es2017.d.ts +26 -0
- package/project-transform/src/bundled/sound-libs/lib.es2017.date.d.ts +31 -0
- package/project-transform/src/bundled/sound-libs/lib.es2017.object.d.ts +49 -0
- package/project-transform/src/bundled/sound-libs/lib.es2017.string.d.ts +45 -0
- package/project-transform/src/bundled/sound-libs/lib.es2017.typedarrays.d.ts +53 -0
- package/project-transform/src/bundled/sound-libs/lib.es2018.asyncgenerator.d.ts +77 -0
- package/project-transform/src/bundled/sound-libs/lib.es2018.asynciterable.d.ts +57 -0
- package/project-transform/src/bundled/sound-libs/lib.es2018.d.ts +24 -0
- package/project-transform/src/bundled/sound-libs/lib.es2018.promise.d.ts +30 -0
- package/project-transform/src/bundled/sound-libs/lib.es2018.regexp.d.ts +37 -0
- package/project-transform/src/bundled/sound-libs/lib.es2019.array.d.ts +79 -0
- package/project-transform/src/bundled/sound-libs/lib.es2019.d.ts +24 -0
- package/project-transform/src/bundled/sound-libs/lib.es2019.object.d.ts +47 -0
- package/project-transform/src/bundled/sound-libs/lib.es2019.string.d.ts +37 -0
- package/project-transform/src/bundled/sound-libs/lib.es2019.symbol.d.ts +24 -0
- package/project-transform/src/bundled/sound-libs/lib.es2020.bigint.d.ts +765 -0
- package/project-transform/src/bundled/sound-libs/lib.es2020.d.ts +27 -0
- package/project-transform/src/bundled/sound-libs/lib.es2020.date.d.ts +42 -0
- package/project-transform/src/bundled/sound-libs/lib.es2020.number.d.ts +28 -0
- package/project-transform/src/bundled/sound-libs/lib.es2020.promise.d.ts +49 -0
- package/project-transform/src/bundled/sound-libs/lib.es2020.string.d.ts +44 -0
- package/project-transform/src/bundled/sound-libs/lib.es2020.symbol.wellknown.d.ts +41 -0
- package/project-transform/src/bundled/sound-libs/lib.es2021.d.ts +23 -0
- package/project-transform/src/bundled/sound-libs/lib.es2021.promise.d.ts +48 -0
- package/project-transform/src/bundled/sound-libs/lib.es2021.string.d.ts +33 -0
- package/project-transform/src/bundled/sound-libs/lib.es2021.weakref.d.ts +78 -0
- package/project-transform/src/bundled/sound-libs/lib.es2022.array.d.ts +121 -0
- package/project-transform/src/bundled/sound-libs/lib.es2022.d.ts +25 -0
- package/project-transform/src/bundled/sound-libs/lib.es2022.error.d.ts +75 -0
- package/project-transform/src/bundled/sound-libs/lib.es2022.object.d.ts +26 -0
- package/project-transform/src/bundled/sound-libs/lib.es2022.regexp.d.ts +39 -0
- package/project-transform/src/bundled/sound-libs/lib.es2022.string.d.ts +25 -0
- package/project-transform/src/bundled/sound-libs/lib.es2023.array.d.ts +924 -0
- package/project-transform/src/bundled/sound-libs/lib.es2023.collection.d.ts +21 -0
- package/project-transform/src/bundled/sound-libs/lib.es2023.d.ts +22 -0
- package/project-transform/src/bundled/sound-libs/lib.es2024.arraybuffer.d.ts +65 -0
- package/project-transform/src/bundled/sound-libs/lib.es2024.collection.d.ts +29 -0
- package/project-transform/src/bundled/sound-libs/lib.es2024.d.ts +26 -0
- package/project-transform/src/bundled/sound-libs/lib.es2024.object.d.ts +33 -0
- package/project-transform/src/bundled/sound-libs/lib.es2024.promise.d.ts +35 -0
- package/project-transform/src/bundled/sound-libs/lib.es2024.regexp.d.ts +25 -0
- package/project-transform/src/bundled/sound-libs/lib.es2024.string.d.ts +29 -0
- package/project-transform/src/bundled/sound-libs/lib.es5.d.ts +4924 -0
- package/project-transform/src/bundled/sound_stdlib.js +142 -0
- package/project-transform/src/bundled/sound_stdlib.ts +180 -0
- package/project-transform/src/checker/analyze_project.js +1361 -0
- package/project-transform/src/checker/analyze_project.ts +2246 -0
- package/project-transform/src/checker/diagnostics.js +112 -0
- package/project-transform/src/checker/diagnostics.ts +222 -0
- package/project-transform/src/checker/engine/context.js +235 -0
- package/project-transform/src/checker/engine/context.ts +340 -0
- package/project-transform/src/checker/engine/diagnostic_codes.js +72 -0
- package/project-transform/src/checker/engine/diagnostic_codes.ts +95 -0
- package/project-transform/src/checker/engine/facts.js +35 -0
- package/project-transform/src/checker/engine/facts.ts +48 -0
- package/project-transform/src/checker/engine/types.js +1 -0
- package/project-transform/src/checker/engine/types.ts +485 -0
- package/project-transform/src/checker/proof_escape_hatch_diagnostics.js +104 -0
- package/project-transform/src/checker/proof_escape_hatch_diagnostics.ts +173 -0
- package/project-transform/src/checker/rules/async_surface.js +231 -0
- package/project-transform/src/checker/rules/async_surface.ts +335 -0
- package/project-transform/src/checker/rules/class_lifecycle.js +798 -0
- package/project-transform/src/checker/rules/class_lifecycle.ts +1276 -0
- package/project-transform/src/checker/rules/directive_validation.js +571 -0
- package/project-transform/src/checker/rules/directive_validation.ts +938 -0
- package/project-transform/src/checker/rules/directives.js +23 -0
- package/project-transform/src/checker/rules/directives.ts +25 -0
- package/project-transform/src/checker/rules/flow.js +202 -0
- package/project-transform/src/checker/rules/flow.ts +333 -0
- package/project-transform/src/checker/rules/flow_facts.js +601 -0
- package/project-transform/src/checker/rules/flow_facts.ts +978 -0
- package/project-transform/src/checker/rules/flow_invalidation.js +1119 -0
- package/project-transform/src/checker/rules/flow_invalidation.ts +2150 -0
- package/project-transform/src/checker/rules/flow_shared.js +2822 -0
- package/project-transform/src/checker/rules/flow_shared.ts +4383 -0
- package/project-transform/src/checker/rules/foreign_boundary.js +120 -0
- package/project-transform/src/checker/rules/foreign_boundary.ts +196 -0
- package/project-transform/src/checker/rules/foreign_projection.js +279 -0
- package/project-transform/src/checker/rules/foreign_projection.ts +425 -0
- package/project-transform/src/checker/rules/generated_helpers.js +13 -0
- package/project-transform/src/checker/rules/generated_helpers.ts +18 -0
- package/project-transform/src/checker/rules/index.js +35 -0
- package/project-transform/src/checker/rules/index.ts +49 -0
- package/project-transform/src/checker/rules/namespace_object.js +845 -0
- package/project-transform/src/checker/rules/namespace_object.ts +1224 -0
- package/project-transform/src/checker/rules/non_ordinary_recovery.js +1328 -0
- package/project-transform/src/checker/rules/non_ordinary_recovery.ts +2391 -0
- package/project-transform/src/checker/rules/null_prototype.js +3 -0
- package/project-transform/src/checker/rules/null_prototype.ts +6 -0
- package/project-transform/src/checker/rules/overloads.js +181 -0
- package/project-transform/src/checker/rules/overloads.ts +317 -0
- package/project-transform/src/checker/rules/predicate_verification.js +691 -0
- package/project-transform/src/checker/rules/predicate_verification.ts +1088 -0
- package/project-transform/src/checker/rules/prototype_hardening.js +237 -0
- package/project-transform/src/checker/rules/prototype_hardening.ts +343 -0
- package/project-transform/src/checker/rules/receiver_discipline.js +263 -0
- package/project-transform/src/checker/rules/receiver_discipline.ts +356 -0
- package/project-transform/src/checker/rules/relations.js +6861 -0
- package/project-transform/src/checker/rules/relations.ts +12158 -0
- package/project-transform/src/checker/rules/resolved_builtins.js +274 -0
- package/project-transform/src/checker/rules/resolved_builtins.ts +438 -0
- package/project-transform/src/checker/rules/trust.js +217 -0
- package/project-transform/src/checker/rules/trust.ts +301 -0
- package/project-transform/src/checker/rules/type_guards.js +173 -0
- package/project-transform/src/checker/rules/type_guards.ts +257 -0
- package/project-transform/src/checker/rules/universal.js +17 -0
- package/project-transform/src/checker/rules/universal.ts +22 -0
- package/project-transform/src/checker/rules/unsafe_value_origin.js +80 -0
- package/project-transform/src/checker/rules/unsafe_value_origin.ts +125 -0
- package/project-transform/src/checker/rules/unsound_imports.js +218 -0
- package/project-transform/src/checker/rules/unsound_imports.ts +301 -0
- package/project-transform/src/checker/rules/unsound_syntax.js +1695 -0
- package/project-transform/src/checker/rules/unsound_syntax.ts +2540 -0
- package/project-transform/src/checker/rules/value_types.js +206 -0
- package/project-transform/src/checker/rules/value_types.ts +407 -0
- package/project-transform/src/checker/timing.js +43 -0
- package/project-transform/src/checker/timing.ts +78 -0
- package/project-transform/src/checker/unsupported_feature_messages.js +337 -0
- package/project-transform/src/checker/unsupported_feature_messages.ts +531 -0
- package/project-transform/src/cli.js +892 -0
- package/project-transform/src/cli.ts +1476 -0
- package/project-transform/src/compiler/compile_project.js +319 -0
- package/project-transform/src/compiler/compile_project.ts +508 -0
- package/project-transform/src/compiler/errors.js +10 -0
- package/project-transform/src/compiler/errors.ts +29 -0
- package/project-transform/src/compiler/ir.js +1 -0
- package/project-transform/src/compiler/ir.ts +1526 -0
- package/project-transform/src/compiler/lower.js +30550 -0
- package/project-transform/src/compiler/lower.ts +43645 -0
- package/project-transform/src/compiler/lower_arrays.js +140 -0
- package/project-transform/src/compiler/lower_arrays.ts +190 -0
- package/project-transform/src/compiler/lower_strings.js +121 -0
- package/project-transform/src/compiler/lower_strings.ts +198 -0
- package/project-transform/src/compiler/lower_tagged.js +329 -0
- package/project-transform/src/compiler/lower_tagged.ts +427 -0
- package/project-transform/src/compiler/lower_views.js +171 -0
- package/project-transform/src/compiler/lower_views.ts +251 -0
- package/project-transform/src/compiler/object_keys.js +25 -0
- package/project-transform/src/compiler/object_keys.ts +35 -0
- package/project-transform/src/compiler/runtime_ir.js +30 -0
- package/project-transform/src/compiler/runtime_ir.ts +727 -0
- package/project-transform/src/compiler/tagged_boundary.js +18 -0
- package/project-transform/src/compiler/tagged_boundary.ts +37 -0
- package/project-transform/src/compiler/toolchain.js +170 -0
- package/project-transform/src/compiler/toolchain.ts +229 -0
- package/project-transform/src/compiler/unicode_case_data.js +2102 -0
- package/project-transform/src/compiler/unicode_case_data.ts +2112 -0
- package/project-transform/src/compiler/wasm_js_host_runtime.js +656 -0
- package/project-transform/src/compiler/wasm_js_host_runtime.ts +762 -0
- package/project-transform/src/compiler/wat_arrays.js +3132 -0
- package/project-transform/src/compiler/wat_arrays.ts +3768 -0
- package/project-transform/src/compiler/wat_emitter.js +17952 -0
- package/project-transform/src/compiler/wat_emitter.ts +22812 -0
- package/project-transform/src/compiler/wat_strings.js +129 -0
- package/project-transform/src/compiler/wat_strings.ts +187 -0
- package/project-transform/src/compiler/wat_tagged.js +548 -0
- package/project-transform/src/compiler/wat_tagged.ts +674 -0
- package/project-transform/src/compiler_generator_runner.js +153 -0
- package/project-transform/src/compiler_generator_runner.ts +171 -0
- package/project-transform/src/compiler_object_test_helpers.js +69 -0
- package/project-transform/src/compiler_object_test_helpers.ts +96 -0
- package/project-transform/src/compiler_promise_runner.js +2116 -0
- package/project-transform/src/compiler_promise_runner.ts +2184 -0
- package/project-transform/src/compiler_test_helpers.js +854 -0
- package/project-transform/src/compiler_test_helpers.ts +1087 -0
- package/project-transform/src/config.js +568 -0
- package/project-transform/src/config.ts +892 -0
- package/project-transform/src/diagnostic_metadata.js +67 -0
- package/project-transform/src/diagnostic_metadata.ts +99 -0
- package/project-transform/src/diagnostic_reference.js +1368 -0
- package/project-transform/src/diagnostic_reference.ts +1523 -0
- package/project-transform/src/editor_diagnostics_worker.js +176 -0
- package/project-transform/src/editor_diagnostics_worker.ts +250 -0
- package/project-transform/src/editor_projection.js +224 -0
- package/project-transform/src/editor_projection.ts +421 -0
- package/project-transform/src/frontend/builtin_expanded_program_test_cleanup.js +47 -0
- package/project-transform/src/frontend/builtin_expanded_program_test_cleanup.ts +72 -0
- package/project-transform/src/frontend/builtin_macro_support.js +842 -0
- package/project-transform/src/frontend/builtin_macro_support.ts +1386 -0
- package/project-transform/src/frontend/builtin_macros.js +409 -0
- package/project-transform/src/frontend/builtin_macros.ts +542 -0
- package/project-transform/src/frontend/component_poc_runtime.js +279 -0
- package/project-transform/src/frontend/component_poc_runtime.ts +372 -0
- package/project-transform/src/frontend/css_macro.js +148 -0
- package/project-transform/src/frontend/css_macro.ts +222 -0
- package/project-transform/src/frontend/derive_macros.js +2072 -0
- package/project-transform/src/frontend/derive_macros.ts +3188 -0
- package/project-transform/src/frontend/embedded_fragment_support.js +106 -0
- package/project-transform/src/frontend/embedded_fragment_support.ts +172 -0
- package/project-transform/src/frontend/error_normalization.js +403 -0
- package/project-transform/src/frontend/error_normalization.ts +832 -0
- package/project-transform/src/frontend/error_stdlib_support.js +1 -0
- package/project-transform/src/frontend/error_stdlib_support.ts +6 -0
- package/project-transform/src/frontend/expand_project.js +169 -0
- package/project-transform/src/frontend/expand_project.ts +248 -0
- package/project-transform/src/frontend/format_soundscript.js +297 -0
- package/project-transform/src/frontend/format_soundscript.ts +582 -0
- package/project-transform/src/frontend/graphql_macro.js +174 -0
- package/project-transform/src/frontend/graphql_macro.ts +253 -0
- package/project-transform/src/frontend/hash_context.js +83 -0
- package/project-transform/src/frontend/hash_context.ts +113 -0
- package/project-transform/src/frontend/hkt_macro.js +448 -0
- package/project-transform/src/frontend/hkt_macro.ts +897 -0
- package/project-transform/src/frontend/import_binding_usage.js +190 -0
- package/project-transform/src/frontend/import_binding_usage.ts +277 -0
- package/project-transform/src/frontend/macro_advanced_backend_adapter.js +58 -0
- package/project-transform/src/frontend/macro_advanced_backend_adapter.ts +123 -0
- package/project-transform/src/frontend/macro_advanced_context.js +826 -0
- package/project-transform/src/frontend/macro_advanced_context.ts +1102 -0
- package/project-transform/src/frontend/macro_advanced_output.js +21 -0
- package/project-transform/src/frontend/macro_advanced_output.ts +41 -0
- package/project-transform/src/frontend/macro_api.js +353 -0
- package/project-transform/src/frontend/macro_api.ts +1722 -0
- package/project-transform/src/frontend/macro_api_internal.js +35 -0
- package/project-transform/src/frontend/macro_api_internal.ts +80 -0
- package/project-transform/src/frontend/macro_api_module_support.js +39 -0
- package/project-transform/src/frontend/macro_api_module_support.ts +65 -0
- package/project-transform/src/frontend/macro_backend_adapter.js +272 -0
- package/project-transform/src/frontend/macro_backend_adapter.ts +420 -0
- package/project-transform/src/frontend/macro_context.js +816 -0
- package/project-transform/src/frontend/macro_context.ts +1105 -0
- package/project-transform/src/frontend/macro_debug.js +99 -0
- package/project-transform/src/frontend/macro_debug.ts +157 -0
- package/project-transform/src/frontend/macro_definition_support.js +28 -0
- package/project-transform/src/frontend/macro_definition_support.ts +73 -0
- package/project-transform/src/frontend/macro_errors.js +40 -0
- package/project-transform/src/frontend/macro_errors.ts +70 -0
- package/project-transform/src/frontend/macro_expander.js +919 -0
- package/project-transform/src/frontend/macro_expander.ts +1611 -0
- package/project-transform/src/frontend/macro_factory_support.js +176 -0
- package/project-transform/src/frontend/macro_factory_support.ts +263 -0
- package/project-transform/src/frontend/macro_host_ast_internal.js +64 -0
- package/project-transform/src/frontend/macro_host_ast_internal.ts +109 -0
- package/project-transform/src/frontend/macro_index.js +27 -0
- package/project-transform/src/frontend/macro_index.ts +50 -0
- package/project-transform/src/frontend/macro_loader.js +281 -0
- package/project-transform/src/frontend/macro_loader.ts +506 -0
- package/project-transform/src/frontend/macro_operand_semantics.js +838 -0
- package/project-transform/src/frontend/macro_operand_semantics.ts +1489 -0
- package/project-transform/src/frontend/macro_output.js +54 -0
- package/project-transform/src/frontend/macro_output.ts +123 -0
- package/project-transform/src/frontend/macro_parser.js +611 -0
- package/project-transform/src/frontend/macro_parser.ts +832 -0
- package/project-transform/src/frontend/macro_resolver.js +69 -0
- package/project-transform/src/frontend/macro_resolver.ts +125 -0
- package/project-transform/src/frontend/macro_rewrite.js +285 -0
- package/project-transform/src/frontend/macro_rewrite.ts +442 -0
- package/project-transform/src/frontend/macro_runtime_support.js +232 -0
- package/project-transform/src/frontend/macro_runtime_support.ts +324 -0
- package/project-transform/src/frontend/macro_scanner.js +393 -0
- package/project-transform/src/frontend/macro_scanner.ts +455 -0
- package/project-transform/src/frontend/macro_semantic_backend_adapter.js +87 -0
- package/project-transform/src/frontend/macro_semantic_backend_adapter.ts +166 -0
- package/project-transform/src/frontend/macro_semantic_context.js +5 -0
- package/project-transform/src/frontend/macro_semantic_context.ts +12 -0
- package/project-transform/src/frontend/macro_semantic_output.js +24 -0
- package/project-transform/src/frontend/macro_semantic_output.ts +47 -0
- package/project-transform/src/frontend/macro_semantic_types.js +1 -0
- package/project-transform/src/frontend/macro_semantic_types.ts +98 -0
- package/project-transform/src/frontend/macro_semantics.js +1172 -0
- package/project-transform/src/frontend/macro_semantics.ts +1502 -0
- package/project-transform/src/frontend/macro_site_kind_support.js +164 -0
- package/project-transform/src/frontend/macro_site_kind_support.ts +255 -0
- package/project-transform/src/frontend/macro_syntax_internal.js +1950 -0
- package/project-transform/src/frontend/macro_syntax_internal.ts +3338 -0
- package/project-transform/src/frontend/macro_templates.js +57 -0
- package/project-transform/src/frontend/macro_templates.ts +143 -0
- package/project-transform/src/frontend/macro_test_helpers.js +82 -0
- package/project-transform/src/frontend/macro_test_helpers.ts +136 -0
- package/project-transform/src/frontend/macro_types.js +1 -0
- package/project-transform/src/frontend/macro_types.ts +103 -0
- package/project-transform/src/frontend/macro_vm.js +39 -0
- package/project-transform/src/frontend/macro_vm.ts +113 -0
- package/project-transform/src/frontend/match_macro.js +885 -0
- package/project-transform/src/frontend/match_macro.ts +1220 -0
- package/project-transform/src/frontend/numeric_normalization.js +824 -0
- package/project-transform/src/frontend/numeric_normalization.ts +1380 -0
- package/project-transform/src/frontend/numeric_prelude.js +278 -0
- package/project-transform/src/frontend/numeric_prelude.ts +370 -0
- package/project-transform/src/frontend/project_frontend.js +2396 -0
- package/project-transform/src/frontend/project_frontend.ts +3776 -0
- package/project-transform/src/frontend/project_macro_support.js +1401 -0
- package/project-transform/src/frontend/project_macro_support.ts +2137 -0
- package/project-transform/src/frontend/sql_macro.js +175 -0
- package/project-transform/src/frontend/sql_macro.ts +254 -0
- package/project-transform/src/frontend/sql_stdlib_support.js +1 -0
- package/project-transform/src/frontend/sql_stdlib_support.ts +6 -0
- package/project-transform/src/frontend/std_package_support.js +228 -0
- package/project-transform/src/frontend/std_package_support.ts +400 -0
- package/project-transform/src/frontend/value_normalization.js +306 -0
- package/project-transform/src/frontend/value_normalization.ts +599 -0
- package/project-transform/src/lsp/project_service.js +4771 -0
- package/project-transform/src/lsp/project_service.ts +7580 -0
- package/project-transform/src/lsp/protocol.js +9 -0
- package/project-transform/src/lsp/protocol.ts +38 -0
- package/project-transform/src/lsp/server.js +355 -0
- package/project-transform/src/lsp/server.ts +671 -0
- package/project-transform/src/lsp/session.js +49 -0
- package/project-transform/src/lsp/session.ts +48 -0
- package/project-transform/src/lsp/timing.js +43 -0
- package/project-transform/src/lsp/timing.ts +76 -0
- package/project-transform/src/lsp/transport.js +205 -0
- package/project-transform/src/lsp/transport.ts +253 -0
- package/project-transform/src/lsp_main.js +5 -0
- package/project-transform/src/lsp_main.ts +7 -0
- package/project-transform/src/macros.d.ts +1 -0
- package/project-transform/src/macros.js +1 -0
- package/project-transform/src/macros.ts +1 -0
- package/project-transform/src/main.js +24 -0
- package/project-transform/src/main.ts +28 -0
- package/project-transform/src/platform/host.js +264 -0
- package/project-transform/src/platform/host.ts +343 -0
- package/project-transform/src/platform/path.js +8 -0
- package/project-transform/src/platform/path.ts +20 -0
- package/project-transform/src/public_macro_api/macro_api.d.ts +1054 -0
- package/project-transform/src/public_macro_api/macro_semantic_types.d.ts +66 -0
- package/project-transform/src/public_macro_api/macro_types.d.ts +70 -0
- package/project-transform/src/run_program.js +14 -0
- package/project-transform/src/run_program.ts +33 -0
- package/project-transform/src/runtime/materialize.js +371 -0
- package/project-transform/src/runtime/materialize.ts +502 -0
- package/project-transform/src/runtime/on_demand.js +203 -0
- package/project-transform/src/runtime/on_demand.ts +305 -0
- package/project-transform/src/runtime/source_maps.js +205 -0
- package/project-transform/src/runtime/source_maps.ts +297 -0
- package/project-transform/src/runtime/transform.js +148 -0
- package/project-transform/src/runtime/transform.ts +295 -0
- package/project-transform/src/service/types.js +1 -0
- package/project-transform/src/service/types.ts +22 -0
- package/project-transform/src/soundscript_packages.js +477 -0
- package/project-transform/src/soundscript_packages.ts +754 -0
- package/project-transform/src/soundscript_runtime_specifiers.js +88 -0
- package/project-transform/src/soundscript_runtime_specifiers.ts +96 -0
- package/project-transform/src/stdlib/async.d.ts +81 -0
- package/project-transform/src/stdlib/async.js +213 -0
- package/project-transform/src/stdlib/async.ts +315 -0
- package/project-transform/src/stdlib/codec.d.ts +32 -0
- package/project-transform/src/stdlib/codec.js +30 -0
- package/project-transform/src/stdlib/codec.ts +76 -0
- package/project-transform/src/stdlib/compare.d.ts +28 -0
- package/project-transform/src/stdlib/compare.js +115 -0
- package/project-transform/src/stdlib/compare.ts +151 -0
- package/project-transform/src/stdlib/css.d.ts +16 -0
- package/project-transform/src/stdlib/css.js +9 -0
- package/project-transform/src/stdlib/css.ts +28 -0
- package/project-transform/src/stdlib/debug.d.ts +2 -0
- package/project-transform/src/stdlib/debug.js +9 -0
- package/project-transform/src/stdlib/debug.ts +10 -0
- package/project-transform/src/stdlib/decode.d.ts +86 -0
- package/project-transform/src/stdlib/decode.js +254 -0
- package/project-transform/src/stdlib/decode.ts +390 -0
- package/project-transform/src/stdlib/derive.d.ts +6 -0
- package/project-transform/src/stdlib/derive.js +7 -0
- package/project-transform/src/stdlib/derive.ts +7 -0
- package/project-transform/src/stdlib/encode.d.ts +100 -0
- package/project-transform/src/stdlib/encode.js +130 -0
- package/project-transform/src/stdlib/encode.ts +259 -0
- package/project-transform/src/stdlib/failures.d.ts +23 -0
- package/project-transform/src/stdlib/failures.js +41 -0
- package/project-transform/src/stdlib/failures.ts +64 -0
- package/project-transform/src/stdlib/fetch.d.ts +67 -0
- package/project-transform/src/stdlib/fetch.js +5 -0
- package/project-transform/src/stdlib/fetch.ts +11 -0
- package/project-transform/src/stdlib/graphql.d.ts +16 -0
- package/project-transform/src/stdlib/graphql.js +9 -0
- package/project-transform/src/stdlib/graphql.ts +28 -0
- package/project-transform/src/stdlib/hash.d.ts +34 -0
- package/project-transform/src/stdlib/hash.js +110 -0
- package/project-transform/src/stdlib/hash.ts +188 -0
- package/project-transform/src/stdlib/hkt.d.ts +40 -0
- package/project-transform/src/stdlib/hkt.js +3 -0
- package/project-transform/src/stdlib/hkt.ts +41 -0
- package/project-transform/src/stdlib/index.d.ts +9 -0
- package/project-transform/src/stdlib/index.js +15 -0
- package/project-transform/src/stdlib/index.ts +23 -0
- package/project-transform/src/stdlib/json.d.ts +125 -0
- package/project-transform/src/stdlib/json.js +764 -0
- package/project-transform/src/stdlib/json.ts +1034 -0
- package/project-transform/src/stdlib/match.d.ts +11 -0
- package/project-transform/src/stdlib/match.js +13 -0
- package/project-transform/src/stdlib/match.ts +26 -0
- package/project-transform/src/stdlib/numerics.d.ts +523 -0
- package/project-transform/src/stdlib/numerics.js +1356 -0
- package/project-transform/src/stdlib/numerics.ts +1937 -0
- package/project-transform/src/stdlib/random.d.ts +19 -0
- package/project-transform/src/stdlib/random.js +3 -0
- package/project-transform/src/stdlib/random.ts +5 -0
- package/project-transform/src/stdlib/result.d.ts +68 -0
- package/project-transform/src/stdlib/result.js +139 -0
- package/project-transform/src/stdlib/result.ts +248 -0
- package/project-transform/src/stdlib/sql.d.ts +22 -0
- package/project-transform/src/stdlib/sql.js +23 -0
- package/project-transform/src/stdlib/sql.ts +53 -0
- package/project-transform/src/stdlib/text.d.ts +24 -0
- package/project-transform/src/stdlib/text.js +3 -0
- package/project-transform/src/stdlib/text.ts +4 -0
- package/project-transform/src/stdlib/thunk.d.ts +2 -0
- package/project-transform/src/stdlib/thunk.js +9 -0
- package/project-transform/src/stdlib/thunk.ts +15 -0
- package/project-transform/src/stdlib/typeclasses.d.ts +57 -0
- package/project-transform/src/stdlib/typeclasses.js +78 -0
- package/project-transform/src/stdlib/typeclasses.ts +173 -0
- package/project-transform/src/stdlib/url.d.ts +37 -0
- package/project-transform/src/stdlib/url.js +3 -0
- package/project-transform/src/stdlib/url.ts +4 -0
- package/project-transform/src/stdlib/value.d.ts +9 -0
- package/project-transform/src/stdlib/value.js +104 -0
- package/project-transform/src/stdlib/value.ts +133 -0
- package/project-transform/src/test_installed_stdlib.js +147 -0
- package/project-transform/src/test_installed_stdlib.ts +245 -0
- package/project-transform/src/test_macro_package_fixture.js +50 -0
- package/project-transform/src/test_macro_package_fixture.ts +68 -0
- package/project-transform/src/value_deep_safe.js +191 -0
- package/project-transform/src/value_deep_safe.ts +273 -0
|
@@ -0,0 +1,571 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
import { BUILTIN_DIRECTIVE_NAMES } from '../../annotation_syntax.js';
|
|
3
|
+
import { SOUND_DIAGNOSTIC_CODES, SOUND_DIAGNOSTIC_MESSAGES } from '../engine/diagnostic_codes.js';
|
|
4
|
+
import { isInteropTargetNode } from './trust.js';
|
|
5
|
+
function createDiagnostic(filePath, line, column, code, message, options) {
|
|
6
|
+
return {
|
|
7
|
+
source: 'sound',
|
|
8
|
+
code,
|
|
9
|
+
category: 'error',
|
|
10
|
+
message,
|
|
11
|
+
metadata: options?.metadata,
|
|
12
|
+
notes: options?.notes,
|
|
13
|
+
hint: options?.hint,
|
|
14
|
+
filePath,
|
|
15
|
+
line,
|
|
16
|
+
column,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function isUnsafeTargetNode(targetNode) {
|
|
20
|
+
return !ts.isImportClause(targetNode) &&
|
|
21
|
+
!ts.isImportDeclaration(targetNode) &&
|
|
22
|
+
!ts.isImportEqualsDeclaration(targetNode);
|
|
23
|
+
}
|
|
24
|
+
function hasDeclareModifier(targetNode) {
|
|
25
|
+
return ts.canHaveModifiers(targetNode) &&
|
|
26
|
+
ts.getModifiers(targetNode)?.some((modifier) => modifier.kind === ts.SyntaxKind.DeclareKeyword) === true;
|
|
27
|
+
}
|
|
28
|
+
function normalizeFileName(fileName) {
|
|
29
|
+
return fileName.replaceAll('\\', '/').toLowerCase();
|
|
30
|
+
}
|
|
31
|
+
function isStandardLibraryExternProofSourceFile(sourceFile) {
|
|
32
|
+
const normalizedFileName = normalizeFileName(sourceFile.fileName);
|
|
33
|
+
const baseName = normalizedFileName.split('/').at(-1) ?? normalizedFileName;
|
|
34
|
+
return normalizedFileName.includes('/src/bundled/sound-libs/') ||
|
|
35
|
+
(baseName.startsWith('lib.') &&
|
|
36
|
+
(baseName.endsWith('.d.ts') || baseName.endsWith('.d.mts') || baseName.endsWith('.d.cts')));
|
|
37
|
+
}
|
|
38
|
+
function resolveReferencedTypeSymbol(context, typeNode) {
|
|
39
|
+
const symbol = ts.isImportTypeNode(typeNode)
|
|
40
|
+
? typeNode.qualifier
|
|
41
|
+
? context.checker.getSymbolAtLocation(typeNode.qualifier)
|
|
42
|
+
: undefined
|
|
43
|
+
: ts.isTypeReferenceNode(typeNode)
|
|
44
|
+
? context.checker.getSymbolAtLocation(typeNode.typeName)
|
|
45
|
+
: ts.isTypeQueryNode(typeNode)
|
|
46
|
+
? context.checker.getSymbolAtLocation(typeNode.exprName)
|
|
47
|
+
: context.checker.getSymbolAtLocation(typeNode.expression);
|
|
48
|
+
if (!symbol) {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
return (symbol.flags & ts.SymbolFlags.Alias) !== 0 ? context.checker.getAliasedSymbol(symbol) : symbol;
|
|
52
|
+
}
|
|
53
|
+
function signatureCarriesProofOracle(context, declaration, seenSymbols) {
|
|
54
|
+
const signature = context.checker.getSignatureFromDeclaration(declaration);
|
|
55
|
+
return (signature !== undefined &&
|
|
56
|
+
context.checker.getTypePredicateOfSignature(signature) !== undefined) ||
|
|
57
|
+
(!!declaration.type &&
|
|
58
|
+
typeNodeCarriesProofOracle(context, declaration.type, seenSymbols));
|
|
59
|
+
}
|
|
60
|
+
function symbolCarriesProofOracle(context, symbol, seenSymbols) {
|
|
61
|
+
if (seenSymbols.has(symbol)) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
seenSymbols.add(symbol);
|
|
65
|
+
for (const declaration of symbol.getDeclarations() ?? []) {
|
|
66
|
+
if (isStandardLibraryExternProofSourceFile(declaration.getSourceFile())) {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (ts.isTypeAliasDeclaration(declaration) &&
|
|
70
|
+
typeNodeCarriesProofOracle(context, declaration.type, seenSymbols)) {
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
if ((ts.isInterfaceDeclaration(declaration) || ts.isClassDeclaration(declaration)) &&
|
|
74
|
+
declarationMembersCarryProofOracle(context, declaration.members, seenSymbols)) {
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
if ((ts.isInterfaceDeclaration(declaration) || ts.isClassDeclaration(declaration)) &&
|
|
78
|
+
declaration.heritageClauses?.some((clause) => clause.types.some((type) => {
|
|
79
|
+
const symbol = resolveReferencedTypeSymbol(context, type);
|
|
80
|
+
return !!symbol && symbolCarriesProofOracle(context, symbol, seenSymbols);
|
|
81
|
+
}))) {
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
function declarationMembersCarryProofOracle(context, members, seenSymbols) {
|
|
88
|
+
return members.some((member) => {
|
|
89
|
+
if ((ts.isMethodSignature(member) || ts.isMethodDeclaration(member) ||
|
|
90
|
+
ts.isCallSignatureDeclaration(member) ||
|
|
91
|
+
ts.isConstructSignatureDeclaration(member)) &&
|
|
92
|
+
signatureCarriesProofOracle(context, member, seenSymbols)) {
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
if ((ts.isPropertySignature(member) || ts.isPropertyDeclaration(member) ||
|
|
96
|
+
ts.isIndexSignatureDeclaration(member) ||
|
|
97
|
+
ts.isGetAccessorDeclaration(member)) &&
|
|
98
|
+
member.type &&
|
|
99
|
+
typeNodeCarriesProofOracle(context, member.type, seenSymbols)) {
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
return false;
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
function typeNodeCarriesProofOracle(context, typeNode, seenSymbols) {
|
|
106
|
+
if (ts.isTypePredicateNode(typeNode)) {
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
if (ts.isParenthesizedTypeNode(typeNode) || ts.isTypeOperatorNode(typeNode)) {
|
|
110
|
+
return typeNodeCarriesProofOracle(context, typeNode.type, seenSymbols);
|
|
111
|
+
}
|
|
112
|
+
if (ts.isArrayTypeNode(typeNode)) {
|
|
113
|
+
return typeNodeCarriesProofOracle(context, typeNode.elementType, seenSymbols);
|
|
114
|
+
}
|
|
115
|
+
if (ts.isTupleTypeNode(typeNode)) {
|
|
116
|
+
return typeNode.elements.some((element) => typeNodeCarriesProofOracle(context, ts.isNamedTupleMember(element) ? element.type : element, seenSymbols));
|
|
117
|
+
}
|
|
118
|
+
if (ts.isUnionTypeNode(typeNode) || ts.isIntersectionTypeNode(typeNode)) {
|
|
119
|
+
return typeNode.types.some((part) => typeNodeCarriesProofOracle(context, part, seenSymbols));
|
|
120
|
+
}
|
|
121
|
+
if (ts.isConditionalTypeNode(typeNode)) {
|
|
122
|
+
return typeNodeCarriesProofOracle(context, typeNode.checkType, seenSymbols) ||
|
|
123
|
+
typeNodeCarriesProofOracle(context, typeNode.extendsType, seenSymbols) ||
|
|
124
|
+
typeNodeCarriesProofOracle(context, typeNode.trueType, seenSymbols) ||
|
|
125
|
+
typeNodeCarriesProofOracle(context, typeNode.falseType, seenSymbols);
|
|
126
|
+
}
|
|
127
|
+
if (ts.isIndexedAccessTypeNode(typeNode)) {
|
|
128
|
+
return typeNodeCarriesProofOracle(context, typeNode.objectType, seenSymbols) ||
|
|
129
|
+
typeNodeCarriesProofOracle(context, typeNode.indexType, seenSymbols);
|
|
130
|
+
}
|
|
131
|
+
if (ts.isMappedTypeNode(typeNode)) {
|
|
132
|
+
return !!typeNode.type && typeNodeCarriesProofOracle(context, typeNode.type, seenSymbols);
|
|
133
|
+
}
|
|
134
|
+
if (ts.isFunctionTypeNode(typeNode) || ts.isConstructorTypeNode(typeNode)) {
|
|
135
|
+
return signatureCarriesProofOracle(context, typeNode, seenSymbols);
|
|
136
|
+
}
|
|
137
|
+
if (ts.isTypeLiteralNode(typeNode)) {
|
|
138
|
+
return declarationMembersCarryProofOracle(context, typeNode.members, seenSymbols);
|
|
139
|
+
}
|
|
140
|
+
if (ts.isTypeReferenceNode(typeNode) || ts.isImportTypeNode(typeNode) || ts.isTypeQueryNode(typeNode)) {
|
|
141
|
+
const symbol = resolveReferencedTypeSymbol(context, typeNode);
|
|
142
|
+
return !!symbol && symbolCarriesProofOracle(context, symbol, seenSymbols);
|
|
143
|
+
}
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
function variableStatementCarriesProofOracle(context, targetNode) {
|
|
147
|
+
return targetNode.declarationList.declarations.some((declaration) => {
|
|
148
|
+
if (!ts.isIdentifier(declaration.name)) {
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
return !!declaration.type &&
|
|
152
|
+
typeNodeCarriesProofOracle(context, declaration.type, new Set());
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
function classDeclarationCarriesProofOracle(context, targetNode) {
|
|
156
|
+
return declarationMembersCarryProofOracle(context, targetNode.members, new Set()) ||
|
|
157
|
+
targetNode.heritageClauses?.some((clause) => clause.types.some((type) => {
|
|
158
|
+
const symbol = resolveReferencedTypeSymbol(context, type);
|
|
159
|
+
return !!symbol && symbolCarriesProofOracle(context, symbol, new Set());
|
|
160
|
+
})) === true;
|
|
161
|
+
}
|
|
162
|
+
function isExternTargetNode(context, targetNode) {
|
|
163
|
+
if (!hasDeclareModifier(targetNode)) {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
if (ts.isVariableStatement(targetNode)) {
|
|
167
|
+
return !variableStatementCarriesProofOracle(context, targetNode);
|
|
168
|
+
}
|
|
169
|
+
if (ts.isFunctionDeclaration(targetNode)) {
|
|
170
|
+
return !signatureCarriesProofOracle(context, targetNode, new Set());
|
|
171
|
+
}
|
|
172
|
+
if (ts.isClassDeclaration(targetNode)) {
|
|
173
|
+
return !classDeclarationCarriesProofOracle(context, targetNode);
|
|
174
|
+
}
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
function isVarianceTargetNode(targetNode) {
|
|
178
|
+
return (ts.isInterfaceDeclaration(targetNode) ||
|
|
179
|
+
ts.isTypeAliasDeclaration(targetNode)) && (targetNode.typeParameters?.length ?? 0) > 0;
|
|
180
|
+
}
|
|
181
|
+
function isValueTargetNode(targetNode) {
|
|
182
|
+
return ts.isClassDeclaration(targetNode);
|
|
183
|
+
}
|
|
184
|
+
function isNewtypeTargetNode(targetNode) {
|
|
185
|
+
return ts.isTypeAliasDeclaration(targetNode);
|
|
186
|
+
}
|
|
187
|
+
function isUnionBackedNewtypeTarget(context, targetNode) {
|
|
188
|
+
const representationType = context.checker.getTypeFromTypeNode(targetNode.type);
|
|
189
|
+
return (representationType.flags & ts.TypeFlags.Union) !== 0;
|
|
190
|
+
}
|
|
191
|
+
function isKnownAnnotation(annotationName) {
|
|
192
|
+
return annotationName === 'extern' ||
|
|
193
|
+
annotationName === 'interop' ||
|
|
194
|
+
annotationName === 'newtype' ||
|
|
195
|
+
annotationName === 'unsafe' ||
|
|
196
|
+
annotationName === 'value' ||
|
|
197
|
+
annotationName === 'variance';
|
|
198
|
+
}
|
|
199
|
+
function splitMacroOwnedAnnotationName(annotationName) {
|
|
200
|
+
const dotIndex = annotationName.indexOf('.');
|
|
201
|
+
if (dotIndex <= 0) {
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
const owner = annotationName.slice(0, dotIndex);
|
|
205
|
+
return BUILTIN_DIRECTIVE_NAMES.has(owner)
|
|
206
|
+
? null
|
|
207
|
+
: {
|
|
208
|
+
owner,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
function createUnknownAnnotationMessage(annotation) {
|
|
212
|
+
return `${SOUND_DIAGNOSTIC_MESSAGES.unknownAnnotation} \`#[${annotation.name}]\` is not registered.`;
|
|
213
|
+
}
|
|
214
|
+
function getRegisteredBuiltinAnnotationsText() {
|
|
215
|
+
return 'extern, interop, newtype, unsafe, value, variance';
|
|
216
|
+
}
|
|
217
|
+
function createMalformedAnnotationDiagnostic(filePath, line, annotationText, parseError) {
|
|
218
|
+
const example = 'Rewrite the comment as a complete annotation such as `// #[unsafe]`, or remove it if no directive is intended.';
|
|
219
|
+
return createDiagnostic(filePath, line, 1, SOUND_DIAGNOSTIC_CODES.malformedAnnotation, `${SOUND_DIAGNOSTIC_MESSAGES.malformedAnnotation} ${parseError}`, {
|
|
220
|
+
metadata: {
|
|
221
|
+
rule: 'malformed_annotation_comment',
|
|
222
|
+
primarySymbol: annotationText,
|
|
223
|
+
fixability: 'local_rewrite',
|
|
224
|
+
invariant: 'Only well-formed `// #[...]` comments participate in checked soundscript annotation semantics.',
|
|
225
|
+
replacementFamily: 'well_formed_annotation_comment',
|
|
226
|
+
evidence: [
|
|
227
|
+
{ label: 'annotationText', value: annotationText },
|
|
228
|
+
{ label: 'parseError', value: parseError },
|
|
229
|
+
],
|
|
230
|
+
counterexample: 'A malformed annotation comment looks like a checked directive, but it attaches to nothing and leaves the following code ordinary checked code.',
|
|
231
|
+
example,
|
|
232
|
+
},
|
|
233
|
+
notes: [
|
|
234
|
+
`\`${annotationText}\` did not parse as a complete soundscript annotation comment, so it does not attach to the following code.`,
|
|
235
|
+
`Parser detail: ${parseError}`,
|
|
236
|
+
`Example: ${example}`,
|
|
237
|
+
],
|
|
238
|
+
hint: 'Rewrite the malformed comment as a complete `// #[...]` annotation, or remove it.',
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
function createUnknownAnnotationDiagnostic(filePath, line, annotation) {
|
|
242
|
+
const label = `#[${annotation.name}]`;
|
|
243
|
+
const registeredBuiltins = getRegisteredBuiltinAnnotationsText();
|
|
244
|
+
const example = `Replace \`${label}\` with a registered builtin annotation such as \`#[extern]\`, or remove it until that directive exists.`;
|
|
245
|
+
return createDiagnostic(filePath, line, 1, SOUND_DIAGNOSTIC_CODES.unknownAnnotation, createUnknownAnnotationMessage(annotation), {
|
|
246
|
+
metadata: {
|
|
247
|
+
rule: 'unknown_annotation',
|
|
248
|
+
primarySymbol: label,
|
|
249
|
+
fixability: 'local_rewrite',
|
|
250
|
+
invariant: 'Only registered soundscript annotations carry builtin checked semantics in annotation position.',
|
|
251
|
+
replacementFamily: 'registered_annotation_name',
|
|
252
|
+
evidence: [
|
|
253
|
+
{ label: 'annotationName', value: annotation.name },
|
|
254
|
+
{ label: 'registeredBuiltins', value: registeredBuiltins },
|
|
255
|
+
],
|
|
256
|
+
counterexample: 'An unknown annotation can look like a checked contract even though soundscript gives it no semantics.',
|
|
257
|
+
example,
|
|
258
|
+
},
|
|
259
|
+
notes: [
|
|
260
|
+
`\`${label}\` is not a registered builtin soundscript annotation.`,
|
|
261
|
+
'Registered builtin annotations in v1 are `#[extern]`, `#[interop]`, `#[newtype]`, `#[unsafe]`, `#[value]`, and `#[variance(...)]`.',
|
|
262
|
+
`Example: ${example}`,
|
|
263
|
+
],
|
|
264
|
+
hint: 'Rename the annotation to a registered builtin, or remove it until that directive exists.',
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
function createDuplicateAnnotationDiagnostic(filePath, line, annotationName, occurrenceCount) {
|
|
268
|
+
const label = `#[${annotationName}]`;
|
|
269
|
+
const example = `Keep one \`${label}\` entry in the block and remove the duplicate.`;
|
|
270
|
+
return createDiagnostic(filePath, line, 1, SOUND_DIAGNOSTIC_CODES.duplicateAnnotation, `${SOUND_DIAGNOSTIC_MESSAGES.duplicateAnnotation} \`${label}\` appears more than once in the same block.`, {
|
|
271
|
+
metadata: {
|
|
272
|
+
rule: 'duplicate_annotation',
|
|
273
|
+
primarySymbol: label,
|
|
274
|
+
fixability: 'local_rewrite',
|
|
275
|
+
invariant: 'Each attached annotation block may mention a given annotation name at most once.',
|
|
276
|
+
replacementFamily: 'single_annotation_per_block',
|
|
277
|
+
evidence: [
|
|
278
|
+
{ label: 'annotationName', value: annotationName },
|
|
279
|
+
{ label: 'occurrenceCount', value: String(occurrenceCount) },
|
|
280
|
+
],
|
|
281
|
+
counterexample: 'Duplicate entries make it ambiguous which single checked contract should govern the attached declaration.',
|
|
282
|
+
example,
|
|
283
|
+
},
|
|
284
|
+
notes: [
|
|
285
|
+
`\`${label}\` appears ${occurrenceCount} times in the same attached annotation block.`,
|
|
286
|
+
`Example: ${example}`,
|
|
287
|
+
],
|
|
288
|
+
hint: 'Keep a single annotation entry for each name in the attached block.',
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
function createUnexpectedArgumentsMessage(annotation) {
|
|
292
|
+
if (annotation.name === 'value') {
|
|
293
|
+
return `${SOUND_DIAGNOSTIC_MESSAGES.annotationArgumentsNotSupported} \`#[value]\` only supports the bare form or \`#[value(deep: true)]\`.`;
|
|
294
|
+
}
|
|
295
|
+
return `${SOUND_DIAGNOSTIC_MESSAGES.annotationArgumentsNotSupported} Remove the arguments from \`#[${annotation.text}]\`.`;
|
|
296
|
+
}
|
|
297
|
+
function describeSupportedAnnotationArguments(annotationName) {
|
|
298
|
+
return annotationName === 'value'
|
|
299
|
+
? 'bare form or `#[value(deep: true)]`'
|
|
300
|
+
: 'bare form only';
|
|
301
|
+
}
|
|
302
|
+
function createAnnotationArgumentsNotSupportedDiagnostic(filePath, line, annotation) {
|
|
303
|
+
const label = `#[${annotation.name}]`;
|
|
304
|
+
const argumentsText = annotation.argumentsText !== undefined ? `(${annotation.argumentsText})` : '()';
|
|
305
|
+
const supportedForm = describeSupportedAnnotationArguments(annotation.name);
|
|
306
|
+
const example = annotation.name === 'value'
|
|
307
|
+
? 'Use bare `#[value]` or `#[value(deep: true)]`.'
|
|
308
|
+
: `Remove the arguments from \`#[${annotation.text}]\`.`;
|
|
309
|
+
return createDiagnostic(filePath, line, 1, SOUND_DIAGNOSTIC_CODES.annotationArgumentsNotSupported, createUnexpectedArgumentsMessage(annotation), {
|
|
310
|
+
metadata: {
|
|
311
|
+
rule: 'annotation_arguments_not_supported',
|
|
312
|
+
primarySymbol: label,
|
|
313
|
+
fixability: 'local_rewrite',
|
|
314
|
+
invariant: 'Builtin annotations only accept the argument forms that the language version defines explicitly.',
|
|
315
|
+
replacementFamily: 'supported_annotation_arguments',
|
|
316
|
+
evidence: [
|
|
317
|
+
{ label: 'annotationName', value: annotation.name },
|
|
318
|
+
{ label: 'argumentsText', value: argumentsText },
|
|
319
|
+
{ label: 'supportedForm', value: supportedForm },
|
|
320
|
+
],
|
|
321
|
+
counterexample: 'Unsupported annotation arguments can look like checked configuration even though v1 does not define any semantics for them.',
|
|
322
|
+
example,
|
|
323
|
+
},
|
|
324
|
+
notes: [
|
|
325
|
+
`\`${label}\` does not accept arguments in v1; this annotation uses \`${argumentsText}\`.`,
|
|
326
|
+
`Example: ${example}`,
|
|
327
|
+
],
|
|
328
|
+
hint: 'Remove the unsupported annotation arguments, or rewrite the annotation to one of its supported forms.',
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
function createInvalidTargetMessage(annotation) {
|
|
332
|
+
if (annotation.name === 'interop') {
|
|
333
|
+
return `${SOUND_DIAGNOSTIC_MESSAGES.invalidAnnotationTarget} \`#[interop]\` must attach to an import, \`require(...)\`, or \`import(...)\` boundary.`;
|
|
334
|
+
}
|
|
335
|
+
if (annotation.name === 'extern') {
|
|
336
|
+
return `${SOUND_DIAGNOSTIC_MESSAGES.invalidAnnotationTarget} \`#[extern]\` must attach to a local ambient runtime declaration.`;
|
|
337
|
+
}
|
|
338
|
+
if (annotation.name === 'variance') {
|
|
339
|
+
return `${SOUND_DIAGNOSTIC_MESSAGES.invalidAnnotationTarget} \`#[variance(...)]\` must attach to a generic interface or type alias declaration.`;
|
|
340
|
+
}
|
|
341
|
+
if (annotation.name === 'newtype') {
|
|
342
|
+
return `${SOUND_DIAGNOSTIC_MESSAGES.invalidAnnotationTarget} \`#[newtype]\` must attach to a type alias declaration.`;
|
|
343
|
+
}
|
|
344
|
+
if (annotation.name === 'value') {
|
|
345
|
+
return `${SOUND_DIAGNOSTIC_MESSAGES.invalidAnnotationTarget} \`#[value]\` must attach to a class declaration.`;
|
|
346
|
+
}
|
|
347
|
+
return `${SOUND_DIAGNOSTIC_MESSAGES.invalidAnnotationTarget} \`#[unsafe]\` must attach to a local proof-override declaration or statement.`;
|
|
348
|
+
}
|
|
349
|
+
function createBannedTypeScriptPragmaDiagnostic(filePath, pragma) {
|
|
350
|
+
const example = `Remove \`${pragma.text}\` and express the invariant with checked code, a validated boundary, or a real type fix.`;
|
|
351
|
+
return createDiagnostic(filePath, pragma.line, 1, SOUND_DIAGNOSTIC_CODES.bannedTypeScriptPragma, `${SOUND_DIAGNOSTIC_MESSAGES.bannedTypeScriptPragma} Remove \`${pragma.text}\` and express the invariant in checked code instead.`, {
|
|
352
|
+
metadata: {
|
|
353
|
+
rule: 'typescript_pragma_banned',
|
|
354
|
+
primarySymbol: pragma.text,
|
|
355
|
+
fixability: 'local_rewrite',
|
|
356
|
+
invariant: 'soundscript diagnostics must not depend on TypeScript suppression comments that hide upstream evidence.',
|
|
357
|
+
replacementFamily: 'checked_code_without_suppression',
|
|
358
|
+
evidence: [
|
|
359
|
+
{ label: 'pragmaText', value: pragma.text },
|
|
360
|
+
],
|
|
361
|
+
counterexample: 'TypeScript pragmas suppress upstream evidence and make soundscript checking depend on hidden unchecked assumptions.',
|
|
362
|
+
example,
|
|
363
|
+
},
|
|
364
|
+
notes: [
|
|
365
|
+
`\`${pragma.text}\` suppresses upstream diagnostics instead of expressing a checked soundscript boundary.`,
|
|
366
|
+
`Example: ${example}`,
|
|
367
|
+
],
|
|
368
|
+
hint: 'Delete the TypeScript pragma and make the code type-check without suppression.',
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
function isSupportedValueAnnotationArguments(annotation) {
|
|
372
|
+
const args = annotation.arguments ?? [];
|
|
373
|
+
if (args.length === 0) {
|
|
374
|
+
return true;
|
|
375
|
+
}
|
|
376
|
+
if (args.length !== 1) {
|
|
377
|
+
return false;
|
|
378
|
+
}
|
|
379
|
+
const [arg] = args;
|
|
380
|
+
return arg?.kind === 'named' &&
|
|
381
|
+
arg.name === 'deep' &&
|
|
382
|
+
arg.value.kind === 'boolean' &&
|
|
383
|
+
arg.value.value === true;
|
|
384
|
+
}
|
|
385
|
+
function createInvalidNewtypeRepresentationMessage() {
|
|
386
|
+
return `${SOUND_DIAGNOSTIC_MESSAGES.invalidAnnotationTarget} \`#[newtype]\` aliases must not resolve to a top-level union representation. Use the newtype at the leaves and compose unions at the use site instead.`;
|
|
387
|
+
}
|
|
388
|
+
function isSupportedMacroOwnedMemberTarget(targetNode) {
|
|
389
|
+
return ts.isPropertyDeclaration(targetNode) || ts.isPropertySignature(targetNode);
|
|
390
|
+
}
|
|
391
|
+
function findMacroOwnedAnnotationOwner(targetNode) {
|
|
392
|
+
if (!isSupportedMacroOwnedMemberTarget(targetNode)) {
|
|
393
|
+
return targetNode;
|
|
394
|
+
}
|
|
395
|
+
let current = targetNode.parent;
|
|
396
|
+
while (current) {
|
|
397
|
+
if (ts.isClassDeclaration(current) ||
|
|
398
|
+
ts.isInterfaceDeclaration(current) ||
|
|
399
|
+
ts.isTypeAliasDeclaration(current)) {
|
|
400
|
+
return current;
|
|
401
|
+
}
|
|
402
|
+
current = current.parent;
|
|
403
|
+
}
|
|
404
|
+
return undefined;
|
|
405
|
+
}
|
|
406
|
+
function createInvalidMacroOwnedAnnotationTargetMessage(annotationName, ownerName) {
|
|
407
|
+
return `${SOUND_DIAGNOSTIC_MESSAGES.invalidAnnotationTarget} \`#[${annotationName}]\` must attach to a declaration annotated with \`#[${ownerName}]\` or to a supported member inside one.`;
|
|
408
|
+
}
|
|
409
|
+
function describeExpectedAnnotationTarget(annotationName, ownerName) {
|
|
410
|
+
if (ownerName) {
|
|
411
|
+
return `declaration annotated with #[${ownerName}] or supported member inside one`;
|
|
412
|
+
}
|
|
413
|
+
if (annotationName === 'interop') {
|
|
414
|
+
return 'import, require(...), or import(...) boundary';
|
|
415
|
+
}
|
|
416
|
+
if (annotationName === 'extern') {
|
|
417
|
+
return 'local ambient runtime declaration';
|
|
418
|
+
}
|
|
419
|
+
if (annotationName === 'variance') {
|
|
420
|
+
return 'generic interface or type alias declaration';
|
|
421
|
+
}
|
|
422
|
+
if (annotationName === 'newtype') {
|
|
423
|
+
return 'type alias declaration';
|
|
424
|
+
}
|
|
425
|
+
if (annotationName === 'value') {
|
|
426
|
+
return 'class declaration';
|
|
427
|
+
}
|
|
428
|
+
return 'local proof-override declaration or statement';
|
|
429
|
+
}
|
|
430
|
+
function describeAnnotationTargetNode(targetNode) {
|
|
431
|
+
if (!targetNode) {
|
|
432
|
+
return 'detached annotation block';
|
|
433
|
+
}
|
|
434
|
+
if (ts.isVariableStatement(targetNode) || ts.isVariableDeclaration(targetNode)) {
|
|
435
|
+
return 'variable declaration';
|
|
436
|
+
}
|
|
437
|
+
if (ts.isImportDeclaration(targetNode) || ts.isImportClause(targetNode) ||
|
|
438
|
+
ts.isImportEqualsDeclaration(targetNode)) {
|
|
439
|
+
return 'import declaration';
|
|
440
|
+
}
|
|
441
|
+
if (ts.isFunctionDeclaration(targetNode)) {
|
|
442
|
+
return 'function declaration';
|
|
443
|
+
}
|
|
444
|
+
if (ts.isClassDeclaration(targetNode)) {
|
|
445
|
+
return 'class declaration';
|
|
446
|
+
}
|
|
447
|
+
if (ts.isInterfaceDeclaration(targetNode)) {
|
|
448
|
+
return 'interface declaration';
|
|
449
|
+
}
|
|
450
|
+
if (ts.isTypeAliasDeclaration(targetNode)) {
|
|
451
|
+
return 'type alias declaration';
|
|
452
|
+
}
|
|
453
|
+
if (ts.isMethodDeclaration(targetNode)) {
|
|
454
|
+
return 'method declaration';
|
|
455
|
+
}
|
|
456
|
+
if (ts.isExpressionStatement(targetNode)) {
|
|
457
|
+
return 'statement';
|
|
458
|
+
}
|
|
459
|
+
return ts.SyntaxKind[targetNode.kind].replace(/([a-z])([A-Z])/g, '$1 $2').toLowerCase();
|
|
460
|
+
}
|
|
461
|
+
function createInvalidAnnotationTargetDiagnostic(filePath, line, column, message, annotationName, targetNode, ownerName) {
|
|
462
|
+
const expectedTarget = describeExpectedAnnotationTarget(annotationName, ownerName);
|
|
463
|
+
const actualTarget = describeAnnotationTargetNode(targetNode);
|
|
464
|
+
const label = `#[${annotationName}]`;
|
|
465
|
+
const example = ownerName
|
|
466
|
+
? `Move \`${label}\` onto a declaration annotated with \`#[${ownerName}]\`, or remove it from this site.`
|
|
467
|
+
: `Move \`${label}\` to a ${expectedTarget}, or remove it if this code is an ordinary implementation.`;
|
|
468
|
+
return createDiagnostic(filePath, line, column, SOUND_DIAGNOSTIC_CODES.invalidAnnotationTarget, message, {
|
|
469
|
+
metadata: {
|
|
470
|
+
rule: 'invalid_annotation_target',
|
|
471
|
+
primarySymbol: label,
|
|
472
|
+
fixability: 'local_rewrite',
|
|
473
|
+
invariant: 'Each builtin annotation only has meaning on the specific syntax sites that define its checked semantics.',
|
|
474
|
+
replacementFamily: 'supported_annotation_site',
|
|
475
|
+
evidence: [
|
|
476
|
+
{ label: 'annotationName', value: annotationName },
|
|
477
|
+
{ label: 'expectedTarget', value: expectedTarget },
|
|
478
|
+
{ label: 'actualTarget', value: actualTarget },
|
|
479
|
+
],
|
|
480
|
+
counterexample: 'An annotation attached to the wrong syntax node can look like it blesses code even though that site does not support the annotation’s semantics.',
|
|
481
|
+
example,
|
|
482
|
+
},
|
|
483
|
+
notes: [
|
|
484
|
+
`\`${label}\` must attach to a ${expectedTarget}, but this annotation is attached to a ${actualTarget}.`,
|
|
485
|
+
`Example: ${example}`,
|
|
486
|
+
],
|
|
487
|
+
hint: 'Move the annotation to a supported target, or remove it if this site should stay ordinary checked code.',
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
function validateAnnotationBlock(context, diagnostics, filePath, annotationLookup, block) {
|
|
491
|
+
const seenAnnotations = new Set();
|
|
492
|
+
for (const annotation of block.annotations) {
|
|
493
|
+
if (seenAnnotations.has(annotation.name)) {
|
|
494
|
+
diagnostics.push(createDuplicateAnnotationDiagnostic(filePath, block.startLine, annotation.name, block.annotations.filter((candidate) => candidate.name === annotation.name).length));
|
|
495
|
+
continue;
|
|
496
|
+
}
|
|
497
|
+
seenAnnotations.add(annotation.name);
|
|
498
|
+
const macroOwned = splitMacroOwnedAnnotationName(annotation.name);
|
|
499
|
+
if (macroOwned) {
|
|
500
|
+
if (!block.targetNode) {
|
|
501
|
+
diagnostics.push(createInvalidAnnotationTargetDiagnostic(filePath, block.startLine, 1, createInvalidMacroOwnedAnnotationTargetMessage(annotation.name, macroOwned.owner), annotation.name, undefined, macroOwned.owner));
|
|
502
|
+
continue;
|
|
503
|
+
}
|
|
504
|
+
const ownerNode = findMacroOwnedAnnotationOwner(block.targetNode);
|
|
505
|
+
if (!ownerNode || !annotationLookup.hasAttachedAnnotation(ownerNode, macroOwned.owner)) {
|
|
506
|
+
diagnostics.push(createInvalidAnnotationTargetDiagnostic(filePath, block.startLine, 1, createInvalidMacroOwnedAnnotationTargetMessage(annotation.name, macroOwned.owner), annotation.name, block.targetNode, macroOwned.owner));
|
|
507
|
+
}
|
|
508
|
+
continue;
|
|
509
|
+
}
|
|
510
|
+
if (!isKnownAnnotation(annotation.name)) {
|
|
511
|
+
diagnostics.push(createUnknownAnnotationDiagnostic(filePath, block.startLine, annotation));
|
|
512
|
+
continue;
|
|
513
|
+
}
|
|
514
|
+
if (annotation.argumentsText !== undefined &&
|
|
515
|
+
annotation.name !== 'variance' &&
|
|
516
|
+
!(annotation.name === 'value' && isSupportedValueAnnotationArguments(annotation))) {
|
|
517
|
+
diagnostics.push(createAnnotationArgumentsNotSupportedDiagnostic(filePath, block.startLine, annotation));
|
|
518
|
+
continue;
|
|
519
|
+
}
|
|
520
|
+
if (!block.targetNode) {
|
|
521
|
+
diagnostics.push(createInvalidAnnotationTargetDiagnostic(filePath, block.startLine, 1, createInvalidTargetMessage(annotation), annotation.name, undefined));
|
|
522
|
+
continue;
|
|
523
|
+
}
|
|
524
|
+
const isValidTarget = annotation.name === 'interop'
|
|
525
|
+
? isInteropTargetNode(block.targetNode)
|
|
526
|
+
: annotation.name === 'extern'
|
|
527
|
+
? isExternTargetNode(context, block.targetNode)
|
|
528
|
+
: annotation.name === 'variance'
|
|
529
|
+
? isVarianceTargetNode(block.targetNode)
|
|
530
|
+
: annotation.name === 'value'
|
|
531
|
+
? isValueTargetNode(block.targetNode)
|
|
532
|
+
: annotation.name === 'newtype'
|
|
533
|
+
? isNewtypeTargetNode(block.targetNode)
|
|
534
|
+
: isUnsafeTargetNode(block.targetNode);
|
|
535
|
+
if (!isValidTarget) {
|
|
536
|
+
diagnostics.push(createInvalidAnnotationTargetDiagnostic(filePath, block.startLine, 1, createInvalidTargetMessage(annotation), annotation.name, block.targetNode));
|
|
537
|
+
continue;
|
|
538
|
+
}
|
|
539
|
+
if (annotation.name === 'newtype' &&
|
|
540
|
+
isNewtypeTargetNode(block.targetNode) &&
|
|
541
|
+
isUnionBackedNewtypeTarget(context, block.targetNode)) {
|
|
542
|
+
diagnostics.push(createDiagnostic(filePath, block.startLine, 1, SOUND_DIAGNOSTIC_CODES.invalidAnnotationTarget, createInvalidNewtypeRepresentationMessage()));
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
export function runAnnotationValidationRules(context) {
|
|
547
|
+
const diagnostics = [];
|
|
548
|
+
context.forEachSourceFile((sourceFile) => {
|
|
549
|
+
const annotationLookup = context.getAnnotationLookup(sourceFile);
|
|
550
|
+
for (const entry of annotationLookup.getEntries()) {
|
|
551
|
+
switch (entry.kind) {
|
|
552
|
+
case 'annotation':
|
|
553
|
+
break;
|
|
554
|
+
case 'annotation-parse-error':
|
|
555
|
+
diagnostics.push(createMalformedAnnotationDiagnostic(sourceFile.fileName, entry.line, entry.text, entry.message));
|
|
556
|
+
break;
|
|
557
|
+
case 'banned-ts-pragma':
|
|
558
|
+
diagnostics.push(createBannedTypeScriptPragmaDiagnostic(sourceFile.fileName, entry));
|
|
559
|
+
break;
|
|
560
|
+
default: {
|
|
561
|
+
const exhaustiveCheck = entry;
|
|
562
|
+
return exhaustiveCheck;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
for (const block of annotationLookup.getBlocks()) {
|
|
567
|
+
validateAnnotationBlock(context, diagnostics, sourceFile.fileName, annotationLookup, block);
|
|
568
|
+
}
|
|
569
|
+
});
|
|
570
|
+
return diagnostics;
|
|
571
|
+
}
|