@soundscript/soundscript 0.1.13 → 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,1361 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
import { dirname, isAbsolute, join } from '../platform/path.js';
|
|
3
|
+
import { createSoundStdlibCompilerHost } from '../bundled/sound_stdlib.js';
|
|
4
|
+
import { createBuiltinExpandedProgram, } from '../frontend/builtin_macro_support.js';
|
|
5
|
+
import { sourceTextLooksLikeMacroModule, usesLegacyDefineMacroAuthoring, } from '../frontend/macro_factory_support.js';
|
|
6
|
+
import { clearPreparedCompilerHostReuseState, emitProjectedDeclarations, getLineAndCharacterOfPosition, getPositionOfLineAndCharacter, isProjectedSoundscriptDeclarationFile, isSoundscriptSourceFile, mapProgramEnclosingRangeToSource, mapProgramPositionToSource, toProjectedDeclarationFileName, toProjectedDeclarationSourceFileName, toSourceFileName, } from '../frontend/project_frontend.js';
|
|
7
|
+
import { collectSoundscriptRootNames, loadConfig } from '../config.js';
|
|
8
|
+
import { findNearestPackageJsonPath, getSoundScriptPackageInfoForResolvedModule, resolveSoundScriptAwareModule, } from '../soundscript_packages.js';
|
|
9
|
+
import { hasErrorDiagnostics, remapDiagnosticFilePaths, toMergedDiagnostic, } from './diagnostics.js';
|
|
10
|
+
import { SOUND_DIAGNOSTIC_CODES } from './engine/diagnostic_codes.js';
|
|
11
|
+
import { createAnalysisContext } from './engine/context.js';
|
|
12
|
+
import { runSoundAnalysis } from './rules/index.js';
|
|
13
|
+
import { runSourceSupplementalPolicyAnalysis, runUniversalPolicyAnalysis, } from './rules/universal.js';
|
|
14
|
+
import { measureCheckerTiming } from './timing.js';
|
|
15
|
+
const fileScopedAnalysisContextCache = new WeakMap();
|
|
16
|
+
const IGNORED_GENERATED_TOP_LEVEL_IMPORT_SPECIFIERS = new Set(['sts:prelude']);
|
|
17
|
+
function combineRootNames(rootNames, additionalRootNames = []) {
|
|
18
|
+
return [...new Set([...rootNames, ...additionalRootNames])];
|
|
19
|
+
}
|
|
20
|
+
function rootNamesEqual(left, right) {
|
|
21
|
+
if (left.length !== right.length) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
for (let index = 0; index < left.length; index += 1) {
|
|
25
|
+
if (left[index] !== right[index]) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
function createFileOverrideSignature(fileOverrides, includeFileName) {
|
|
32
|
+
if (!fileOverrides || fileOverrides.size === 0) {
|
|
33
|
+
return '';
|
|
34
|
+
}
|
|
35
|
+
return [...fileOverrides.entries()]
|
|
36
|
+
.filter(([fileName]) => includeFileName(fileName))
|
|
37
|
+
.sort(([left], [right]) => left.localeCompare(right))
|
|
38
|
+
.map(([fileName, text]) => `${fileName}:${text.length}:${text}`)
|
|
39
|
+
.join('|');
|
|
40
|
+
}
|
|
41
|
+
function createSoundscriptRootDiscoverySignature(projectPath, loadedConfig) {
|
|
42
|
+
const basePath = dirname(projectPath);
|
|
43
|
+
const rawConfig = loadedConfig.commandLine.raw;
|
|
44
|
+
const explicitFiles = (rawConfig?.files ?? [])
|
|
45
|
+
.map((fileName) => isAbsolute(fileName) ? fileName : join(basePath, fileName))
|
|
46
|
+
.map((fileName) => ts.sys.resolvePath(fileName))
|
|
47
|
+
.filter(isSoundscriptSourceFile)
|
|
48
|
+
.sort()
|
|
49
|
+
.join('\u0000');
|
|
50
|
+
const includePatterns = rawConfig?.include
|
|
51
|
+
? [...rawConfig.include]
|
|
52
|
+
: rawConfig?.files
|
|
53
|
+
? []
|
|
54
|
+
: ['**/*'];
|
|
55
|
+
const excludePatterns = rawConfig?.exclude
|
|
56
|
+
? [...rawConfig.exclude]
|
|
57
|
+
: ['node_modules', 'bower_components', 'jspm_packages', '.git'];
|
|
58
|
+
return [
|
|
59
|
+
basePath,
|
|
60
|
+
explicitFiles,
|
|
61
|
+
includePatterns.join('\u0001'),
|
|
62
|
+
excludePatterns.join('\u0001'),
|
|
63
|
+
].join('\u0002');
|
|
64
|
+
}
|
|
65
|
+
function stableConfigSignature(value) {
|
|
66
|
+
return JSON.stringify(value, (_key, currentValue) => {
|
|
67
|
+
if (currentValue !== null &&
|
|
68
|
+
typeof currentValue === 'object' &&
|
|
69
|
+
!Array.isArray(currentValue)) {
|
|
70
|
+
return Object.fromEntries(Object.entries(currentValue).sort(([left], [right]) => left.localeCompare(right)));
|
|
71
|
+
}
|
|
72
|
+
return currentValue;
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
function createProjectConfigReuseSignature(projectPath, loadedConfig) {
|
|
76
|
+
return [
|
|
77
|
+
projectPath,
|
|
78
|
+
stableConfigSignature(loadedConfig.commandLine.raw),
|
|
79
|
+
stableConfigSignature(loadedConfig.commandLine.options),
|
|
80
|
+
stableConfigSignature(loadedConfig.commandLine.projectReferences ?? []),
|
|
81
|
+
stableConfigSignature(loadedConfig.runtime),
|
|
82
|
+
].join('\u0003');
|
|
83
|
+
}
|
|
84
|
+
function createModuleResolutionHostWithOverrides(fileOverrides) {
|
|
85
|
+
const normalizedOverrides = fileOverrides
|
|
86
|
+
? new Map([...fileOverrides.entries()].map(([fileName, text]) => [ts.sys.resolvePath(fileName), text]))
|
|
87
|
+
: new Map();
|
|
88
|
+
return {
|
|
89
|
+
directoryExists(directoryName) {
|
|
90
|
+
const normalizedDirectoryName = ts.sys.resolvePath(directoryName);
|
|
91
|
+
if ([...normalizedOverrides.keys()].some((fileName) => fileName === normalizedDirectoryName ||
|
|
92
|
+
fileName.startsWith(`${normalizedDirectoryName}/`) ||
|
|
93
|
+
fileName.startsWith(`${normalizedDirectoryName}\\`))) {
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
return ts.sys.directoryExists?.(directoryName) ?? false;
|
|
97
|
+
},
|
|
98
|
+
fileExists(fileName) {
|
|
99
|
+
return normalizedOverrides.has(ts.sys.resolvePath(fileName)) || ts.sys.fileExists(fileName);
|
|
100
|
+
},
|
|
101
|
+
getCurrentDirectory: ts.sys.getCurrentDirectory,
|
|
102
|
+
getDirectories: ts.sys.getDirectories,
|
|
103
|
+
readFile(fileName) {
|
|
104
|
+
return normalizedOverrides.get(ts.sys.resolvePath(fileName)) ?? ts.sys.readFile(fileName);
|
|
105
|
+
},
|
|
106
|
+
realpath: ts.sys.realpath,
|
|
107
|
+
useCaseSensitiveFileNames: ts.sys.useCaseSensitiveFileNames,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
function isRelativeOrAbsoluteModuleSpecifier(moduleSpecifier) {
|
|
111
|
+
return moduleSpecifier.startsWith('.') ||
|
|
112
|
+
moduleSpecifier.startsWith('/') ||
|
|
113
|
+
/^[A-Za-z]:[/\\]/u.test(moduleSpecifier);
|
|
114
|
+
}
|
|
115
|
+
function resolveRelativeSoundscriptDependency(containingFileName, moduleSpecifier, host) {
|
|
116
|
+
if (!isRelativeOrAbsoluteModuleSpecifier(moduleSpecifier)) {
|
|
117
|
+
return undefined;
|
|
118
|
+
}
|
|
119
|
+
const explicitNonSoundscriptExtensionPattern = /\.(?:[cm]?[jt]sx?|[cm]?js)$/u;
|
|
120
|
+
if (explicitNonSoundscriptExtensionPattern.test(moduleSpecifier)) {
|
|
121
|
+
return undefined;
|
|
122
|
+
}
|
|
123
|
+
const candidateBase = ts.sys.resolvePath(isAbsolute(moduleSpecifier)
|
|
124
|
+
? moduleSpecifier
|
|
125
|
+
: join(dirname(containingFileName), moduleSpecifier));
|
|
126
|
+
const candidates = moduleSpecifier.endsWith('.sts')
|
|
127
|
+
? [candidateBase]
|
|
128
|
+
: [`${candidateBase}.sts`, join(candidateBase, 'index.sts')];
|
|
129
|
+
for (const candidate of candidates) {
|
|
130
|
+
if (host.fileExists(candidate)) {
|
|
131
|
+
return candidate;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return undefined;
|
|
135
|
+
}
|
|
136
|
+
function collectReachableSoundscriptDependencyFiles(rootNames, compilerOptions, fileOverrides) {
|
|
137
|
+
const host = createModuleResolutionHostWithOverrides(fileOverrides);
|
|
138
|
+
const visited = new Set();
|
|
139
|
+
const reachableFiles = [];
|
|
140
|
+
function visit(fileName) {
|
|
141
|
+
const sourceFileName = ts.sys.resolvePath(toSourceFileName(fileName));
|
|
142
|
+
if (!isSoundscriptSourceFile(sourceFileName) || visited.has(sourceFileName)) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
visited.add(sourceFileName);
|
|
146
|
+
reachableFiles.push(sourceFileName);
|
|
147
|
+
const sourceText = host.readFile(sourceFileName);
|
|
148
|
+
if (!sourceText) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
for (const importedFile of ts.preProcessFile(sourceText, true, true).importedFiles) {
|
|
152
|
+
const resolvedDependency = resolveRelativeSoundscriptDependency(sourceFileName, importedFile.fileName, host);
|
|
153
|
+
if (resolvedDependency) {
|
|
154
|
+
visit(resolvedDependency);
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
const resolvedModule = resolveSoundScriptAwareModule(importedFile.fileName, sourceFileName, compilerOptions, host);
|
|
158
|
+
if (resolvedModule) {
|
|
159
|
+
visit(resolvedModule.resolvedFileName);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
for (const rootName of rootNames) {
|
|
164
|
+
visit(rootName);
|
|
165
|
+
}
|
|
166
|
+
reachableFiles.sort();
|
|
167
|
+
return reachableFiles;
|
|
168
|
+
}
|
|
169
|
+
function createSoundscriptRootContentSignature(rootNames, compilerOptions, fileOverrides) {
|
|
170
|
+
const host = createModuleResolutionHostWithOverrides(fileOverrides);
|
|
171
|
+
return collectReachableSoundscriptDependencyFiles(rootNames, compilerOptions, fileOverrides)
|
|
172
|
+
.map((fileName) => {
|
|
173
|
+
const text = host.readFile(fileName) ?? '';
|
|
174
|
+
return `${fileName}\u0001${text.length}\u0001${text}`;
|
|
175
|
+
})
|
|
176
|
+
.join('\u0002');
|
|
177
|
+
}
|
|
178
|
+
function getConfigFileParsingDiagnostics(diagnostics, additionalRootNames = []) {
|
|
179
|
+
if (additionalRootNames.length === 0) {
|
|
180
|
+
return diagnostics;
|
|
181
|
+
}
|
|
182
|
+
return diagnostics.filter((diagnostic) => diagnostic.code !== 18003);
|
|
183
|
+
}
|
|
184
|
+
function remapDiagnostics(diagnostics) {
|
|
185
|
+
return diagnostics.map((diagnostic) => remapDiagnosticFilePaths(diagnostic, toSourceFileName));
|
|
186
|
+
}
|
|
187
|
+
function remapPreparedSoundDiagnosticRange(diagnostic, preparedFile) {
|
|
188
|
+
if (!preparedFile ||
|
|
189
|
+
!diagnostic.filePath ||
|
|
190
|
+
diagnostic.line === undefined ||
|
|
191
|
+
diagnostic.column === undefined) {
|
|
192
|
+
return diagnostic;
|
|
193
|
+
}
|
|
194
|
+
const programStart = getPositionOfLineAndCharacter(preparedFile.rewrittenText, diagnostic.line - 1, diagnostic.column - 1);
|
|
195
|
+
const programEnd = diagnostic.endLine !== undefined && diagnostic.endColumn !== undefined
|
|
196
|
+
? getPositionOfLineAndCharacter(preparedFile.rewrittenText, diagnostic.endLine - 1, diagnostic.endColumn - 1)
|
|
197
|
+
: programStart;
|
|
198
|
+
const mappedRange = mapProgramEnclosingRangeToSource(preparedFile, programStart, programEnd);
|
|
199
|
+
const mappedStart = getLineAndCharacterOfPosition(preparedFile.originalText, mappedRange.start);
|
|
200
|
+
const mappedEnd = getLineAndCharacterOfPosition(preparedFile.originalText, mappedRange.end);
|
|
201
|
+
return {
|
|
202
|
+
...diagnostic,
|
|
203
|
+
line: mappedStart.line + 1,
|
|
204
|
+
column: mappedStart.character + 1,
|
|
205
|
+
endLine: mappedEnd.line + 1,
|
|
206
|
+
endColumn: mappedEnd.character + 1,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
function remapSoundDiagnostics(diagnostics, diagnosticPreparedFiles) {
|
|
210
|
+
return diagnostics.map((diagnostic) => {
|
|
211
|
+
const preparedFile = diagnostic.filePath
|
|
212
|
+
? diagnosticPreparedFiles.get(toSourceFileName(diagnostic.filePath))
|
|
213
|
+
: undefined;
|
|
214
|
+
const remapped = remapPreparedSoundDiagnosticRange(diagnostic, preparedFile);
|
|
215
|
+
return {
|
|
216
|
+
...remapped,
|
|
217
|
+
relatedInformation: remapped.relatedInformation?.map((relatedInformation) => {
|
|
218
|
+
const relatedPreparedFile = relatedInformation.filePath
|
|
219
|
+
? diagnosticPreparedFiles.get(toSourceFileName(relatedInformation.filePath))
|
|
220
|
+
: undefined;
|
|
221
|
+
return remapPreparedSoundDiagnosticRange(relatedInformation, relatedPreparedFile);
|
|
222
|
+
}),
|
|
223
|
+
};
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
function remapMergedDiagnosticRange(mergedDiagnostic, diagnostic, preparedFile) {
|
|
227
|
+
if (!preparedFile || !diagnostic.file || diagnostic.start === undefined) {
|
|
228
|
+
return mergedDiagnostic;
|
|
229
|
+
}
|
|
230
|
+
const diagnosticLength = diagnostic.length ?? 0;
|
|
231
|
+
const diagnosticText = diagnostic.file.text.slice(diagnostic.start, diagnostic.start + diagnosticLength);
|
|
232
|
+
const rawLineStartsAt = diagnostic.file.text.lastIndexOf('\n', diagnostic.start - 1) + 1;
|
|
233
|
+
const rawNextNewline = diagnostic.file.text.indexOf('\n', diagnostic.start);
|
|
234
|
+
const rawLineEndsAt = rawNextNewline === -1 ? diagnostic.file.text.length : rawNextNewline;
|
|
235
|
+
const rawLineText = diagnostic.file.text.slice(rawLineStartsAt, rawLineEndsAt);
|
|
236
|
+
const mappedRange = mapProgramEnclosingRangeToSource(preparedFile, diagnostic.start, diagnostic.start + diagnosticLength);
|
|
237
|
+
const refinedRange = refineMappedRangeToMatchingText(preparedFile.originalText, mappedRange, diagnosticText, rawLineText);
|
|
238
|
+
const mappedStart = getLineAndCharacterOfPosition(preparedFile.originalText, refinedRange.start);
|
|
239
|
+
const mappedEnd = getLineAndCharacterOfPosition(preparedFile.originalText, refinedRange.end);
|
|
240
|
+
return {
|
|
241
|
+
...mergedDiagnostic,
|
|
242
|
+
line: mappedStart.line + 1,
|
|
243
|
+
column: mappedStart.character + 1,
|
|
244
|
+
endLine: mappedEnd.line + 1,
|
|
245
|
+
endColumn: mappedEnd.character + 1,
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
function refineMappedRangeToMatchingText(originalText, mappedRange, diagnosticText, rawLineText) {
|
|
249
|
+
if (mappedRange.intersectsReplacement ||
|
|
250
|
+
diagnosticText.length === 0 ||
|
|
251
|
+
diagnosticText.includes('\n') ||
|
|
252
|
+
diagnosticText.includes('\r')) {
|
|
253
|
+
return mappedRange;
|
|
254
|
+
}
|
|
255
|
+
if (originalText.slice(mappedRange.start, mappedRange.end) === diagnosticText) {
|
|
256
|
+
return mappedRange;
|
|
257
|
+
}
|
|
258
|
+
const lineStart = originalText.lastIndexOf('\n', mappedRange.start - 1) + 1;
|
|
259
|
+
const nextNewline = originalText.indexOf('\n', mappedRange.start);
|
|
260
|
+
const lineEnd = nextNewline === -1 ? originalText.length : nextNewline;
|
|
261
|
+
const lineText = originalText.slice(lineStart, lineEnd);
|
|
262
|
+
if (lineText !== rawLineText) {
|
|
263
|
+
return mappedRange;
|
|
264
|
+
}
|
|
265
|
+
let bestStart;
|
|
266
|
+
let searchIndex = lineText.indexOf(diagnosticText);
|
|
267
|
+
while (searchIndex !== -1) {
|
|
268
|
+
const candidateStart = lineStart + searchIndex;
|
|
269
|
+
if (bestStart === undefined ||
|
|
270
|
+
Math.abs(candidateStart - mappedRange.start) < Math.abs(bestStart - mappedRange.start)) {
|
|
271
|
+
bestStart = candidateStart;
|
|
272
|
+
}
|
|
273
|
+
searchIndex = lineText.indexOf(diagnosticText, searchIndex + 1);
|
|
274
|
+
}
|
|
275
|
+
if (bestStart === undefined) {
|
|
276
|
+
return mappedRange;
|
|
277
|
+
}
|
|
278
|
+
return {
|
|
279
|
+
intersectsReplacement: false,
|
|
280
|
+
start: bestStart,
|
|
281
|
+
end: bestStart + diagnosticText.length,
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
function toMappedMergedDiagnostic(diagnostic, diagnosticPreparedFiles) {
|
|
285
|
+
const mergedDiagnostic = toMergedDiagnostic(diagnostic);
|
|
286
|
+
const preparedFile = diagnostic.file
|
|
287
|
+
? diagnosticPreparedFiles.get(toSourceFileName(diagnostic.file.fileName))
|
|
288
|
+
: undefined;
|
|
289
|
+
const remapped = remapMergedDiagnosticRange(mergedDiagnostic, diagnostic, preparedFile);
|
|
290
|
+
if (!mergedDiagnostic.relatedInformation || !diagnostic.relatedInformation) {
|
|
291
|
+
return remapped;
|
|
292
|
+
}
|
|
293
|
+
return {
|
|
294
|
+
...remapped,
|
|
295
|
+
relatedInformation: mergedDiagnostic.relatedInformation.map((relatedInformation, index) => {
|
|
296
|
+
const relatedDiagnostic = diagnostic.relatedInformation?.[index];
|
|
297
|
+
const relatedPreparedFile = relatedDiagnostic?.file
|
|
298
|
+
? diagnosticPreparedFiles.get(toSourceFileName(relatedDiagnostic.file.fileName))
|
|
299
|
+
: undefined;
|
|
300
|
+
return remapMergedDiagnosticRange(relatedInformation, relatedDiagnostic ?? diagnostic, relatedPreparedFile);
|
|
301
|
+
}),
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
function mergeProjectedDeclarationOverrides(first, second) {
|
|
305
|
+
if (!first && !second) {
|
|
306
|
+
return undefined;
|
|
307
|
+
}
|
|
308
|
+
if (!first) {
|
|
309
|
+
return second;
|
|
310
|
+
}
|
|
311
|
+
if (!second) {
|
|
312
|
+
return first;
|
|
313
|
+
}
|
|
314
|
+
const merged = new Map(first);
|
|
315
|
+
for (const [fileName, text] of second) {
|
|
316
|
+
merged.set(fileName, text);
|
|
317
|
+
}
|
|
318
|
+
return merged;
|
|
319
|
+
}
|
|
320
|
+
function filterProjectedDeclarationOverridesToRootNames(projectedDeclarationOverrides, rootNames) {
|
|
321
|
+
if (!projectedDeclarationOverrides) {
|
|
322
|
+
return undefined;
|
|
323
|
+
}
|
|
324
|
+
const normalizedRootNames = new Set(rootNames.map((rootName) => ts.sys.resolvePath(rootName)));
|
|
325
|
+
const filtered = new Map();
|
|
326
|
+
for (const [fileName, text] of projectedDeclarationOverrides) {
|
|
327
|
+
if (normalizedRootNames.has(ts.sys.resolvePath(fileName))) {
|
|
328
|
+
filtered.set(fileName, text);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
return filtered;
|
|
332
|
+
}
|
|
333
|
+
function projectedDeclarationOverridesDiffer(first, second) {
|
|
334
|
+
if (!first && !second) {
|
|
335
|
+
return false;
|
|
336
|
+
}
|
|
337
|
+
if (!first || !second) {
|
|
338
|
+
return true;
|
|
339
|
+
}
|
|
340
|
+
if (first.size !== second.size) {
|
|
341
|
+
return true;
|
|
342
|
+
}
|
|
343
|
+
for (const [fileName, text] of first) {
|
|
344
|
+
if (second.get(fileName) !== text) {
|
|
345
|
+
return true;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
return false;
|
|
349
|
+
}
|
|
350
|
+
function collectProjectedDeclarationCandidateRootNames(program, existingOverrides, projectPackageJsonPath) {
|
|
351
|
+
const rootNames = new Set();
|
|
352
|
+
for (const sourceFile of program.getSourceFiles()) {
|
|
353
|
+
const sourceFileName = toSourceFileName(sourceFile.fileName);
|
|
354
|
+
if (!isSoundscriptSourceFile(sourceFileName)) {
|
|
355
|
+
continue;
|
|
356
|
+
}
|
|
357
|
+
if (isInstalledSoundStdlibSourceFileName(sourceFileName)) {
|
|
358
|
+
continue;
|
|
359
|
+
}
|
|
360
|
+
if (existingOverrides?.has(sourceFileName)) {
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
if (!isSupplementalPackageSourceCandidate(sourceFileName, projectPackageJsonPath)) {
|
|
364
|
+
continue;
|
|
365
|
+
}
|
|
366
|
+
rootNames.add(sourceFileName);
|
|
367
|
+
}
|
|
368
|
+
return [...rootNames].sort();
|
|
369
|
+
}
|
|
370
|
+
function hasNonRootProjectedDeclarationCandidates(program, soundscriptRootNameSet, projectPackageJsonPath) {
|
|
371
|
+
return program.getSourceFiles().some((sourceFile) => {
|
|
372
|
+
const sourceFileName = toSourceFileName(sourceFile.fileName);
|
|
373
|
+
return isSoundscriptSourceFile(sourceFileName) &&
|
|
374
|
+
!isInstalledSoundStdlibSourceFileName(sourceFileName) &&
|
|
375
|
+
isSupplementalPackageSourceCandidate(sourceFileName, projectPackageJsonPath) &&
|
|
376
|
+
!soundscriptRootNameSet.has(ts.sys.resolvePath(sourceFileName));
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
function collectProjectedDeclarationCandidateRootNamesFromPrograms(programs, existingOverrides, projectPackageJsonPath) {
|
|
380
|
+
const rootNames = new Set();
|
|
381
|
+
for (const program of programs) {
|
|
382
|
+
if (!program) {
|
|
383
|
+
continue;
|
|
384
|
+
}
|
|
385
|
+
for (const rootName of collectProjectedDeclarationCandidateRootNames(program, existingOverrides, projectPackageJsonPath)) {
|
|
386
|
+
rootNames.add(rootName);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
return [...rootNames].sort();
|
|
390
|
+
}
|
|
391
|
+
function isInstalledSoundStdlibSourceFileName(fileName) {
|
|
392
|
+
const normalizedFileName = toSourceFileName(fileName).replaceAll('\\', '/');
|
|
393
|
+
return normalizedFileName.includes('/node_modules/@soundscript/soundscript/soundscript/') &&
|
|
394
|
+
normalizedFileName.endsWith('.sts');
|
|
395
|
+
}
|
|
396
|
+
function isNodeModulesPath(fileName) {
|
|
397
|
+
const normalizedFileName = toSourceFileName(fileName).replaceAll('\\', '/');
|
|
398
|
+
return normalizedFileName.includes('/node_modules/');
|
|
399
|
+
}
|
|
400
|
+
function shouldAnalyzeSoundscriptSourceFile(sourceFile, preparedProgram) {
|
|
401
|
+
const sourceFileName = toSourceFileName(sourceFile.fileName);
|
|
402
|
+
return isSoundscriptSourceFile(sourceFileName) &&
|
|
403
|
+
!isInstalledSoundStdlibSourceFileName(sourceFileName) &&
|
|
404
|
+
!isMacroAuthoringSourceFile(sourceFile, preparedProgram);
|
|
405
|
+
}
|
|
406
|
+
function normalizeOptionalResolvedPath(path) {
|
|
407
|
+
return path ? ts.sys.resolvePath(path) : undefined;
|
|
408
|
+
}
|
|
409
|
+
function isSupplementalPackageSourceCandidate(fileName, projectPackageJsonPath) {
|
|
410
|
+
if (!isSoundscriptSourceFile(fileName) || isInstalledSoundStdlibSourceFileName(fileName)) {
|
|
411
|
+
return false;
|
|
412
|
+
}
|
|
413
|
+
const packageInfo = getSoundScriptPackageInfoForResolvedModule(fileName, ts.sys);
|
|
414
|
+
if (!packageInfo) {
|
|
415
|
+
return false;
|
|
416
|
+
}
|
|
417
|
+
const normalizedProjectPackageJsonPath = normalizeOptionalResolvedPath(projectPackageJsonPath);
|
|
418
|
+
const normalizedFilePackageJsonPath = normalizeOptionalResolvedPath(packageInfo.packageJsonPath);
|
|
419
|
+
return normalizedProjectPackageJsonPath === undefined ||
|
|
420
|
+
normalizedFilePackageJsonPath !== normalizedProjectPackageJsonPath;
|
|
421
|
+
}
|
|
422
|
+
function shouldAnalyzeProjectSoundscriptSourceFile(sourceFile, preparedProgram, projectPackageJsonPath) {
|
|
423
|
+
const sourceFileName = toSourceFileName(sourceFile.fileName);
|
|
424
|
+
return shouldAnalyzeSoundscriptSourceFile(sourceFile, preparedProgram) &&
|
|
425
|
+
!isSupplementalPackageSourceCandidate(sourceFileName, projectPackageJsonPath);
|
|
426
|
+
}
|
|
427
|
+
function shouldAnalyzeTypescriptViewSourceFile(sourceFile) {
|
|
428
|
+
return !isSoundscriptSourceFile(toSourceFileName(sourceFile.fileName));
|
|
429
|
+
}
|
|
430
|
+
function isIgnorableGeneratedTopLevelStatement(statement) {
|
|
431
|
+
return ts.isImportDeclaration(statement) &&
|
|
432
|
+
ts.isStringLiteralLike(statement.moduleSpecifier) &&
|
|
433
|
+
IGNORED_GENERATED_TOP_LEVEL_IMPORT_SPECIFIERS.has(statement.moduleSpecifier.text);
|
|
434
|
+
}
|
|
435
|
+
function hasGeneratedTopLevelStatements(sourceFile, isGeneratedNode) {
|
|
436
|
+
return sourceFile.statements.some((statement) => isGeneratedNode(statement) && !isIgnorableGeneratedTopLevelStatement(statement));
|
|
437
|
+
}
|
|
438
|
+
function createOriginalSourceFileForPreparedSource(fileName, preparedSource) {
|
|
439
|
+
return ts.createSourceFile(fileName, preparedSource.originalText, ts.ScriptTarget.Latest, true, /\.(?:[cm]?tsx|jsx|sts)$/iu.test(fileName) ? ts.ScriptKind.TSX : ts.ScriptKind.TS);
|
|
440
|
+
}
|
|
441
|
+
function findInnermostNodeContainingPosition(root, position) {
|
|
442
|
+
if (position < root.getFullStart() || position >= root.getEnd()) {
|
|
443
|
+
return undefined;
|
|
444
|
+
}
|
|
445
|
+
let best = root;
|
|
446
|
+
const visit = (node) => {
|
|
447
|
+
if (position < node.getFullStart() || position >= node.getEnd()) {
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
best = node;
|
|
451
|
+
ts.forEachChild(node, visit);
|
|
452
|
+
};
|
|
453
|
+
visit(root);
|
|
454
|
+
return best;
|
|
455
|
+
}
|
|
456
|
+
function isTopLevelMacroReplacement(originalSourceFile, preparedSource, replacementId) {
|
|
457
|
+
const macroInvocation = preparedSource.rewriteResult.macrosById.get(replacementId);
|
|
458
|
+
if (!macroInvocation) {
|
|
459
|
+
return false;
|
|
460
|
+
}
|
|
461
|
+
const anchorPosition = macroInvocation.declarationSpan?.start ?? macroInvocation.span.start;
|
|
462
|
+
const anchorNode = findInnermostNodeContainingPosition(originalSourceFile, anchorPosition);
|
|
463
|
+
if (!anchorNode || ts.isSourceFile(anchorNode)) {
|
|
464
|
+
return false;
|
|
465
|
+
}
|
|
466
|
+
let current = anchorNode;
|
|
467
|
+
while (current?.parent && !ts.isSourceFile(current.parent)) {
|
|
468
|
+
if (ts.isBlock(current.parent) ||
|
|
469
|
+
ts.isFunctionLike(current.parent) ||
|
|
470
|
+
ts.isModuleBlock(current.parent)) {
|
|
471
|
+
return false;
|
|
472
|
+
}
|
|
473
|
+
current = current.parent;
|
|
474
|
+
}
|
|
475
|
+
return current !== undefined && ts.isSourceFile(current.parent);
|
|
476
|
+
}
|
|
477
|
+
function hasTopLevelMacroReplacements(fileName, preparedSource) {
|
|
478
|
+
if (!preparedSource || preparedSource.rewriteResult.replacements.length === 0) {
|
|
479
|
+
return false;
|
|
480
|
+
}
|
|
481
|
+
const originalSourceFile = createOriginalSourceFileForPreparedSource(fileName, preparedSource);
|
|
482
|
+
return preparedSource.rewriteResult.replacements.some((replacement) => isTopLevelMacroReplacement(originalSourceFile, preparedSource, replacement.id));
|
|
483
|
+
}
|
|
484
|
+
function prepareAnalysisView(options, loadedConfig, rootNames, baseHost, configFileParsingDiagnostics, includeSourceFile, projectedDeclarationOverrides, runSound, universalPolicyScope = 'full', reusableCompilerHostState, oldProgram) {
|
|
485
|
+
if (rootNames.length === 0) {
|
|
486
|
+
return null;
|
|
487
|
+
}
|
|
488
|
+
const expandedProgram = createBuiltinExpandedProgram({
|
|
489
|
+
allowSupplementalDiagnosticPrograms: true,
|
|
490
|
+
baseHost,
|
|
491
|
+
configFileParsingDiagnostics,
|
|
492
|
+
fileOverrides: options.fileOverrides ?? new Map(),
|
|
493
|
+
oldProgram,
|
|
494
|
+
options: loadedConfig.commandLine.options,
|
|
495
|
+
projectReferences: loadedConfig.commandLine.projectReferences,
|
|
496
|
+
projectedDeclarationOverrides,
|
|
497
|
+
runtime: loadedConfig.runtime,
|
|
498
|
+
reusableCompilerHostState,
|
|
499
|
+
rootNames,
|
|
500
|
+
});
|
|
501
|
+
const program = expandedProgram.program;
|
|
502
|
+
const isGeneratedNode = createPreparedProgramGeneratedNodeDetector(expandedProgram.analysisPreparedProgram);
|
|
503
|
+
const sourceFileHasTopLevelMacroReplacements = (sourceFile) => {
|
|
504
|
+
const sourceFileName = expandedProgram.analysisPreparedProgram.toSourceFileName(sourceFile.fileName);
|
|
505
|
+
const preparedSource = expandedProgram.preparedProgram.preparedHost.getPreparedSourceFile(sourceFileName);
|
|
506
|
+
return hasTopLevelMacroReplacements(sourceFileName, preparedSource);
|
|
507
|
+
};
|
|
508
|
+
const analysisContext = createAnalysisContext({
|
|
509
|
+
includeSourceFile: includeSourceFile
|
|
510
|
+
? (sourceFile) => !sourceFileHasTopLevelMacroReplacements(sourceFile) &&
|
|
511
|
+
!hasGeneratedTopLevelStatements(sourceFile, isGeneratedNode) &&
|
|
512
|
+
includeSourceFile(sourceFile, expandedProgram.analysisPreparedProgram)
|
|
513
|
+
: (sourceFile) => !sourceFileHasTopLevelMacroReplacements(sourceFile) &&
|
|
514
|
+
!hasGeneratedTopLevelStatements(sourceFile, isGeneratedNode),
|
|
515
|
+
isGeneratedNode,
|
|
516
|
+
program,
|
|
517
|
+
runtime: loadedConfig.runtime,
|
|
518
|
+
workingDirectory: options.workingDirectory,
|
|
519
|
+
});
|
|
520
|
+
return {
|
|
521
|
+
analysisContext,
|
|
522
|
+
analysisPreparedProgram: expandedProgram.analysisPreparedProgram,
|
|
523
|
+
diagnosticPreparedFiles: expandedProgram.diagnosticPreparedFiles,
|
|
524
|
+
frontendDiagnostics: remapDiagnostics(expandedProgram.frontendDiagnostics()),
|
|
525
|
+
macroEnvironment: expandedProgram.macroEnvironment,
|
|
526
|
+
macroCacheStats: expandedProgram.macroEnvironment.cacheStats(),
|
|
527
|
+
preparedProgram: expandedProgram.preparedProgram,
|
|
528
|
+
program,
|
|
529
|
+
runSound,
|
|
530
|
+
tsDiagnosticPrograms: expandedProgram.tsDiagnosticPrograms,
|
|
531
|
+
universalPolicyScope,
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
function analyzePreparedView(preparedView) {
|
|
535
|
+
if (!preparedView) {
|
|
536
|
+
return {
|
|
537
|
+
frontendDiagnostics: [],
|
|
538
|
+
tsDiagnostics: [],
|
|
539
|
+
soundDiagnostics: [],
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
const frontendDiagnostics = [...preparedView.frontendDiagnostics];
|
|
543
|
+
const tsDiagnostics = collectPreparedViewTsDiagnostics(preparedView, frontendDiagnostics);
|
|
544
|
+
const hasFrontendErrors = hasErrorDiagnostics(frontendDiagnostics);
|
|
545
|
+
const hasTsErrors = hasErrorDiagnostics(tsDiagnostics);
|
|
546
|
+
const universalDiagnostics = hasFrontendErrors ? [] : collectPreparedViewUniversalDiagnostics(preparedView, preparedView.analysisContext);
|
|
547
|
+
const soundDiagnostics = hasFrontendErrors ? [] : collectPreparedViewSoundDiagnostics(preparedView, preparedView.analysisContext);
|
|
548
|
+
return {
|
|
549
|
+
frontendDiagnostics,
|
|
550
|
+
tsDiagnostics,
|
|
551
|
+
soundDiagnostics: hasTsErrors
|
|
552
|
+
? retainSoundDiagnosticsAlongsideTsErrors([...universalDiagnostics, ...soundDiagnostics])
|
|
553
|
+
: [...universalDiagnostics, ...soundDiagnostics],
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
function emitProjectedDeclarationsFailClosed(preparedView, rootNames) {
|
|
557
|
+
if (!preparedView) {
|
|
558
|
+
return undefined;
|
|
559
|
+
}
|
|
560
|
+
try {
|
|
561
|
+
return emitProjectedDeclarations(preparedView.analysisPreparedProgram, rootNames);
|
|
562
|
+
}
|
|
563
|
+
catch (error) {
|
|
564
|
+
const analyzedView = analyzePreparedView(preparedView);
|
|
565
|
+
if (hasErrorDiagnostics([
|
|
566
|
+
...analyzedView.frontendDiagnostics,
|
|
567
|
+
...analyzedView.tsDiagnostics,
|
|
568
|
+
...analyzedView.soundDiagnostics,
|
|
569
|
+
])) {
|
|
570
|
+
return undefined;
|
|
571
|
+
}
|
|
572
|
+
throw error;
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
function analyzePreparedViewForFile(preparedView, filePath) {
|
|
576
|
+
if (!preparedView) {
|
|
577
|
+
return {
|
|
578
|
+
frontendDiagnostics: [],
|
|
579
|
+
tsDiagnostics: [],
|
|
580
|
+
soundDiagnostics: [],
|
|
581
|
+
};
|
|
582
|
+
}
|
|
583
|
+
const frontendDiagnosticPaths = collectPreparedViewFrontendDiagnosticPaths(preparedView, filePath);
|
|
584
|
+
const frontendDiagnostics = preparedView.frontendDiagnostics.filter((diagnostic) => matchesPreparedAnalysisAnyFilePath(diagnostic.filePath, frontendDiagnosticPaths));
|
|
585
|
+
const tsDiagnostics = collectPreparedViewTsDiagnostics(preparedView, frontendDiagnostics, filePath, true);
|
|
586
|
+
const hasFrontendErrors = hasErrorDiagnostics(frontendDiagnostics);
|
|
587
|
+
const hasTsErrors = hasErrorDiagnostics(tsDiagnostics);
|
|
588
|
+
const fileScopedAnalysisContext = getFileScopedAnalysisContext(preparedView, filePath);
|
|
589
|
+
const universalDiagnostics = !fileScopedAnalysisContext || hasFrontendErrors
|
|
590
|
+
? []
|
|
591
|
+
: filterAnalyzedDiagnosticsForFile(collectPreparedViewUniversalDiagnostics(preparedView, fileScopedAnalysisContext, filePath), filePath);
|
|
592
|
+
const soundDiagnostics = !fileScopedAnalysisContext ||
|
|
593
|
+
hasFrontendErrors
|
|
594
|
+
? []
|
|
595
|
+
: filterAnalyzedDiagnosticsForFile(collectPreparedViewSoundDiagnostics(preparedView, fileScopedAnalysisContext, filePath), filePath);
|
|
596
|
+
return {
|
|
597
|
+
frontendDiagnostics,
|
|
598
|
+
tsDiagnostics,
|
|
599
|
+
soundDiagnostics: hasTsErrors
|
|
600
|
+
? retainSoundDiagnosticsAlongsideTsErrors([...universalDiagnostics, ...soundDiagnostics])
|
|
601
|
+
: [...universalDiagnostics, ...soundDiagnostics],
|
|
602
|
+
};
|
|
603
|
+
}
|
|
604
|
+
function analyzePreparedViewForDiagnosticPaths(preparedView, diagnosticPaths) {
|
|
605
|
+
if (!preparedView || diagnosticPaths.length === 0) {
|
|
606
|
+
return {
|
|
607
|
+
frontendDiagnostics: [],
|
|
608
|
+
tsDiagnostics: [],
|
|
609
|
+
soundDiagnostics: [],
|
|
610
|
+
};
|
|
611
|
+
}
|
|
612
|
+
const frontendDiagnostics = preparedView.frontendDiagnostics.filter((diagnostic) => matchesPreparedAnalysisAnyFilePath(diagnostic.filePath, diagnosticPaths));
|
|
613
|
+
const tsDiagnostics = hasErrorDiagnostics(frontendDiagnostics)
|
|
614
|
+
? []
|
|
615
|
+
: collectPreparedViewTsDiagnostics(preparedView, frontendDiagnostics).filter((diagnostic) => matchesPreparedAnalysisAnyFilePath(diagnostic.filePath, diagnosticPaths));
|
|
616
|
+
const hasFrontendErrors = hasErrorDiagnostics(frontendDiagnostics);
|
|
617
|
+
const hasTsErrors = hasErrorDiagnostics(tsDiagnostics);
|
|
618
|
+
const universalDiagnostics = hasFrontendErrors
|
|
619
|
+
? []
|
|
620
|
+
: collectPreparedViewUniversalDiagnostics(preparedView, preparedView.analysisContext).filter((diagnostic) => matchesPreparedAnalysisAnyFilePath(diagnostic.filePath, diagnosticPaths));
|
|
621
|
+
const soundDiagnostics = hasFrontendErrors
|
|
622
|
+
? []
|
|
623
|
+
: collectPreparedViewSoundDiagnostics(preparedView, preparedView.analysisContext).filter((diagnostic) => matchesPreparedAnalysisAnyFilePath(diagnostic.filePath, diagnosticPaths));
|
|
624
|
+
return {
|
|
625
|
+
frontendDiagnostics,
|
|
626
|
+
tsDiagnostics,
|
|
627
|
+
soundDiagnostics: hasTsErrors
|
|
628
|
+
? retainSoundDiagnosticsAlongsideTsErrors([...universalDiagnostics, ...soundDiagnostics])
|
|
629
|
+
: [...universalDiagnostics, ...soundDiagnostics],
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
function retainSoundDiagnosticsAlongsideTsErrors(diagnostics) {
|
|
633
|
+
return diagnostics.filter((diagnostic) => diagnostic.source === 'sound' &&
|
|
634
|
+
(diagnostic.code === SOUND_DIAGNOSTIC_CODES.constructionLifecycleViolation ||
|
|
635
|
+
diagnostic.code === SOUND_DIAGNOSTIC_CODES.fieldReadBeforeInitialization));
|
|
636
|
+
}
|
|
637
|
+
function matchesPreparedAnalysisAnyFilePath(candidateFilePath, expectedFilePaths) {
|
|
638
|
+
return expectedFilePaths.some((expectedFilePath) => matchesPreparedAnalysisFilePath(candidateFilePath, expectedFilePath));
|
|
639
|
+
}
|
|
640
|
+
function collectPreparedViewFrontendDiagnosticPaths(preparedView, filePath) {
|
|
641
|
+
const diagnosticPaths = new Set();
|
|
642
|
+
const addDiagnosticPath = (candidateFilePath) => {
|
|
643
|
+
for (const variant of collectPreparedAnalysisFilePathCandidates(candidateFilePath)) {
|
|
644
|
+
diagnosticPaths.add(variant);
|
|
645
|
+
}
|
|
646
|
+
if (isSoundscriptSourceFile(candidateFilePath)) {
|
|
647
|
+
for (const variant of collectPreparedAnalysisFilePathCandidates(toProjectedDeclarationFileName(candidateFilePath))) {
|
|
648
|
+
diagnosticPaths.add(variant);
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
};
|
|
652
|
+
addDiagnosticPath(filePath);
|
|
653
|
+
const traversalRoots = [];
|
|
654
|
+
const addTraversalRoot = (key, program, sourceFile) => {
|
|
655
|
+
if (!sourceFile || traversalRoots.some((root) => root.key === key)) {
|
|
656
|
+
return;
|
|
657
|
+
}
|
|
658
|
+
traversalRoots.push({ key, program, sourceFile });
|
|
659
|
+
};
|
|
660
|
+
const sourceFileMatch = getPreparedViewSourceFileMatch(preparedView, filePath);
|
|
661
|
+
addTraversalRoot('prepared', preparedView.program, sourceFileMatch?.sourceFile ?? null);
|
|
662
|
+
const tsDiagnosticProgramMatch = getPreparedViewTsDiagnosticProgramMatch(preparedView, filePath);
|
|
663
|
+
addTraversalRoot(`ts:${tsDiagnosticProgramMatch?.diagnosticProgram.filePaths?.join(',') ?? 'all'}`, tsDiagnosticProgramMatch?.diagnosticProgram.program ?? preparedView.program, tsDiagnosticProgramMatch?.sourceFile ?? null);
|
|
664
|
+
if (traversalRoots.length === 0) {
|
|
665
|
+
return [...diagnosticPaths];
|
|
666
|
+
}
|
|
667
|
+
const visitedSourceFiles = new Set();
|
|
668
|
+
const getTraversalSourceFile = (program, candidateFilePath) => {
|
|
669
|
+
for (const candidate of collectPreparedAnalysisFilePathCandidates(candidateFilePath)) {
|
|
670
|
+
const sourceFile = program.getSourceFile(preparedView.preparedProgram.toProgramFileName(candidate));
|
|
671
|
+
if (sourceFile) {
|
|
672
|
+
return sourceFile;
|
|
673
|
+
}
|
|
674
|
+
if (isSoundscriptSourceFile(candidate)) {
|
|
675
|
+
const projectedCandidate = toProjectedDeclarationFileName(candidate);
|
|
676
|
+
const projectedSourceFile = program.getSourceFile(preparedView.preparedProgram.toProgramFileName(projectedCandidate));
|
|
677
|
+
if (projectedSourceFile) {
|
|
678
|
+
return projectedSourceFile;
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
return null;
|
|
683
|
+
};
|
|
684
|
+
const visit = (programKey, program, sourceFile) => {
|
|
685
|
+
const sourceFilePath = preparedView.preparedProgram.toSourceFileName(sourceFile.fileName);
|
|
686
|
+
const visitKey = `${programKey}:${sourceFilePath}`;
|
|
687
|
+
if (visitedSourceFiles.has(visitKey)) {
|
|
688
|
+
return;
|
|
689
|
+
}
|
|
690
|
+
visitedSourceFiles.add(visitKey);
|
|
691
|
+
addDiagnosticPath(sourceFilePath);
|
|
692
|
+
for (const moduleSpecifier of getStaticSourceFileModuleSpecifiers(sourceFile)) {
|
|
693
|
+
const resolvedModule = resolveSoundScriptAwareModule(moduleSpecifier, sourceFilePath, preparedView.preparedProgram.options, preparedView.preparedProgram.preparedHost.host);
|
|
694
|
+
if (!resolvedModule) {
|
|
695
|
+
continue;
|
|
696
|
+
}
|
|
697
|
+
const resolvedSourcePath = preparedView.preparedProgram.toSourceFileName(resolvedModule.resolvedFileName);
|
|
698
|
+
if (!isSoundscriptSourceFile(resolvedSourcePath) &&
|
|
699
|
+
!isProjectedSoundscriptDeclarationFile(resolvedSourcePath)) {
|
|
700
|
+
continue;
|
|
701
|
+
}
|
|
702
|
+
addDiagnosticPath(resolvedSourcePath);
|
|
703
|
+
const dependencySourceFile = getTraversalSourceFile(program, resolvedSourcePath);
|
|
704
|
+
if (dependencySourceFile) {
|
|
705
|
+
visit(programKey, program, dependencySourceFile);
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
};
|
|
709
|
+
for (const traversalRoot of traversalRoots) {
|
|
710
|
+
visit(traversalRoot.key, traversalRoot.program, traversalRoot.sourceFile);
|
|
711
|
+
}
|
|
712
|
+
return [...diagnosticPaths];
|
|
713
|
+
}
|
|
714
|
+
function getStaticSourceFileModuleSpecifiers(sourceFile) {
|
|
715
|
+
const moduleSpecifiers = [];
|
|
716
|
+
for (const statement of sourceFile.statements) {
|
|
717
|
+
if ((ts.isImportDeclaration(statement) || ts.isExportDeclaration(statement)) &&
|
|
718
|
+
statement.moduleSpecifier &&
|
|
719
|
+
ts.isStringLiteral(statement.moduleSpecifier)) {
|
|
720
|
+
moduleSpecifiers.push(statement.moduleSpecifier.text);
|
|
721
|
+
continue;
|
|
722
|
+
}
|
|
723
|
+
if (ts.isImportEqualsDeclaration(statement) &&
|
|
724
|
+
ts.isExternalModuleReference(statement.moduleReference) &&
|
|
725
|
+
ts.isStringLiteral(statement.moduleReference.expression)) {
|
|
726
|
+
moduleSpecifiers.push(statement.moduleReference.expression.text);
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
return moduleSpecifiers;
|
|
730
|
+
}
|
|
731
|
+
function getPreparedViewTsDiagnosticProgramMatch(preparedView, filePath) {
|
|
732
|
+
const preferredPrograms = [
|
|
733
|
+
...preparedView.tsDiagnosticPrograms.filter((program) => program.filePaths !== undefined),
|
|
734
|
+
...preparedView.tsDiagnosticPrograms.filter((program) => program.filePaths === undefined),
|
|
735
|
+
];
|
|
736
|
+
for (const candidateFilePath of collectPreparedAnalysisFilePathCandidates(filePath)) {
|
|
737
|
+
const programFileName = preparedView.preparedProgram.toProgramFileName(candidateFilePath);
|
|
738
|
+
for (const diagnosticProgram of preferredPrograms) {
|
|
739
|
+
if (diagnosticProgram.filePaths !== undefined &&
|
|
740
|
+
!diagnosticProgram.filePaths.includes(candidateFilePath)) {
|
|
741
|
+
continue;
|
|
742
|
+
}
|
|
743
|
+
const sourceFile = diagnosticProgram.program.getSourceFile(programFileName);
|
|
744
|
+
if (!sourceFile) {
|
|
745
|
+
continue;
|
|
746
|
+
}
|
|
747
|
+
return {
|
|
748
|
+
diagnosticProgram,
|
|
749
|
+
matchedFilePath: candidateFilePath,
|
|
750
|
+
sourceFile,
|
|
751
|
+
};
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
return null;
|
|
755
|
+
}
|
|
756
|
+
function collectPreparedViewTsDiagnostics(preparedView, frontendDiagnostics, filePath, requireSourceFile = false) {
|
|
757
|
+
if (preparedView.universalPolicyScope === 'sourceSupplemental' ||
|
|
758
|
+
hasErrorDiagnostics(frontendDiagnostics) ||
|
|
759
|
+
(requireSourceFile && !filePath)) {
|
|
760
|
+
return [];
|
|
761
|
+
}
|
|
762
|
+
const sourceFileMatch = filePath
|
|
763
|
+
? getPreparedViewTsDiagnosticProgramMatch(preparedView, filePath)
|
|
764
|
+
: null;
|
|
765
|
+
if (requireSourceFile && !sourceFileMatch) {
|
|
766
|
+
return [];
|
|
767
|
+
}
|
|
768
|
+
const metadata = {
|
|
769
|
+
fileScoped: filePath !== undefined,
|
|
770
|
+
requireSourceFile,
|
|
771
|
+
rootCount: sourceFileMatch
|
|
772
|
+
? sourceFileMatch.diagnosticProgram.program.getRootFileNames().length
|
|
773
|
+
: preparedView.program.getRootFileNames().length,
|
|
774
|
+
universalPolicyScope: preparedView.universalPolicyScope,
|
|
775
|
+
};
|
|
776
|
+
if (sourceFileMatch) {
|
|
777
|
+
metadata.filePath = sourceFileMatch.matchedFilePath;
|
|
778
|
+
}
|
|
779
|
+
const diagnostics = measureCheckerTiming('project.analyze.tsDiagnostics', metadata, () => {
|
|
780
|
+
const handledFilePaths = new Set(preparedView.tsDiagnosticPrograms.flatMap((diagnosticProgram) => diagnosticProgram.filePaths ? [...diagnosticProgram.filePaths] : []));
|
|
781
|
+
const collectedDiagnostics = sourceFileMatch
|
|
782
|
+
? ts.getPreEmitDiagnostics(sourceFileMatch.diagnosticProgram.program, sourceFileMatch.sourceFile)
|
|
783
|
+
: preparedView.tsDiagnosticPrograms.flatMap((diagnosticProgram) => {
|
|
784
|
+
if (!diagnosticProgram.filePaths || diagnosticProgram.filePaths.length === 0) {
|
|
785
|
+
return ts.getPreEmitDiagnostics(diagnosticProgram.program).filter((diagnostic) => !diagnostic.file ||
|
|
786
|
+
!handledFilePaths.has(toSourceFileName(diagnostic.file.fileName)));
|
|
787
|
+
}
|
|
788
|
+
return diagnosticProgram.filePaths.flatMap((diagnosticFilePath) => {
|
|
789
|
+
const programFileName = preparedView.preparedProgram.toProgramFileName(diagnosticFilePath);
|
|
790
|
+
const diagnosticSourceFile = diagnosticProgram.program.getSourceFile(programFileName);
|
|
791
|
+
return diagnosticSourceFile
|
|
792
|
+
? ts.getPreEmitDiagnostics(diagnosticProgram.program, diagnosticSourceFile)
|
|
793
|
+
: [];
|
|
794
|
+
});
|
|
795
|
+
});
|
|
796
|
+
metadata.diagnostics = collectedDiagnostics.length;
|
|
797
|
+
return collectedDiagnostics;
|
|
798
|
+
}, { always: true });
|
|
799
|
+
return remapDiagnostics(diagnostics.map((diagnostic) => toMappedMergedDiagnostic(diagnostic, preparedView.diagnosticPreparedFiles)));
|
|
800
|
+
}
|
|
801
|
+
function collectPreparedViewUniversalDiagnostics(preparedView, analysisContext, filePath) {
|
|
802
|
+
const metadata = {
|
|
803
|
+
fileScoped: filePath !== undefined,
|
|
804
|
+
rootCount: preparedView.program.getRootFileNames().length,
|
|
805
|
+
universalPolicyScope: preparedView.universalPolicyScope,
|
|
806
|
+
};
|
|
807
|
+
if (filePath) {
|
|
808
|
+
metadata.filePath = filePath;
|
|
809
|
+
}
|
|
810
|
+
return measureCheckerTiming('project.analyze.universalPolicy', metadata, () => {
|
|
811
|
+
const diagnostics = remapDiagnostics(remapSoundDiagnostics(preparedView.universalPolicyScope === 'sourceSupplemental'
|
|
812
|
+
? runSourceSupplementalPolicyAnalysis(analysisContext)
|
|
813
|
+
: runUniversalPolicyAnalysis(analysisContext), preparedView.diagnosticPreparedFiles));
|
|
814
|
+
metadata.diagnostics = diagnostics.length;
|
|
815
|
+
return diagnostics;
|
|
816
|
+
}, { always: true });
|
|
817
|
+
}
|
|
818
|
+
function collectPreparedViewSoundDiagnostics(preparedView, analysisContext, filePath) {
|
|
819
|
+
const metadata = {
|
|
820
|
+
fileScoped: filePath !== undefined,
|
|
821
|
+
rootCount: preparedView.program.getRootFileNames().length,
|
|
822
|
+
runSound: preparedView.runSound,
|
|
823
|
+
};
|
|
824
|
+
if (filePath) {
|
|
825
|
+
metadata.filePath = filePath;
|
|
826
|
+
}
|
|
827
|
+
return measureCheckerTiming('project.analyze.soundRules', metadata, () => {
|
|
828
|
+
const diagnostics = remapDiagnostics(remapSoundDiagnostics(preparedView.runSound ? runSoundAnalysis(analysisContext) : [], preparedView.diagnosticPreparedFiles));
|
|
829
|
+
metadata.diagnostics = diagnostics.length;
|
|
830
|
+
return diagnostics;
|
|
831
|
+
}, { always: true });
|
|
832
|
+
}
|
|
833
|
+
function getFileScopedAnalysisContext(preparedView, filePath) {
|
|
834
|
+
let byFile = fileScopedAnalysisContextCache.get(preparedView);
|
|
835
|
+
if (!byFile) {
|
|
836
|
+
byFile = new Map();
|
|
837
|
+
fileScopedAnalysisContextCache.set(preparedView, byFile);
|
|
838
|
+
}
|
|
839
|
+
const cached = byFile.get(filePath);
|
|
840
|
+
if (cached !== undefined) {
|
|
841
|
+
return cached;
|
|
842
|
+
}
|
|
843
|
+
const sourceFileMatch = getPreparedViewSourceFileMatch(preparedView, filePath);
|
|
844
|
+
if (!sourceFileMatch) {
|
|
845
|
+
byFile.set(filePath, null);
|
|
846
|
+
return null;
|
|
847
|
+
}
|
|
848
|
+
const sourceFile = sourceFileMatch.sourceFile;
|
|
849
|
+
const preparedSource = preparedView.preparedProgram.preparedHost.getPreparedSourceFile(sourceFileMatch.matchedFilePath);
|
|
850
|
+
if (hasTopLevelMacroReplacements(sourceFileMatch.matchedFilePath, preparedSource) ||
|
|
851
|
+
hasGeneratedTopLevelStatements(sourceFile, preparedView.analysisContext.isGeneratedNode)) {
|
|
852
|
+
byFile.set(filePath, null);
|
|
853
|
+
return null;
|
|
854
|
+
}
|
|
855
|
+
const analysisContext = createAnalysisContext({
|
|
856
|
+
includeSourceFile: (candidate) => matchesPreparedAnalysisFilePath(toSourceFileName(candidate.fileName), filePath) &&
|
|
857
|
+
!isMacroAuthoringSourceFile(candidate, preparedView.analysisPreparedProgram),
|
|
858
|
+
isGeneratedNode: createPreparedProgramGeneratedNodeDetector(preparedView.analysisPreparedProgram),
|
|
859
|
+
program: preparedView.program,
|
|
860
|
+
runtime: preparedView.analysisContext.runtime,
|
|
861
|
+
workingDirectory: preparedView.analysisContext.workingDirectory,
|
|
862
|
+
});
|
|
863
|
+
byFile.set(filePath, analysisContext);
|
|
864
|
+
return analysisContext;
|
|
865
|
+
}
|
|
866
|
+
function createSummary(diagnostics) {
|
|
867
|
+
return {
|
|
868
|
+
total: diagnostics.length,
|
|
869
|
+
errors: diagnostics.filter((diagnostic) => diagnostic.category === 'error').length,
|
|
870
|
+
warnings: diagnostics.filter((diagnostic) => diagnostic.category === 'warning').length,
|
|
871
|
+
messages: diagnostics.filter((diagnostic) => diagnostic.category === 'message').length,
|
|
872
|
+
};
|
|
873
|
+
}
|
|
874
|
+
function isMacroAuthoringSourceFile(sourceFile, preparedProgram) {
|
|
875
|
+
const sourceText = preparedProgram?.preparedHost.getPreparedSourceFile(toSourceFileName(sourceFile.fileName))?.originalText ?? sourceFile.text;
|
|
876
|
+
return sourceTextLooksLikeMacroModule(sourceText) ||
|
|
877
|
+
usesLegacyDefineMacroAuthoring(sourceText);
|
|
878
|
+
}
|
|
879
|
+
function applyMacroCacheStatsToMetadata(metadata, macroCacheStats) {
|
|
880
|
+
metadata.macroCacheHits = macroCacheStats.moduleCacheHits;
|
|
881
|
+
metadata.macroCacheMisses = macroCacheStats.moduleCacheMisses;
|
|
882
|
+
metadata.macroCacheInvalidations = macroCacheStats.moduleCacheInvalidations;
|
|
883
|
+
metadata.macroModulesEvaluated = macroCacheStats.evaluatedModules;
|
|
884
|
+
}
|
|
885
|
+
function createPreparedProgramGeneratedNodeDetector(preparedProgram) {
|
|
886
|
+
const preparedFileCache = new Map();
|
|
887
|
+
function getPreparedFile(sourceFile) {
|
|
888
|
+
if (!sourceFile) {
|
|
889
|
+
return undefined;
|
|
890
|
+
}
|
|
891
|
+
const sourceFileName = toSourceFileName(sourceFile.fileName);
|
|
892
|
+
if (preparedFileCache.has(sourceFileName)) {
|
|
893
|
+
return preparedFileCache.get(sourceFileName) ?? undefined;
|
|
894
|
+
}
|
|
895
|
+
const preparedFile = preparedProgram.preparedHost.getPreparedSourceFile(sourceFileName);
|
|
896
|
+
preparedFileCache.set(sourceFileName, preparedFile ?? null);
|
|
897
|
+
return preparedFile;
|
|
898
|
+
}
|
|
899
|
+
return (node) => {
|
|
900
|
+
if (ts.isSourceFile(node)) {
|
|
901
|
+
return false;
|
|
902
|
+
}
|
|
903
|
+
const sourceFile = node.getSourceFile();
|
|
904
|
+
const preparedFile = getPreparedFile(sourceFile);
|
|
905
|
+
if (!preparedFile) {
|
|
906
|
+
return false;
|
|
907
|
+
}
|
|
908
|
+
const programStart = node.getStart(sourceFile, false);
|
|
909
|
+
const programEnd = node.getEnd();
|
|
910
|
+
if (programEnd <= programStart) {
|
|
911
|
+
return false;
|
|
912
|
+
}
|
|
913
|
+
const startMapping = mapProgramPositionToSource(preparedFile, programStart);
|
|
914
|
+
const endMapping = mapProgramPositionToSource(preparedFile, Math.max(programStart, programEnd - 1));
|
|
915
|
+
return startMapping.insideReplacement && endMapping.insideReplacement;
|
|
916
|
+
};
|
|
917
|
+
}
|
|
918
|
+
function aggregateMacroCacheStats(preparedProject) {
|
|
919
|
+
const aggregated = {
|
|
920
|
+
evaluatedModules: 0,
|
|
921
|
+
moduleCacheHits: 0,
|
|
922
|
+
moduleCacheInvalidations: 0,
|
|
923
|
+
moduleCacheMisses: 0,
|
|
924
|
+
};
|
|
925
|
+
for (const view of [
|
|
926
|
+
preparedProject.tsView,
|
|
927
|
+
preparedProject.stsView,
|
|
928
|
+
preparedProject.packageSourcePolicyView,
|
|
929
|
+
]) {
|
|
930
|
+
if (!view) {
|
|
931
|
+
continue;
|
|
932
|
+
}
|
|
933
|
+
aggregated.evaluatedModules += view.macroCacheStats.evaluatedModules;
|
|
934
|
+
aggregated.moduleCacheHits += view.macroCacheStats.moduleCacheHits;
|
|
935
|
+
aggregated.moduleCacheInvalidations += view.macroCacheStats.moduleCacheInvalidations;
|
|
936
|
+
aggregated.moduleCacheMisses += view.macroCacheStats.moduleCacheMisses;
|
|
937
|
+
}
|
|
938
|
+
return aggregated;
|
|
939
|
+
}
|
|
940
|
+
function collectPreparedProjectViews(preparedProject) {
|
|
941
|
+
if (!preparedProject) {
|
|
942
|
+
return [];
|
|
943
|
+
}
|
|
944
|
+
return [
|
|
945
|
+
preparedProject.tsView,
|
|
946
|
+
preparedProject.stsView,
|
|
947
|
+
preparedProject.packageSourcePolicyView,
|
|
948
|
+
].filter((view) => view !== null);
|
|
949
|
+
}
|
|
950
|
+
export function disposePreparedAnalysisProject(preparedProject, retainedProject) {
|
|
951
|
+
const retainedViews = new Set(collectPreparedProjectViews(retainedProject));
|
|
952
|
+
const retainedPreparedPrograms = new Set(collectPreparedProjectViews(retainedProject).flatMap((view) => [
|
|
953
|
+
view.analysisPreparedProgram,
|
|
954
|
+
view.preparedProgram,
|
|
955
|
+
]));
|
|
956
|
+
const retainedReuseStates = new Set([...retainedPreparedPrograms].map((preparedProgram) => preparedProgram.preparedHost.reuseState));
|
|
957
|
+
const disposedMacroEnvironments = new Set();
|
|
958
|
+
const disposedPreparedPrograms = new Set();
|
|
959
|
+
for (const view of collectPreparedProjectViews(preparedProject)) {
|
|
960
|
+
if (retainedViews.has(view)) {
|
|
961
|
+
continue;
|
|
962
|
+
}
|
|
963
|
+
const macroEnvironment = view.macroEnvironment;
|
|
964
|
+
if (disposedMacroEnvironments.has(macroEnvironment)) {
|
|
965
|
+
continue;
|
|
966
|
+
}
|
|
967
|
+
disposedMacroEnvironments.add(macroEnvironment);
|
|
968
|
+
view.macroEnvironment.dispose();
|
|
969
|
+
for (const preparedProgram of [view.analysisPreparedProgram, view.preparedProgram]) {
|
|
970
|
+
if (disposedPreparedPrograms.has(preparedProgram) ||
|
|
971
|
+
retainedPreparedPrograms.has(preparedProgram)) {
|
|
972
|
+
continue;
|
|
973
|
+
}
|
|
974
|
+
disposedPreparedPrograms.add(preparedProgram);
|
|
975
|
+
const reuseState = preparedProgram.preparedHost.reuseState;
|
|
976
|
+
preparedProgram.dispose(false);
|
|
977
|
+
if (!retainedReuseStates.has(reuseState)) {
|
|
978
|
+
clearPreparedCompilerHostReuseState(reuseState);
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
export function analyzeProject(options) {
|
|
984
|
+
const preparedProject = prepareProjectAnalysis(options);
|
|
985
|
+
try {
|
|
986
|
+
return analyzePreparedProject(preparedProject);
|
|
987
|
+
}
|
|
988
|
+
finally {
|
|
989
|
+
disposePreparedAnalysisProject(preparedProject);
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
export function prepareProjectAnalysis(options, reusableProject, prepareOptions = {}) {
|
|
993
|
+
const prepareMetadata = {
|
|
994
|
+
projectPath: options.projectPath,
|
|
995
|
+
};
|
|
996
|
+
return measureCheckerTiming('project.prepareProjectAnalysis', prepareMetadata, () => {
|
|
997
|
+
const loadedConfig = loadConfig(options.projectPath, { target: options.target }, options.additionalRootNames);
|
|
998
|
+
const projectPackageJsonPath = findNearestPackageJsonPath(options.projectPath, ts.sys);
|
|
999
|
+
const configReuseSignature = createProjectConfigReuseSignature(options.projectPath, loadedConfig);
|
|
1000
|
+
const soundscriptRootDiscoverySignature = createSoundscriptRootDiscoverySignature(options.projectPath, loadedConfig);
|
|
1001
|
+
// Same-stem .sts roots are discovered from the current filesystem, so
|
|
1002
|
+
// reusing a previous discovered-root list can keep removed files alive
|
|
1003
|
+
// across prepared-project rebuilds.
|
|
1004
|
+
const configuredSoundscriptRootNames = collectSoundscriptRootNames(options.projectPath, loadedConfig);
|
|
1005
|
+
const allRootNames = combineRootNames(combineRootNames(loadedConfig.commandLine.fileNames, configuredSoundscriptRootNames), options.additionalRootNames);
|
|
1006
|
+
const soundscriptRootNames = allRootNames.filter(isSoundscriptSourceFile);
|
|
1007
|
+
const typescriptRootNames = allRootNames.filter((fileName) => !isSoundscriptSourceFile(fileName));
|
|
1008
|
+
const configFileParsingDiagnostics = getConfigFileParsingDiagnostics(loadedConfig.diagnostics, options.additionalRootNames);
|
|
1009
|
+
const soundscriptFileOverridesSignature = createFileOverrideSignature(options.fileOverrides, isSoundscriptSourceFile);
|
|
1010
|
+
const soundscriptRootContentSignature = createSoundscriptRootContentSignature(soundscriptRootNames, loadedConfig.commandLine.options, options.fileOverrides);
|
|
1011
|
+
const canReuseConfigArtifacts = reusableProject !== undefined &&
|
|
1012
|
+
reusableProject.analyzeOptions.projectPath === options.projectPath &&
|
|
1013
|
+
reusableProject.configReuseSignature === configReuseSignature;
|
|
1014
|
+
const canReuseStsArtifacts = canReuseConfigArtifacts &&
|
|
1015
|
+
rootNamesEqual(reusableProject.soundscriptRootNames, soundscriptRootNames) &&
|
|
1016
|
+
reusableProject.soundscriptRootContentSignature === soundscriptRootContentSignature &&
|
|
1017
|
+
reusableProject.soundscriptFileOverridesSignature === soundscriptFileOverridesSignature;
|
|
1018
|
+
const soundscriptRootNameSet = new Set(soundscriptRootNames.map((rootName) => ts.sys.resolvePath(rootName)));
|
|
1019
|
+
const stsView = canReuseStsArtifacts ? reusableProject.stsView : (() => {
|
|
1020
|
+
const metadata = {
|
|
1021
|
+
rootCount: soundscriptRootNames.length,
|
|
1022
|
+
};
|
|
1023
|
+
return measureCheckerTiming('project.prepare.stsView', metadata, () => {
|
|
1024
|
+
const preparedView = prepareAnalysisView(options, loadedConfig, soundscriptRootNames, createSoundStdlibCompilerHost(loadedConfig.commandLine.options, dirname(options.projectPath)), [], (sourceFile, preparedProgram) => shouldAnalyzeProjectSoundscriptSourceFile(sourceFile, preparedProgram, projectPackageJsonPath), undefined, true, 'full', canReuseConfigArtifacts ? reusableProject?.stsCompilerHostReuseState : undefined, canReuseConfigArtifacts ? reusableProject?.stsView?.program : undefined);
|
|
1025
|
+
if (preparedView) {
|
|
1026
|
+
applyMacroCacheStatsToMetadata(metadata, preparedView.macroCacheStats);
|
|
1027
|
+
}
|
|
1028
|
+
return preparedView;
|
|
1029
|
+
}, { always: true });
|
|
1030
|
+
})();
|
|
1031
|
+
const shouldDeferTypescriptView = prepareOptions.deferTypescriptView === true;
|
|
1032
|
+
if (shouldDeferTypescriptView) {
|
|
1033
|
+
const canReuseLocalProjectedDeclarationOverrides = canReuseStsArtifacts &&
|
|
1034
|
+
reusableProject?.localProjectedDeclarationOverrides !== undefined;
|
|
1035
|
+
const localProjectedDeclarationOverrides = !canReuseLocalProjectedDeclarationOverrides
|
|
1036
|
+
? undefined
|
|
1037
|
+
: reusableProject.localProjectedDeclarationOverrides;
|
|
1038
|
+
const preparedProject = {
|
|
1039
|
+
analyzeOptions: { ...options },
|
|
1040
|
+
configReuseSignature,
|
|
1041
|
+
configuredSoundscriptRootNames,
|
|
1042
|
+
localProjectedDeclarationOverrides,
|
|
1043
|
+
packageSourcePolicyContentSignature: '',
|
|
1044
|
+
packageSourcePolicyCompilerHostReuseState: canReuseConfigArtifacts
|
|
1045
|
+
? reusableProject?.packageSourcePolicyCompilerHostReuseState
|
|
1046
|
+
: undefined,
|
|
1047
|
+
packageSourcePolicyView: null,
|
|
1048
|
+
soundscriptRootContentSignature,
|
|
1049
|
+
soundscriptRootDiscoverySignature,
|
|
1050
|
+
stsCompilerHostReuseState: stsView?.preparedProgram.preparedHost.reuseState,
|
|
1051
|
+
soundscriptFileOverridesSignature,
|
|
1052
|
+
soundscriptRootNames,
|
|
1053
|
+
stsView,
|
|
1054
|
+
tsCompilerHostReuseState: canReuseConfigArtifacts
|
|
1055
|
+
? reusableProject?.tsCompilerHostReuseState
|
|
1056
|
+
: undefined,
|
|
1057
|
+
tsView: null,
|
|
1058
|
+
};
|
|
1059
|
+
applyMacroCacheStatsToMetadata(prepareMetadata, aggregateMacroCacheStats(preparedProject));
|
|
1060
|
+
return preparedProject;
|
|
1061
|
+
}
|
|
1062
|
+
const needsSupplementalProjectionViews = typescriptRootNames.length > 0 ||
|
|
1063
|
+
(stsView !== null &&
|
|
1064
|
+
hasNonRootProjectedDeclarationCandidates(stsView.program, soundscriptRootNameSet, projectPackageJsonPath));
|
|
1065
|
+
if (!needsSupplementalProjectionViews) {
|
|
1066
|
+
const preparedProject = {
|
|
1067
|
+
analyzeOptions: { ...options },
|
|
1068
|
+
configReuseSignature,
|
|
1069
|
+
configuredSoundscriptRootNames,
|
|
1070
|
+
localProjectedDeclarationOverrides: undefined,
|
|
1071
|
+
packageSourcePolicyContentSignature: '',
|
|
1072
|
+
packageSourcePolicyCompilerHostReuseState: canReuseConfigArtifacts
|
|
1073
|
+
? reusableProject?.packageSourcePolicyCompilerHostReuseState
|
|
1074
|
+
: undefined,
|
|
1075
|
+
packageSourcePolicyView: null,
|
|
1076
|
+
soundscriptRootContentSignature,
|
|
1077
|
+
soundscriptRootDiscoverySignature,
|
|
1078
|
+
stsCompilerHostReuseState: stsView?.preparedProgram.preparedHost.reuseState,
|
|
1079
|
+
soundscriptFileOverridesSignature,
|
|
1080
|
+
soundscriptRootNames,
|
|
1081
|
+
stsView,
|
|
1082
|
+
tsCompilerHostReuseState: canReuseConfigArtifacts
|
|
1083
|
+
? reusableProject?.tsCompilerHostReuseState
|
|
1084
|
+
: undefined,
|
|
1085
|
+
tsView: null,
|
|
1086
|
+
};
|
|
1087
|
+
applyMacroCacheStatsToMetadata(prepareMetadata, aggregateMacroCacheStats(preparedProject));
|
|
1088
|
+
return preparedProject;
|
|
1089
|
+
}
|
|
1090
|
+
const canReuseLocalProjectedDeclarationOverrides = canReuseStsArtifacts &&
|
|
1091
|
+
reusableProject?.localProjectedDeclarationOverrides !== undefined;
|
|
1092
|
+
const localProjectedDeclarationOverrides = canReuseLocalProjectedDeclarationOverrides
|
|
1093
|
+
? reusableProject.localProjectedDeclarationOverrides
|
|
1094
|
+
: measureCheckerTiming('project.prepare.localProjection', {
|
|
1095
|
+
hasStsView: stsView !== null,
|
|
1096
|
+
rootCount: soundscriptRootNames.length,
|
|
1097
|
+
}, () => filterProjectedDeclarationOverridesToRootNames(emitProjectedDeclarationsFailClosed(stsView, soundscriptRootNames), soundscriptRootNames), { always: true });
|
|
1098
|
+
const preliminaryTsView = (() => {
|
|
1099
|
+
const metadata = {
|
|
1100
|
+
rootCount: typescriptRootNames.length,
|
|
1101
|
+
localProjectionCount: localProjectedDeclarationOverrides?.size ?? 0,
|
|
1102
|
+
};
|
|
1103
|
+
return measureCheckerTiming('project.prepare.preliminaryTsView', metadata, () => {
|
|
1104
|
+
const preparedView = prepareAnalysisView(options, loadedConfig, typescriptRootNames, ts.createCompilerHost(loadedConfig.commandLine.options), configFileParsingDiagnostics, (sourceFile) => shouldAnalyzeTypescriptViewSourceFile(sourceFile), localProjectedDeclarationOverrides, false, 'full', canReuseConfigArtifacts ? reusableProject?.tsCompilerHostReuseState : undefined, canReuseConfigArtifacts ? reusableProject?.tsView?.program : undefined);
|
|
1105
|
+
if (preparedView) {
|
|
1106
|
+
applyMacroCacheStatsToMetadata(metadata, preparedView.macroCacheStats);
|
|
1107
|
+
}
|
|
1108
|
+
return preparedView;
|
|
1109
|
+
}, { always: true });
|
|
1110
|
+
})();
|
|
1111
|
+
const packageProjectedDeclarationRootNames = collectProjectedDeclarationCandidateRootNamesFromPrograms([preliminaryTsView?.program, stsView?.program], localProjectedDeclarationOverrides, projectPackageJsonPath);
|
|
1112
|
+
const packageSourcePolicyContentSignature = packageProjectedDeclarationRootNames.length === 0
|
|
1113
|
+
? ''
|
|
1114
|
+
: createSoundscriptRootContentSignature(packageProjectedDeclarationRootNames, loadedConfig.commandLine.options, options.fileOverrides);
|
|
1115
|
+
const packageProjectedDeclarationOverrides = measureCheckerTiming('project.prepare.packageProjection', {
|
|
1116
|
+
candidateCount: packageProjectedDeclarationRootNames.length,
|
|
1117
|
+
}, () => {
|
|
1118
|
+
if (packageProjectedDeclarationRootNames.length === 0 || !preliminaryTsView) {
|
|
1119
|
+
return undefined;
|
|
1120
|
+
}
|
|
1121
|
+
const expandedProgram = createBuiltinExpandedProgram({
|
|
1122
|
+
baseHost: createSoundStdlibCompilerHost(loadedConfig.commandLine.options, dirname(options.projectPath)),
|
|
1123
|
+
configFileParsingDiagnostics: [],
|
|
1124
|
+
fileOverrides: options.fileOverrides ?? new Map(),
|
|
1125
|
+
options: loadedConfig.commandLine.options,
|
|
1126
|
+
projectReferences: loadedConfig.commandLine.projectReferences,
|
|
1127
|
+
projectedDeclarationOverrides: localProjectedDeclarationOverrides,
|
|
1128
|
+
runtime: loadedConfig.runtime,
|
|
1129
|
+
rootNames: packageProjectedDeclarationRootNames,
|
|
1130
|
+
});
|
|
1131
|
+
try {
|
|
1132
|
+
return emitProjectedDeclarations(expandedProgram.analysisPreparedProgram, packageProjectedDeclarationRootNames);
|
|
1133
|
+
}
|
|
1134
|
+
finally {
|
|
1135
|
+
expandedProgram.dispose();
|
|
1136
|
+
}
|
|
1137
|
+
}, { always: true });
|
|
1138
|
+
const projectedDeclarationOverrides = mergeProjectedDeclarationOverrides(localProjectedDeclarationOverrides, packageProjectedDeclarationOverrides);
|
|
1139
|
+
const canReusePackageSourcePolicyView = canReuseConfigArtifacts &&
|
|
1140
|
+
rootNamesEqual(reusableProject.packageSourcePolicyView?.program.getRootFileNames().map(toSourceFileName) ?? [], packageProjectedDeclarationRootNames) &&
|
|
1141
|
+
reusableProject.packageSourcePolicyContentSignature ===
|
|
1142
|
+
packageSourcePolicyContentSignature &&
|
|
1143
|
+
!projectedDeclarationOverridesDiffer(reusableProject.localProjectedDeclarationOverrides, localProjectedDeclarationOverrides);
|
|
1144
|
+
const shouldRebuildTsView = projectedDeclarationOverridesDiffer(localProjectedDeclarationOverrides, projectedDeclarationOverrides);
|
|
1145
|
+
const preparedProject = {
|
|
1146
|
+
analyzeOptions: { ...options },
|
|
1147
|
+
configReuseSignature,
|
|
1148
|
+
configuredSoundscriptRootNames,
|
|
1149
|
+
localProjectedDeclarationOverrides,
|
|
1150
|
+
packageSourcePolicyContentSignature,
|
|
1151
|
+
packageSourcePolicyCompilerHostReuseState: canReusePackageSourcePolicyView
|
|
1152
|
+
? reusableProject?.packageSourcePolicyCompilerHostReuseState
|
|
1153
|
+
: undefined,
|
|
1154
|
+
packageSourcePolicyView: canReusePackageSourcePolicyView
|
|
1155
|
+
? reusableProject?.packageSourcePolicyView ?? null
|
|
1156
|
+
: measureCheckerTiming('project.prepare.packageSourcePolicyView', {
|
|
1157
|
+
rootCount: packageProjectedDeclarationRootNames.length,
|
|
1158
|
+
}, () => prepareAnalysisView(options, loadedConfig, packageProjectedDeclarationRootNames, createSoundStdlibCompilerHost(loadedConfig.commandLine.options, dirname(options.projectPath)), [], shouldAnalyzeSoundscriptSourceFile, localProjectedDeclarationOverrides, true, 'sourceSupplemental', canReusePackageSourcePolicyView
|
|
1159
|
+
? reusableProject?.packageSourcePolicyCompilerHostReuseState
|
|
1160
|
+
: undefined, canReusePackageSourcePolicyView
|
|
1161
|
+
? reusableProject?.packageSourcePolicyView?.program
|
|
1162
|
+
: undefined), { always: true }),
|
|
1163
|
+
soundscriptRootContentSignature,
|
|
1164
|
+
soundscriptRootDiscoverySignature,
|
|
1165
|
+
stsCompilerHostReuseState: stsView?.preparedProgram.preparedHost.reuseState,
|
|
1166
|
+
soundscriptFileOverridesSignature,
|
|
1167
|
+
soundscriptRootNames,
|
|
1168
|
+
stsView,
|
|
1169
|
+
tsCompilerHostReuseState: preliminaryTsView?.preparedProgram.preparedHost.reuseState,
|
|
1170
|
+
tsView: shouldRebuildTsView
|
|
1171
|
+
? (() => {
|
|
1172
|
+
const metadata = {
|
|
1173
|
+
rootCount: typescriptRootNames.length,
|
|
1174
|
+
projectionCount: projectedDeclarationOverrides?.size ?? 0,
|
|
1175
|
+
};
|
|
1176
|
+
return measureCheckerTiming('project.prepare.finalTsView', metadata, () => {
|
|
1177
|
+
const preparedView = prepareAnalysisView(options, loadedConfig, typescriptRootNames, ts.createCompilerHost(loadedConfig.commandLine.options), configFileParsingDiagnostics, (sourceFile) => shouldAnalyzeTypescriptViewSourceFile(sourceFile), projectedDeclarationOverrides, false, 'full', preliminaryTsView?.preparedProgram.preparedHost.reuseState ??
|
|
1178
|
+
reusableProject?.tsCompilerHostReuseState, preliminaryTsView?.program);
|
|
1179
|
+
if (preparedView) {
|
|
1180
|
+
applyMacroCacheStatsToMetadata(metadata, preparedView.macroCacheStats);
|
|
1181
|
+
}
|
|
1182
|
+
return preparedView;
|
|
1183
|
+
}, { always: true });
|
|
1184
|
+
})()
|
|
1185
|
+
: preliminaryTsView,
|
|
1186
|
+
};
|
|
1187
|
+
applyMacroCacheStatsToMetadata(prepareMetadata, aggregateMacroCacheStats(preparedProject));
|
|
1188
|
+
return preparedProject;
|
|
1189
|
+
}, { always: true });
|
|
1190
|
+
}
|
|
1191
|
+
export function getPreparedAnalysisViewForFile(preparedProject, filePath) {
|
|
1192
|
+
if (isSoundscriptSourceFile(filePath)) {
|
|
1193
|
+
const packageSourceView = preparedProject.packageSourcePolicyView;
|
|
1194
|
+
if (packageSourceView &&
|
|
1195
|
+
isNodeModulesPath(filePath) &&
|
|
1196
|
+
getPreparedViewSourceFileMatch(packageSourceView, filePath)) {
|
|
1197
|
+
return packageSourceView;
|
|
1198
|
+
}
|
|
1199
|
+
const stsView = preparedProject.stsView;
|
|
1200
|
+
if (stsView && getPreparedViewSourceFileMatch(stsView, filePath)) {
|
|
1201
|
+
return stsView;
|
|
1202
|
+
}
|
|
1203
|
+
if (packageSourceView && getPreparedViewSourceFileMatch(packageSourceView, filePath)) {
|
|
1204
|
+
return packageSourceView;
|
|
1205
|
+
}
|
|
1206
|
+
return stsView;
|
|
1207
|
+
}
|
|
1208
|
+
return preparedProject.tsView;
|
|
1209
|
+
}
|
|
1210
|
+
function getPreparedAnalysisSupplementalViewsForFile(preparedProject, filePath, primaryView) {
|
|
1211
|
+
const supplementalViews = [];
|
|
1212
|
+
const addView = (view) => {
|
|
1213
|
+
if (!view || view === primaryView || supplementalViews.includes(view)) {
|
|
1214
|
+
return;
|
|
1215
|
+
}
|
|
1216
|
+
supplementalViews.push(view);
|
|
1217
|
+
};
|
|
1218
|
+
if (isSoundscriptSourceFile(filePath)) {
|
|
1219
|
+
addView(preparedProject.packageSourcePolicyView);
|
|
1220
|
+
return supplementalViews;
|
|
1221
|
+
}
|
|
1222
|
+
addView(preparedProject.stsView);
|
|
1223
|
+
addView(preparedProject.packageSourcePolicyView);
|
|
1224
|
+
return supplementalViews;
|
|
1225
|
+
}
|
|
1226
|
+
export function analyzePreparedProjectForFile(preparedProject, filePath) {
|
|
1227
|
+
return measureCheckerTiming('project.analyzePreparedProjectForFile', {
|
|
1228
|
+
filePath,
|
|
1229
|
+
hasTsView: preparedProject.tsView !== null,
|
|
1230
|
+
hasStsView: preparedProject.stsView !== null,
|
|
1231
|
+
}, () => {
|
|
1232
|
+
const primaryView = getPreparedAnalysisViewForFile(preparedProject, filePath);
|
|
1233
|
+
const primaryAnalysis = analyzePreparedViewForFile(primaryView, filePath);
|
|
1234
|
+
const diagnosticPaths = primaryView
|
|
1235
|
+
? collectPreparedViewFrontendDiagnosticPaths(primaryView, filePath)
|
|
1236
|
+
: [filePath];
|
|
1237
|
+
const primaryDependencyAnalysis = analyzePreparedViewForDiagnosticPaths(primaryView, diagnosticPaths);
|
|
1238
|
+
const supplementalAnalyses = getPreparedAnalysisSupplementalViewsForFile(preparedProject, filePath, primaryView).map((view) => analyzePreparedViewForDiagnosticPaths(view, diagnosticPaths));
|
|
1239
|
+
const diagnostics = dedupeMergedDiagnostics([
|
|
1240
|
+
...primaryAnalysis.frontendDiagnostics,
|
|
1241
|
+
...primaryAnalysis.tsDiagnostics,
|
|
1242
|
+
...primaryAnalysis.soundDiagnostics,
|
|
1243
|
+
...primaryDependencyAnalysis.frontendDiagnostics,
|
|
1244
|
+
...primaryDependencyAnalysis.tsDiagnostics,
|
|
1245
|
+
...primaryDependencyAnalysis.soundDiagnostics,
|
|
1246
|
+
...supplementalAnalyses.flatMap((analyzedProgram) => [
|
|
1247
|
+
...analyzedProgram.frontendDiagnostics,
|
|
1248
|
+
...analyzedProgram.tsDiagnostics,
|
|
1249
|
+
...analyzedProgram.soundDiagnostics,
|
|
1250
|
+
]),
|
|
1251
|
+
]);
|
|
1252
|
+
return {
|
|
1253
|
+
diagnostics,
|
|
1254
|
+
summary: createSummary(diagnostics),
|
|
1255
|
+
};
|
|
1256
|
+
}, { always: true });
|
|
1257
|
+
}
|
|
1258
|
+
function collectPreparedAnalysisFilePathCandidates(filePath) {
|
|
1259
|
+
const candidates = new Set();
|
|
1260
|
+
const addCandidate = (candidate) => {
|
|
1261
|
+
if (candidate) {
|
|
1262
|
+
candidates.add(candidate);
|
|
1263
|
+
}
|
|
1264
|
+
};
|
|
1265
|
+
addCandidate(filePath);
|
|
1266
|
+
if (isProjectedSoundscriptDeclarationFile(filePath)) {
|
|
1267
|
+
addCandidate(toProjectedDeclarationSourceFileName(filePath));
|
|
1268
|
+
}
|
|
1269
|
+
addCandidate(ts.sys.resolvePath(filePath));
|
|
1270
|
+
if (isProjectedSoundscriptDeclarationFile(filePath)) {
|
|
1271
|
+
addCandidate(ts.sys.resolvePath(toProjectedDeclarationSourceFileName(filePath)));
|
|
1272
|
+
}
|
|
1273
|
+
try {
|
|
1274
|
+
const realPath = ts.sys.realpath?.(filePath);
|
|
1275
|
+
addCandidate(realPath);
|
|
1276
|
+
if (realPath) {
|
|
1277
|
+
addCandidate(ts.sys.resolvePath(realPath));
|
|
1278
|
+
if (isProjectedSoundscriptDeclarationFile(realPath)) {
|
|
1279
|
+
const sourcePath = toProjectedDeclarationSourceFileName(realPath);
|
|
1280
|
+
addCandidate(sourcePath);
|
|
1281
|
+
addCandidate(ts.sys.resolvePath(sourcePath));
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
catch {
|
|
1286
|
+
// Ignore realpath failures for virtual or missing paths and fall back to the raw path.
|
|
1287
|
+
}
|
|
1288
|
+
return [...candidates];
|
|
1289
|
+
}
|
|
1290
|
+
function matchesPreparedAnalysisFilePath(candidateFilePath, expectedFilePath) {
|
|
1291
|
+
if (!candidateFilePath) {
|
|
1292
|
+
return false;
|
|
1293
|
+
}
|
|
1294
|
+
if (candidateFilePath === expectedFilePath) {
|
|
1295
|
+
return true;
|
|
1296
|
+
}
|
|
1297
|
+
const expectedCandidates = new Set(collectPreparedAnalysisFilePathCandidates(expectedFilePath));
|
|
1298
|
+
if (expectedCandidates.has(candidateFilePath)) {
|
|
1299
|
+
return true;
|
|
1300
|
+
}
|
|
1301
|
+
return collectPreparedAnalysisFilePathCandidates(candidateFilePath).some((candidate) => expectedCandidates.has(candidate));
|
|
1302
|
+
}
|
|
1303
|
+
export function filterAnalyzedDiagnosticsForFile(diagnostics, filePath) {
|
|
1304
|
+
return diagnostics.filter((diagnostic) => matchesPreparedAnalysisFilePath(diagnostic.filePath, filePath));
|
|
1305
|
+
}
|
|
1306
|
+
function getPreparedViewSourceFileMatch(preparedView, filePath) {
|
|
1307
|
+
for (const candidateFilePath of collectPreparedAnalysisFilePathCandidates(filePath)) {
|
|
1308
|
+
const programFileName = preparedView.preparedProgram.toProgramFileName(candidateFilePath);
|
|
1309
|
+
const sourceFile = preparedView.program.getSourceFile(programFileName);
|
|
1310
|
+
if (sourceFile) {
|
|
1311
|
+
return {
|
|
1312
|
+
matchedFilePath: candidateFilePath,
|
|
1313
|
+
sourceFile,
|
|
1314
|
+
};
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1317
|
+
return null;
|
|
1318
|
+
}
|
|
1319
|
+
export function analyzePreparedProject(preparedProject) {
|
|
1320
|
+
return measureCheckerTiming('project.analyzePreparedProject', {
|
|
1321
|
+
hasTsView: preparedProject.tsView !== null,
|
|
1322
|
+
hasStsView: preparedProject.stsView !== null,
|
|
1323
|
+
}, () => {
|
|
1324
|
+
const analyzedPrograms = [
|
|
1325
|
+
analyzePreparedView(preparedProject.tsView),
|
|
1326
|
+
analyzePreparedView(preparedProject.stsView),
|
|
1327
|
+
analyzePreparedView(preparedProject.packageSourcePolicyView),
|
|
1328
|
+
];
|
|
1329
|
+
const diagnostics = dedupeMergedDiagnostics(analyzedPrograms.flatMap((programResult) => [
|
|
1330
|
+
...programResult.frontendDiagnostics,
|
|
1331
|
+
...programResult.tsDiagnostics,
|
|
1332
|
+
...programResult.soundDiagnostics,
|
|
1333
|
+
]));
|
|
1334
|
+
return {
|
|
1335
|
+
diagnostics,
|
|
1336
|
+
summary: createSummary(diagnostics),
|
|
1337
|
+
};
|
|
1338
|
+
}, { always: true });
|
|
1339
|
+
}
|
|
1340
|
+
function dedupeMergedDiagnostics(diagnostics) {
|
|
1341
|
+
const deduped = [];
|
|
1342
|
+
const seen = new Set();
|
|
1343
|
+
for (const diagnostic of diagnostics) {
|
|
1344
|
+
const key = [
|
|
1345
|
+
diagnostic.source,
|
|
1346
|
+
diagnostic.code,
|
|
1347
|
+
diagnostic.filePath ?? '',
|
|
1348
|
+
diagnostic.line ?? 0,
|
|
1349
|
+
diagnostic.column ?? 0,
|
|
1350
|
+
diagnostic.endLine ?? 0,
|
|
1351
|
+
diagnostic.endColumn ?? 0,
|
|
1352
|
+
diagnostic.message,
|
|
1353
|
+
].join('\u0000');
|
|
1354
|
+
if (seen.has(key)) {
|
|
1355
|
+
continue;
|
|
1356
|
+
}
|
|
1357
|
+
seen.add(key);
|
|
1358
|
+
deduped.push(diagnostic);
|
|
1359
|
+
}
|
|
1360
|
+
return deduped;
|
|
1361
|
+
}
|