ttsc 0.33.0 → 0.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/cmd/ttsc/api_compile.go +3 -2
- package/cmd/ttsc/api_transform.go +1 -1
- package/cmd/ttsc/build.go +5 -4
- package/cmd/ttsc-cache/account.go +16 -0
- package/cmd/ttsc-cache/account_test.go +91 -0
- package/cmd/ttsc-cache/main.go +1 -1
- package/cmd/ttsc-cache/protocol_test.go +2 -2
- package/cmd/ttsc-cache/publisher_seal_test.go +1 -1
- package/cmd/ttsc-cache/stock_go_failure_test.go +1 -1
- package/cmd/ttsc-cache/stock_go_test.go +2 -2
- package/cmd/ttsc-cache/store.go +5 -0
- package/cmd/ttsc-cache/tuple.go +6 -2
- package/cmd/ttsc-cache/tuple_test.go +1 -1
- package/cmd/ttscgraph/main.go +6 -1
- package/cmd/ttscgraph/run_help_version_and_bad_flags_exit_codes_test.go +6 -1
- package/cmd/ttscgraph/serve.go +22 -20
- package/cmd/ttscgraph/serve_alternative_members_and_reads_refresh_test.go +95 -0
- package/cmd/ttscgraph/serve_shards.go +26 -15
- package/cmd/ttscgraph/serve_shards_abandoned_generation_converges_on_retry_test.go +2 -2
- package/cmd/ttscgraph/serve_shards_delete_removed_source_test.go +3 -3
- package/cmd/ttscgraph/serve_shards_prune_unreferenced_external_endpoints_test.go +1 -1
- package/cmd/ttscgraph/serve_shards_publish_created_source_test.go +3 -3
- package/cmd/ttscgraph/serve_shards_refresh_cross_file_implementation_test.go +2 -2
- package/cmd/ttscgraph/serve_shards_refresh_dependent_diagnostics_test.go +3 -3
- package/cmd/ttscgraph/serve_shards_rename_moves_source_identity_test.go +5 -5
- package/cmd/ttscgraph/serve_shards_reuse_unaffected_sources_test.go +8 -8
- package/cmd/ttscgraph/serve_source_encoding_test.go +2 -2
- package/driver/build_information_uses_selected_output_identity_test.go +5 -4
- package/driver/check_observations.go +1 -1
- package/driver/config_discovery.go +5 -1
- package/driver/declaration_shape.go +15 -21
- package/driver/diagnostics_preamble.go +2 -2
- package/driver/emit_containment.go +11 -14
- package/driver/emit_plugin.go +51 -43
- package/driver/emit_plugin_output.go +6 -5
- package/driver/emit_provenance.go +12 -15
- package/driver/graph.go +8 -8
- package/driver/host.go +15 -5
- package/driver/input_observation.go +22 -21
- package/driver/input_observation_test.go +11 -10
- package/driver/overlay.go +11 -11
- package/driver/program.go +102 -51
- package/driver/resolution_candidates.go +50 -32
- package/driver/resolution_candidates_test.go +18 -5
- package/driver/rewrite.go +11 -13
- package/driver/session.go +13 -7
- package/driver/target_ts70.go +85 -0
- package/driver/target_ts71.go +97 -0
- package/driver/transform_dependencies.go +1 -1
- package/driver/transform_source_map.go +21 -20
- package/go.mod +3 -3
- package/go.sum +4 -4
- package/internal/graph/alternative_member_declarations_resolve_uses_test.go +145 -0
- package/internal/graph/assigned_implementations_of_declaration_file_symbols_leave_no_edge_source_test.go +2 -2
- package/internal/graph/assigned_implementations_of_node_modules_symbols_leave_no_edge_source_test.go +2 -2
- package/internal/graph/build.go +75 -33
- package/internal/graph/build_files_reuses_committed_cross_file_endpoints_test.go +4 -4
- package/internal/graph/build_records_a_node_per_top_level_declaration_test.go +1 -1
- package/internal/graph/declaration_members.go +143 -0
- package/internal/graph/decorators_capture_name_and_literal_arguments_test.go +3 -3
- package/internal/graph/doc_tags.go +2 -2
- package/internal/graph/dump_paths.go +6 -5
- package/internal/graph/duplicate_variable_object_members_keep_first_declaration_test.go +1 -1
- package/internal/graph/edges.go +151 -68
- package/internal/graph/edges_cover_class_level_references_test.go +5 -5
- package/internal/graph/enum_initializer_calls_are_edges_test.go +2 -2
- package/internal/graph/enum_members_carry_their_names_on_the_enum_node_test.go +6 -6
- package/internal/graph/exports.go +6 -6
- package/internal/graph/file_diagnostics_match_tsgo_code_and_location_test.go +2 -2
- package/internal/graph/file_diagnostics_report_code_column_and_message_test.go +1 -1
- package/internal/graph/function_locals_do_not_collide_test.go +3 -3
- package/internal/graph/heritage_edges_cover_implements_and_interface_extends_test.go +5 -5
- package/internal/graph/heritage_edges_keep_extends_and_implements_to_same_base_test.go +2 -2
- package/internal/graph/heritage_edges_record_extends_versus_implements_origin_test.go +3 -3
- package/internal/graph/heritage_edges_traverse_barrels_and_stop_at_external_leaves_test.go +3 -3
- package/internal/graph/literals.go +3 -3
- package/internal/graph/literals_are_absent_when_the_type_admits_more_than_it_can_name_test.go +2 -2
- package/internal/graph/literals_cover_enum_members_the_graph_has_no_nodes_for_test.go +4 -4
- package/internal/graph/literals_do_not_depend_on_declaration_line_wrapping_test.go +2 -2
- package/internal/graph/literals_render_every_value_in_typescript_source_form_test.go +1 -1
- package/internal/graph/literals_resolve_through_alias_indirection_test.go +3 -3
- package/internal/graph/member_relation_edges_follow_checker_validity_test.go +7 -7
- package/internal/graph/member_relation_edges_preserve_checker_boundaries_test.go +19 -19
- package/internal/graph/member_relation_edges_reject_checker_invalid_pairs_test.go +11 -11
- package/internal/graph/namespace_dotted_form_qualifies_deeply_test.go +2 -2
- package/internal/graph/namespace_members_become_qualified_nodes_and_edges_test.go +7 -7
- package/internal/graph/namespace_private_declarations_keep_lexical_identity_test.go +85 -0
- package/internal/graph/nodes_are_marked_exported_through_the_export_table_test.go +2 -2
- package/internal/graph/object_literal_declarations_resolve_calls_test.go +9 -9
- package/internal/graph/object_literal_members_ride_on_the_snapshot_test.go +1 -1
- package/internal/graph/overload_implementation_replaces_signature_test.go +2 -2
- package/internal/graph/property_member_edges_remain_owner_visible_test.go +6 -6
- package/internal/graph/resolve.go +37 -12
- package/internal/graph/resolve_unwraps_barrel_reexport_to_real_declaration_test.go +6 -6
- package/internal/graph/source.go +1 -1
- package/internal/graph/type_ref_edges_cover_typeof_as_satisfies_test.go +7 -7
- package/internal/graph/type_ref_edges_resolve_named_types_across_files_test.go +2 -2
- package/internal/graph/value_access_edges_cover_properties_test.go +5 -5
- package/internal/graph/value_call_edges_attribute_function_assignments_to_members_test.go +3 -3
- package/internal/graph/value_call_edges_cover_jsx_components_test.go +2 -2
- package/internal/graph/value_call_edges_cover_methods_and_constructors_test.go +3 -3
- package/internal/graph/value_call_edges_cover_variable_bound_callables_test.go +2 -2
- package/internal/graph/value_call_edges_do_not_double_record_invoked_member_access_test.go +4 -4
- package/internal/graph/value_call_edges_record_construct_versus_call_origin_test.go +3 -3
- package/internal/graph/value_call_edges_resolve_across_files_and_dedupe_test.go +2 -2
- package/internal/graph/value_call_edges_skip_self_and_unresolved_test.go +4 -4
- package/internal/graph/value_reads_cover_expression_positions_test.go +88 -0
- package/lib/compiler/internal/buildNativeCompiler.d.ts +5 -2
- package/lib/compiler/internal/buildNativeCompiler.js +12 -4
- package/lib/compiler/internal/buildNativeCompiler.js.map +1 -1
- package/lib/flags/COMPILER_ENUM_WHITESPACE.js +1 -1
- package/lib/flags/COMPILER_ENUM_WHITESPACE.js.map +1 -1
- package/lib/flags/COMPILER_OPTIONS.js +1079 -149
- package/lib/flags/COMPILER_OPTIONS.js.map +1 -1
- package/lib/flags/COMPILER_OPTION_ASCII_FOLDS.js +1 -1
- package/lib/flags/COMPILER_OPTION_ASCII_FOLDS.js.map +1 -1
- package/lib/flags/COMPILER_OPTION_KINDS.js +1 -1
- package/lib/flags/COMPILER_OPTION_KINDS.js.map +1 -1
- package/lib/flags/CompilerOptionSpec.d.ts +9 -2
- package/lib/internal/pluginSource.d.ts +1 -0
- package/lib/internal/pluginSource.js +1 -0
- package/lib/internal/pluginSource.js.map +1 -1
- package/lib/launcher/internal/TypeScriptSyncApi.d.ts +140 -0
- package/lib/launcher/internal/TypeScriptSyncApi.js +99 -0
- package/lib/launcher/internal/TypeScriptSyncApi.js.map +1 -0
- package/lib/launcher/internal/buildSingleRootInMemory.d.ts +80 -0
- package/lib/launcher/internal/buildSingleRootInMemory.js +253 -0
- package/lib/launcher/internal/buildSingleRootInMemory.js.map +1 -0
- package/lib/launcher/internal/buildSingleRootProject.d.ts +22 -18
- package/lib/launcher/internal/buildSingleRootProject.js +27 -18
- package/lib/launcher/internal/buildSingleRootProject.js.map +1 -1
- package/lib/launcher/internal/compilerArgsAsConfigOptions.d.ts +39 -0
- package/lib/launcher/internal/compilerArgsAsConfigOptions.js +115 -0
- package/lib/launcher/internal/compilerArgsAsConfigOptions.js.map +1 -0
- package/lib/plugin/CapabilityPluginResolver.js +3 -0
- package/lib/plugin/CapabilityPluginResolver.js.map +1 -1
- package/lib/plugin/internal/load/loadProjectPlugins.js +6 -2
- package/lib/plugin/internal/load/loadProjectPlugins.js.map +1 -1
- package/lib/plugin/internal/source/CompilerTarget.d.ts +127 -0
- package/lib/plugin/internal/source/CompilerTarget.js +231 -0
- package/lib/plugin/internal/source/CompilerTarget.js.map +1 -0
- package/lib/plugin/internal/source/NativeSourcePackages.js +6 -5
- package/lib/plugin/internal/source/NativeSourcePackages.js.map +1 -1
- package/lib/plugin/internal/source/SourcePluginAdmission.d.ts +18 -1
- package/lib/plugin/internal/source/SourcePluginAdmission.js +24 -2
- package/lib/plugin/internal/source/SourcePluginAdmission.js.map +1 -1
- package/lib/plugin/internal/source/SourcePluginWorkspace.d.ts +6 -3
- package/lib/plugin/internal/source/SourcePluginWorkspace.js +31 -13
- package/lib/plugin/internal/source/SourcePluginWorkspace.js.map +1 -1
- package/lib/plugin/internal/source/buildSourcePlugin.js +3 -1
- package/lib/plugin/internal/source/buildSourcePlugin.js.map +1 -1
- package/lib/plugin/internal/source/hashPluginBuildEnvironment.d.ts +1 -1
- package/lib/plugin/internal/source/hashPluginBuildEnvironment.js +9 -1
- package/lib/plugin/internal/source/hashPluginBuildEnvironment.js.map +1 -1
- package/package.json +14 -9
- package/shim/ast/enums_gen.go +1 -0
- package/shim/ast/go.mod +2 -2
- package/shim/ast/go.sum +4 -4
- package/shim/ast/neutral.go +141 -0
- package/shim/astnav/go.mod +2 -2
- package/shim/astnav/go.sum +4 -4
- package/shim/bundled/go.mod +2 -2
- package/shim/bundled/go.sum +4 -4
- package/shim/checker/go.mod +2 -2
- package/shim/checker/go.sum +4 -4
- package/shim/compiler/go.mod +2 -2
- package/shim/compiler/go.sum +4 -4
- package/shim/compiler/neutral.go +213 -0
- package/shim/core/go.mod +2 -2
- package/shim/core/go.sum +4 -4
- package/shim/diagnosticwriter/go.mod +2 -2
- package/shim/diagnosticwriter/go.sum +4 -4
- package/shim/lsp/go.mod +2 -2
- package/shim/lsp/go.sum +4 -4
- package/shim/parser/go.mod +2 -2
- package/shim/parser/go.sum +4 -4
- package/shim/printer/go.mod +2 -2
- package/shim/printer/go.sum +4 -4
- package/shim/scanner/go.mod +2 -2
- package/shim/scanner/go.sum +4 -4
- package/shim/stringutil/go.mod +1 -1
- package/shim/stringutil/go.sum +2 -2
- package/shim/stringutil/shim.go +15 -0
- package/shim/transformers/go.mod +2 -2
- package/shim/transformers/go.sum +4 -4
- package/shim/tsoptions/go.mod +2 -2
- package/shim/tsoptions/go.sum +4 -4
- package/shim/tsoptions/neutral.go +56 -0
- package/shim/tspath/go.mod +1 -1
- package/shim/tspath/go.sum +2 -2
- package/shim/tspath/neutral.go +150 -0
- package/shim/tspath/typed_paths.go +266 -0
- package/shim/vfs/cachedvfs/go.mod +2 -2
- package/shim/vfs/cachedvfs/go.sum +4 -4
- package/shim/vfs/go.mod +2 -2
- package/shim/vfs/go.sum +4 -4
- package/shim/vfs/neutral.go +20 -0
- package/shim/vfs/osvfs/go.mod +2 -2
- package/shim/vfs/osvfs/go.sum +4 -4
- package/src/compiler/internal/buildNativeCompiler.ts +13 -4
- package/src/flags/COMPILER_ENUM_WHITESPACE.ts +1 -1
- package/src/flags/COMPILER_OPTIONS.ts +1080 -150
- package/src/flags/COMPILER_OPTION_ASCII_FOLDS.ts +1 -1
- package/src/flags/COMPILER_OPTION_KINDS.ts +1 -1
- package/src/flags/CompilerOptionSpec.ts +11 -2
- package/src/internal/pluginSource.ts +1 -0
- package/src/launcher/internal/TypeScriptSyncApi.ts +186 -0
- package/src/launcher/internal/buildSingleRootInMemory.ts +319 -0
- package/src/launcher/internal/buildSingleRootProject.ts +26 -18
- package/src/launcher/internal/compilerArgsAsConfigOptions.ts +112 -0
- package/src/plugin/CapabilityPluginResolver.ts +4 -1
- package/src/plugin/internal/load/loadProjectPlugins.ts +12 -2
- package/src/plugin/internal/source/CompilerTarget.ts +249 -0
- package/src/plugin/internal/source/NativeSourcePackages.ts +10 -4
- package/src/plugin/internal/source/SourcePluginAdmission.ts +28 -2
- package/src/plugin/internal/source/SourcePluginWorkspace.ts +45 -19
- package/src/plugin/internal/source/buildSourcePlugin.ts +3 -1
- package/src/plugin/internal/source/hashPluginBuildEnvironment.ts +9 -1
- package/targets/7.1/bridge/ast/enums_gen.go +174 -0
- package/targets/7.1/bridge/ast/extra-shim.json +4 -0
- package/targets/7.1/bridge/ast/go.mod +14 -0
- package/targets/7.1/bridge/ast/go.sum +20 -0
- package/targets/7.1/bridge/ast/lint.go +1412 -0
- package/targets/7.1/bridge/ast/neutral.go +141 -0
- package/targets/7.1/bridge/ast/parent.go +60 -0
- package/targets/7.1/bridge/ast/safe_text.go +108 -0
- package/targets/7.1/bridge/ast/shim.go +1656 -0
- package/targets/7.1/bridge/ast/surface.go +686 -0
- package/targets/7.1/bridge/ast/test/next_jsdoc_comment_location_reaches_variable_statement_test.go +51 -0
- package/targets/7.1/bridge/ast/test/node_text_joins_multi_hop_qualified_name_test.go +47 -0
- package/targets/7.1/bridge/ast/test/node_text_joins_one_hop_qualified_name_test.go +35 -0
- package/targets/7.1/bridge/ast/test/node_text_returns_empty_for_nil_test.go +31 -0
- package/targets/7.1/bridge/ast/test/node_text_returns_identifier_text_test.go +34 -0
- package/targets/7.1/bridge/ast/test/node_text_skips_empty_qualified_left_test.go +60 -0
- package/targets/7.1/bridge/astnav/go.mod +14 -0
- package/targets/7.1/bridge/astnav/go.sum +22 -0
- package/targets/7.1/bridge/astnav/shim.go +24 -0
- package/targets/7.1/bridge/bundled/extra-shim.json +1 -0
- package/targets/7.1/bridge/bundled/go.mod +10 -0
- package/targets/7.1/bridge/bundled/go.sum +10 -0
- package/targets/7.1/bridge/bundled/shim.go +24 -0
- package/targets/7.1/bridge/checker/enums_gen.go +150 -0
- package/targets/7.1/bridge/checker/extra-shim.json +37 -0
- package/targets/7.1/bridge/checker/go.mod +15 -0
- package/targets/7.1/bridge/checker/go.sum +24 -0
- package/targets/7.1/bridge/checker/node_builder_fields_gen.go +19 -0
- package/targets/7.1/bridge/checker/shim.go +1390 -0
- package/targets/7.1/bridge/compiler/contentmapper_process.go +70 -0
- package/targets/7.1/bridge/compiler/emit_sourcemap.go +296 -0
- package/targets/7.1/bridge/compiler/emitassemble.go +81 -0
- package/targets/7.1/bridge/compiler/emithook.go +44 -0
- package/targets/7.1/bridge/compiler/extra-shim.json +4 -0
- package/targets/7.1/bridge/compiler/go.mod +15 -0
- package/targets/7.1/bridge/compiler/go.sum +24 -0
- package/targets/7.1/bridge/compiler/incremental.go +185 -0
- package/targets/7.1/bridge/compiler/neutral.go +256 -0
- package/targets/7.1/bridge/compiler/resolution.go +571 -0
- package/targets/7.1/bridge/compiler/shim.go +70 -0
- package/targets/7.1/bridge/core/enums_gen.go +15 -0
- package/targets/7.1/bridge/core/extra-shim.json +4 -0
- package/targets/7.1/bridge/core/go.mod +7 -0
- package/targets/7.1/bridge/core/go.sum +8 -0
- package/targets/7.1/bridge/core/modulekind.go +19 -0
- package/targets/7.1/bridge/core/shim.go +272 -0
- package/targets/7.1/bridge/diagnosticwriter/go.mod +14 -0
- package/targets/7.1/bridge/diagnosticwriter/go.sum +20 -0
- package/targets/7.1/bridge/diagnosticwriter/lint.go +411 -0
- package/targets/7.1/bridge/diagnosticwriter/shim.go +56 -0
- package/targets/7.1/bridge/lsp/extra-shim.json +4 -0
- package/targets/7.1/bridge/lsp/go.mod +16 -0
- package/targets/7.1/bridge/lsp/go.sum +26 -0
- package/targets/7.1/bridge/lsp/shim.go +112 -0
- package/targets/7.1/bridge/parser/extra-shim.json +4 -0
- package/targets/7.1/bridge/parser/go.mod +14 -0
- package/targets/7.1/bridge/parser/go.sum +24 -0
- package/targets/7.1/bridge/parser/shim.go +61 -0
- package/targets/7.1/bridge/printer/emithost.go +69 -0
- package/targets/7.1/bridge/printer/go.mod +15 -0
- package/targets/7.1/bridge/printer/go.sum +24 -0
- package/targets/7.1/bridge/printer/shim.go +168 -0
- package/targets/7.1/bridge/printer/sourcemap.go +49 -0
- package/targets/7.1/bridge/scanner/extra-shim.json +4 -0
- package/targets/7.1/bridge/scanner/go.mod +14 -0
- package/targets/7.1/bridge/scanner/go.sum +20 -0
- package/targets/7.1/bridge/scanner/regexp.go +42 -0
- package/targets/7.1/bridge/scanner/shim.go +137 -0
- package/targets/7.1/bridge/stringutil/extra-shim.json +1 -0
- package/targets/7.1/bridge/stringutil/go.mod +5 -0
- package/targets/7.1/bridge/stringutil/go.sum +2 -0
- package/targets/7.1/bridge/stringutil/shim.go +131 -0
- package/targets/7.1/bridge/transformers/go.mod +15 -0
- package/targets/7.1/bridge/transformers/go.sum +24 -0
- package/targets/7.1/bridge/transformers/shim.go +24 -0
- package/targets/7.1/bridge/tsoptions/command_line_raw.go +44 -0
- package/targets/7.1/bridge/tsoptions/extra-shim.json +4 -0
- package/targets/7.1/bridge/tsoptions/go.mod +15 -0
- package/targets/7.1/bridge/tsoptions/go.sum +24 -0
- package/targets/7.1/bridge/tsoptions/neutral.go +47 -0
- package/targets/7.1/bridge/tsoptions/shim.go +193 -0
- package/targets/7.1/bridge/tspath/extra-shim.json +4 -0
- package/targets/7.1/bridge/tspath/go.mod +5 -0
- package/targets/7.1/bridge/tspath/go.sum +6 -0
- package/targets/7.1/bridge/tspath/neutral.go +142 -0
- package/targets/7.1/bridge/tspath/shim.go +382 -0
- package/targets/7.1/bridge/vfs/cachedvfs/extra-shim.json +4 -0
- package/targets/7.1/bridge/vfs/cachedvfs/go.mod +5 -0
- package/targets/7.1/bridge/vfs/cachedvfs/go.sum +10 -0
- package/targets/7.1/bridge/vfs/cachedvfs/shim.go +12 -0
- package/targets/7.1/bridge/vfs/decode.go +26 -0
- package/targets/7.1/bridge/vfs/decode_test.go +42 -0
- package/targets/7.1/bridge/vfs/extra-shim.json +4 -0
- package/targets/7.1/bridge/vfs/go.mod +10 -0
- package/targets/7.1/bridge/vfs/go.sum +10 -0
- package/targets/7.1/bridge/vfs/neutral.go +23 -0
- package/targets/7.1/bridge/vfs/osvfs/extra-shim.json +4 -0
- package/targets/7.1/bridge/vfs/osvfs/go.mod +10 -0
- package/targets/7.1/bridge/vfs/osvfs/go.sum +10 -0
- package/targets/7.1/bridge/vfs/osvfs/shim.go +14 -0
- package/targets/7.1/bridge/vfs/shim.go +27 -0
- package/targets/7.1/facade/ast/facade_gen.go +2691 -0
- package/targets/7.1/facade/ast/go.mod +20 -0
- package/targets/7.1/facade/ast/go.sum +20 -0
- package/targets/7.1/facade/astnav/facade_gen.go +15 -0
- package/targets/7.1/facade/astnav/go.mod +22 -0
- package/targets/7.1/facade/astnav/go.sum +22 -0
- package/targets/7.1/facade/bundled/facade_gen.go +32 -0
- package/targets/7.1/facade/bundled/go.mod +21 -0
- package/targets/7.1/facade/bundled/go.sum +10 -0
- package/targets/7.1/facade/checker/facade_gen.go +563 -0
- package/targets/7.1/facade/checker/go.mod +26 -0
- package/targets/7.1/facade/checker/go.sum +24 -0
- package/targets/7.1/facade/compiler/facade_gen.go +198 -0
- package/targets/7.1/facade/compiler/go.mod +41 -0
- package/targets/7.1/facade/compiler/go.sum +24 -0
- package/targets/7.1/facade/core/facade_gen.go +130 -0
- package/targets/7.1/facade/core/go.mod +12 -0
- package/targets/7.1/facade/core/go.sum +8 -0
- package/targets/7.1/facade/diagnosticwriter/facade_gen.go +36 -0
- package/targets/7.1/facade/diagnosticwriter/go.mod +22 -0
- package/targets/7.1/facade/diagnosticwriter/go.sum +20 -0
- package/targets/7.1/facade/lsp/facade_gen.go +31 -0
- package/targets/7.1/facade/lsp/go.mod +19 -0
- package/targets/7.1/facade/lsp/go.sum +26 -0
- package/targets/7.1/facade/parser/facade_gen.go +102 -0
- package/targets/7.1/facade/parser/go.mod +25 -0
- package/targets/7.1/facade/parser/go.sum +24 -0
- package/targets/7.1/facade/printer/facade_gen.go +74 -0
- package/targets/7.1/facade/printer/go.mod +26 -0
- package/targets/7.1/facade/printer/go.sum +24 -0
- package/targets/7.1/facade/scanner/facade_gen.go +191 -0
- package/targets/7.1/facade/scanner/go.mod +25 -0
- package/targets/7.1/facade/scanner/go.sum +20 -0
- package/targets/7.1/facade/stringutil/facade_gen.go +176 -0
- package/targets/7.1/facade/stringutil/go.mod +9 -0
- package/targets/7.1/facade/stringutil/go.sum +2 -0
- package/targets/7.1/facade/transformers/facade_gen.go +12 -0
- package/targets/7.1/facade/transformers/go.mod +18 -0
- package/targets/7.1/facade/transformers/go.sum +24 -0
- package/targets/7.1/facade/tsoptions/facade_gen.go +274 -0
- package/targets/7.1/facade/tsoptions/go.mod +32 -0
- package/targets/7.1/facade/tsoptions/go.sum +24 -0
- package/targets/7.1/facade/tspath/facade_gen.go +550 -0
- package/targets/7.1/facade/tspath/go.mod +9 -0
- package/targets/7.1/facade/tspath/go.sum +6 -0
- package/targets/7.1/facade/vfs/cachedvfs/facade_gen.go +17 -0
- package/targets/7.1/facade/vfs/cachedvfs/go.mod +18 -0
- package/targets/7.1/facade/vfs/cachedvfs/go.sum +10 -0
- package/targets/7.1/facade/vfs/facade_gen.go +47 -0
- package/targets/7.1/facade/vfs/go.mod +18 -0
- package/targets/7.1/facade/vfs/go.sum +10 -0
- package/targets/7.1/facade/vfs/osvfs/facade_gen.go +20 -0
- package/targets/7.1/facade/vfs/osvfs/go.mod +21 -0
- package/targets/7.1/facade/vfs/osvfs/go.sum +10 -0
- package/tools/gen_facade/committed_facades_match_their_bridges_test.go +57 -0
- package/tools/gen_facade/facade_manifest_points_into_the_bridge_root_test.go +75 -0
- package/tools/gen_facade/facade_spells_internal_types_through_bridge_aliases_test.go +75 -0
- package/tools/gen_facade/facade_types_are_their_bridge_types_test.go +99 -0
- package/tools/gen_facade/go.mod +10 -0
- package/tools/gen_facade/go.sum +8 -0
- package/tools/gen_facade/main.go +734 -0
- package/tools/gen_shims/go.mod +4 -4
- package/tools/gen_shims/go.sum +6 -6
- package/tools/gen_shims/main.go +124 -66
- package/tools/gen_shims/mirror_structs_terminate_on_unexported_cycles_test.go +101 -0
- package/tools/shim_audit/baseline-7.1.json +720 -0
- package/tools/shim_audit/baseline.json +5 -4
- package/tools/shim_audit/go.mod +4 -4
- package/tools/shim_audit/go.sum +6 -6
- package/tools/shim_audit/linkname_signatures.go +178 -0
- package/tools/shim_audit/linkname_signatures_match_their_targets_test.go +64 -0
- package/tools/shim_audit/linkname_targets_follow_the_audited_compiler_test.go +38 -0
- package/tools/shim_audit/main.go +29 -4
- package/tools/shim_audit/neutral_api.go +160 -0
- package/tools/shim_audit/neutral_api_must_match_across_targets_test.go +74 -0
- package/utility/host.go +5 -4
- package/utility/preamble_output.go +15 -15
- package/utility/serve.go +1 -1
|
@@ -0,0 +1,734 @@
|
|
|
1
|
+
// Package main generates the documented github.com/microsoft/typescript-go/shim/*
|
|
2
|
+
// plugin import paths as facades over a compiler target's bridges.
|
|
3
|
+
//
|
|
4
|
+
// From TypeScript 7.1 the compiler module is github.com/microsoft/TypeScript/tsc.
|
|
5
|
+
// Go admits an import of its internal/ tree only from an import path rooted at
|
|
6
|
+
// that module, so the target's maintained bridges are the modules
|
|
7
|
+
// github.com/microsoft/TypeScript/tsc/shim/<name>. Plugins keep importing
|
|
8
|
+
// github.com/microsoft/typescript-go/shim/<name>: each facade module aliases
|
|
9
|
+
// every exported identity of its bridge, so both paths name one compiler's
|
|
10
|
+
// types, functions and values.
|
|
11
|
+
//
|
|
12
|
+
// Usage, from packages/ttsc after the bridges compile:
|
|
13
|
+
//
|
|
14
|
+
// go -C tools/gen_facade run . # write every facade_gen.go
|
|
15
|
+
// go -C tools/gen_facade run . -check # fail when a committed facade is stale
|
|
16
|
+
//
|
|
17
|
+
// -bridge and -facade name the target's bridge and facade roots; the defaults
|
|
18
|
+
// are the TypeScript 7.1 target.
|
|
19
|
+
//
|
|
20
|
+
// Adapted from Danny Wilson's TypeScript 7.1 port (#1727).
|
|
21
|
+
package main
|
|
22
|
+
|
|
23
|
+
import (
|
|
24
|
+
"bytes"
|
|
25
|
+
"errors"
|
|
26
|
+
"flag"
|
|
27
|
+
"fmt"
|
|
28
|
+
"go/format"
|
|
29
|
+
"go/types"
|
|
30
|
+
"io/fs"
|
|
31
|
+
"log"
|
|
32
|
+
"maps"
|
|
33
|
+
"os"
|
|
34
|
+
"path/filepath"
|
|
35
|
+
"slices"
|
|
36
|
+
"strings"
|
|
37
|
+
|
|
38
|
+
"golang.org/x/mod/modfile"
|
|
39
|
+
"golang.org/x/tools/go/packages"
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
const (
|
|
43
|
+
bridgePrefix = "github.com/microsoft/TypeScript/tsc/shim/"
|
|
44
|
+
facadePrefix = "github.com/microsoft/typescript-go/shim/"
|
|
45
|
+
internalPrefix = "github.com/microsoft/TypeScript/tsc/internal/"
|
|
46
|
+
outputName = "facade_gen.go"
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
func main() {
|
|
50
|
+
bridgeRoot := flag.String("bridge", "../../targets/7.1/bridge", "bridge root of the compiler target")
|
|
51
|
+
facadeRoot := flag.String("facade", "../../targets/7.1/facade", "facade root of the compiler target")
|
|
52
|
+
check := flag.Bool("check", false, "report stale facades without writing them")
|
|
53
|
+
flag.Parse()
|
|
54
|
+
|
|
55
|
+
outputs, err := generate(*bridgeRoot, *facadeRoot)
|
|
56
|
+
if err != nil {
|
|
57
|
+
log.Fatalf("gen_facade: %v", err)
|
|
58
|
+
}
|
|
59
|
+
var stale []string
|
|
60
|
+
for _, output := range outputs {
|
|
61
|
+
if *check {
|
|
62
|
+
current, err := os.ReadFile(output.path)
|
|
63
|
+
if err != nil || !bytes.Equal(current, output.source) {
|
|
64
|
+
stale = append(stale, output.path)
|
|
65
|
+
}
|
|
66
|
+
continue
|
|
67
|
+
}
|
|
68
|
+
if err := os.MkdirAll(filepath.Dir(output.path), 0o755); err != nil {
|
|
69
|
+
log.Fatalf("gen_facade: %v", err)
|
|
70
|
+
}
|
|
71
|
+
if err := os.WriteFile(output.path, output.source, 0o644); err != nil {
|
|
72
|
+
log.Fatalf("gen_facade: %v", err)
|
|
73
|
+
}
|
|
74
|
+
fmt.Printf("gen_facade: wrote %s\n", output.path)
|
|
75
|
+
}
|
|
76
|
+
if len(stale) > 0 {
|
|
77
|
+
log.Fatalf("gen_facade: stale facades (run go -C tools/gen_facade run .):\n %s", strings.Join(stale, "\n "))
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// facadeOutput is one generated facade file and its destination.
|
|
82
|
+
type facadeOutput struct {
|
|
83
|
+
path string
|
|
84
|
+
source []byte
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// bridge is one loaded bridge package. rel is its path below the shim root
|
|
88
|
+
// and below both module namespaces, such as "vfs/cachedvfs".
|
|
89
|
+
type bridge struct {
|
|
90
|
+
rel string
|
|
91
|
+
pkg *types.Package
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// generate loads every bridge below bridgeRoot and renders its facade below
|
|
95
|
+
// facadeRoot. Nothing is written here, so a failed bridge leaves every committed
|
|
96
|
+
// facade untouched.
|
|
97
|
+
func generate(bridgeRoot string, facadeRoot string) ([]facadeOutput, error) {
|
|
98
|
+
rels, err := discoverBridges(bridgeRoot)
|
|
99
|
+
if err != nil {
|
|
100
|
+
return nil, err
|
|
101
|
+
}
|
|
102
|
+
bridges := make([]bridge, 0, len(rels))
|
|
103
|
+
for _, rel := range rels {
|
|
104
|
+
pkg, err := loadBridge(filepath.Join(bridgeRoot, filepath.FromSlash(rel)), bridgePrefix+rel)
|
|
105
|
+
if err != nil {
|
|
106
|
+
return nil, err
|
|
107
|
+
}
|
|
108
|
+
bridges = append(bridges, bridge{rel: rel, pkg: pkg})
|
|
109
|
+
}
|
|
110
|
+
index := newAliasIndex(bridges)
|
|
111
|
+
outputs := make([]facadeOutput, 0, len(bridges))
|
|
112
|
+
var problems []error
|
|
113
|
+
for _, b := range bridges {
|
|
114
|
+
source, imported, err := renderFacade(b, index)
|
|
115
|
+
if err != nil {
|
|
116
|
+
problems = append(problems, err)
|
|
117
|
+
continue
|
|
118
|
+
}
|
|
119
|
+
dir := filepath.Join(facadeRoot, filepath.FromSlash(b.rel))
|
|
120
|
+
manifest, err := facadeManifest(filepath.Join(dir, "go.mod"), b.rel, bridgeRoot, imported)
|
|
121
|
+
if err != nil {
|
|
122
|
+
problems = append(problems, err)
|
|
123
|
+
continue
|
|
124
|
+
}
|
|
125
|
+
outputs = append(outputs,
|
|
126
|
+
facadeOutput{path: filepath.Join(dir, outputName), source: source},
|
|
127
|
+
facadeOutput{path: filepath.Join(dir, "go.mod"), source: manifest},
|
|
128
|
+
)
|
|
129
|
+
}
|
|
130
|
+
return outputs, errors.Join(problems...)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// discoverBridges returns the slash-separated directory of every go.mod below
|
|
134
|
+
// bridgeRoot, after checking that each declares the bridge module its
|
|
135
|
+
// directory names.
|
|
136
|
+
func discoverBridges(bridgeRoot string) ([]string, error) {
|
|
137
|
+
var rels []string
|
|
138
|
+
err := filepath.WalkDir(bridgeRoot, func(path string, entry fs.DirEntry, err error) error {
|
|
139
|
+
if err != nil {
|
|
140
|
+
return err
|
|
141
|
+
}
|
|
142
|
+
if entry.IsDir() {
|
|
143
|
+
return nil
|
|
144
|
+
}
|
|
145
|
+
if entry.Name() != "go.mod" {
|
|
146
|
+
return nil
|
|
147
|
+
}
|
|
148
|
+
data, err := os.ReadFile(path)
|
|
149
|
+
if err != nil {
|
|
150
|
+
return err
|
|
151
|
+
}
|
|
152
|
+
dir, err := filepath.Rel(bridgeRoot, filepath.Dir(path))
|
|
153
|
+
if err != nil {
|
|
154
|
+
return err
|
|
155
|
+
}
|
|
156
|
+
rel := filepath.ToSlash(dir)
|
|
157
|
+
if module := modfile.ModulePath(data); module != bridgePrefix+rel {
|
|
158
|
+
return fmt.Errorf("%s declares module %q; the bridge in %s must declare %q", path, module, rel, bridgePrefix+rel)
|
|
159
|
+
}
|
|
160
|
+
rels = append(rels, rel)
|
|
161
|
+
return nil
|
|
162
|
+
})
|
|
163
|
+
if err != nil {
|
|
164
|
+
return nil, err
|
|
165
|
+
}
|
|
166
|
+
if len(rels) == 0 {
|
|
167
|
+
return nil, fmt.Errorf("no bridge go.mod below %s", bridgeRoot)
|
|
168
|
+
}
|
|
169
|
+
slices.Sort(rels)
|
|
170
|
+
return rels, nil
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// loadBridge type-checks the bridge package rooted at dir. Tests and nested
|
|
174
|
+
// packages are not part of a bridge's public surface.
|
|
175
|
+
func loadBridge(dir string, importPath string) (*types.Package, error) {
|
|
176
|
+
loaded, err := packages.Load(&packages.Config{
|
|
177
|
+
Dir: dir,
|
|
178
|
+
Env: standaloneModuleEnv(),
|
|
179
|
+
Mode: packages.NeedName | packages.NeedTypes,
|
|
180
|
+
}, ".")
|
|
181
|
+
if err != nil {
|
|
182
|
+
return nil, fmt.Errorf("load %s: %w", importPath, err)
|
|
183
|
+
}
|
|
184
|
+
if len(loaded) != 1 {
|
|
185
|
+
return nil, fmt.Errorf("load %s: %d packages, want 1", importPath, len(loaded))
|
|
186
|
+
}
|
|
187
|
+
pkg := loaded[0]
|
|
188
|
+
if len(pkg.Errors) > 0 {
|
|
189
|
+
messages := make([]string, len(pkg.Errors))
|
|
190
|
+
for i, e := range pkg.Errors {
|
|
191
|
+
messages[i] = e.Error()
|
|
192
|
+
}
|
|
193
|
+
return nil, fmt.Errorf("load %s:\n %s", importPath, strings.Join(messages, "\n "))
|
|
194
|
+
}
|
|
195
|
+
if pkg.PkgPath != importPath || pkg.Types == nil {
|
|
196
|
+
return nil, fmt.Errorf("load %s: loaded %q", importPath, pkg.PkgPath)
|
|
197
|
+
}
|
|
198
|
+
return pkg.Types, nil
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// aliasRef names an exported bridge alias of a compiler-internal type.
|
|
202
|
+
type aliasRef struct {
|
|
203
|
+
bridgePath string
|
|
204
|
+
name string
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// aliasIndex maps "<internal package path>.<type name>" to the bridge alias a
|
|
208
|
+
// facade spells that type with. A facade cannot import the internal package,
|
|
209
|
+
// so a bridge alias is the only legal spelling of an internal type.
|
|
210
|
+
type aliasIndex map[string]aliasRef
|
|
211
|
+
|
|
212
|
+
// newAliasIndex records every exported bridge alias of an internal named type
|
|
213
|
+
// or alias. One internal type exposed by several bridges is spelled through
|
|
214
|
+
// the bridge of the same name, then by the alias carrying the type's own name,
|
|
215
|
+
// then by the first in import-path order, so output is deterministic.
|
|
216
|
+
func newAliasIndex(bridges []bridge) aliasIndex {
|
|
217
|
+
rank := func(key string, ref aliasRef) []string {
|
|
218
|
+
pkgPath, name, _ := strings.Cut(key[len(internalPrefix):], ".")
|
|
219
|
+
sameBridge, sameName := "1", "1"
|
|
220
|
+
if ref.bridgePath == bridgePrefix+pkgPath {
|
|
221
|
+
sameBridge = "0"
|
|
222
|
+
}
|
|
223
|
+
if ref.name == name {
|
|
224
|
+
sameName = "0"
|
|
225
|
+
}
|
|
226
|
+
return []string{sameBridge + sameName, ref.bridgePath, ref.name}
|
|
227
|
+
}
|
|
228
|
+
index := aliasIndex{}
|
|
229
|
+
add := func(key string, ref aliasRef) {
|
|
230
|
+
if current, ok := index[key]; ok && slices.Compare(rank(key, current), rank(key, ref)) <= 0 {
|
|
231
|
+
return
|
|
232
|
+
}
|
|
233
|
+
index[key] = ref
|
|
234
|
+
}
|
|
235
|
+
for _, b := range bridges {
|
|
236
|
+
scope := b.pkg.Scope()
|
|
237
|
+
for _, name := range scope.Names() {
|
|
238
|
+
obj, ok := scope.Lookup(name).(*types.TypeName)
|
|
239
|
+
if !ok || !obj.Exported() || !obj.IsAlias() {
|
|
240
|
+
continue
|
|
241
|
+
}
|
|
242
|
+
alias, ok := obj.Type().(*types.Alias)
|
|
243
|
+
if !ok {
|
|
244
|
+
continue
|
|
245
|
+
}
|
|
246
|
+
ref := aliasRef{bridgePath: b.pkg.Path(), name: name}
|
|
247
|
+
// A chain of internal aliases is spelled by the same bridge alias.
|
|
248
|
+
for {
|
|
249
|
+
rhs := alias.Rhs()
|
|
250
|
+
next, isAlias := rhs.(*types.Alias)
|
|
251
|
+
if isAlias {
|
|
252
|
+
if key, ok := internalKey(next.Obj()); ok && sameTypeParams(alias.TypeParams(), next.TypeArgs()) {
|
|
253
|
+
add(key, ref)
|
|
254
|
+
}
|
|
255
|
+
alias = next
|
|
256
|
+
continue
|
|
257
|
+
}
|
|
258
|
+
if named, isNamed := rhs.(*types.Named); isNamed {
|
|
259
|
+
if key, ok := internalKey(named.Obj()); ok && sameTypeParams(alias.TypeParams(), named.TypeArgs()) {
|
|
260
|
+
add(key, ref)
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
break
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
return index
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// internalKey returns the index key of a package-level internal type name.
|
|
271
|
+
func internalKey(obj *types.TypeName) (string, bool) {
|
|
272
|
+
if obj.Pkg() == nil || !strings.HasPrefix(obj.Pkg().Path(), internalPrefix) || obj.Parent() != obj.Pkg().Scope() {
|
|
273
|
+
return "", false
|
|
274
|
+
}
|
|
275
|
+
return obj.Pkg().Path() + "." + obj.Name(), true
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// sameTypeParams reports whether args instantiate a generic type with exactly
|
|
279
|
+
// params, in order, so the alias stands for the whole generic type.
|
|
280
|
+
func sameTypeParams(params *types.TypeParamList, args *types.TypeList) bool {
|
|
281
|
+
if params.Len() != args.Len() {
|
|
282
|
+
return false
|
|
283
|
+
}
|
|
284
|
+
for i := range params.Len() {
|
|
285
|
+
if arg, ok := args.At(i).(*types.TypeParam); !ok || arg.Obj() != params.At(i).Obj() {
|
|
286
|
+
return false
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return true
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// importSet assigns each imported package one local name in a facade file.
|
|
293
|
+
type importSet struct {
|
|
294
|
+
names map[string]string // path -> local name
|
|
295
|
+
taken map[string]string // local name -> path
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
func newImportSet() *importSet {
|
|
299
|
+
return &importSet{names: map[string]string{}, taken: map[string]string{}}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// clone copies s, so a declaration that fails to print can be discarded
|
|
303
|
+
// without leaving its imports behind.
|
|
304
|
+
func (s *importSet) clone() *importSet {
|
|
305
|
+
return &importSet{names: maps.Clone(s.names), taken: maps.Clone(s.taken)}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// local returns the local name of path, whose declared package name is name.
|
|
309
|
+
// Bridges are imported as tsc<name> so a facade never shadows its own package.
|
|
310
|
+
func (s *importSet) local(path string, name string) string {
|
|
311
|
+
if local, ok := s.names[path]; ok {
|
|
312
|
+
return local
|
|
313
|
+
}
|
|
314
|
+
base := name
|
|
315
|
+
if strings.HasPrefix(path, bridgePrefix) {
|
|
316
|
+
base = "tsc" + name
|
|
317
|
+
}
|
|
318
|
+
local := base
|
|
319
|
+
for i := 2; s.taken[local] != ""; i++ {
|
|
320
|
+
local = fmt.Sprintf("%s%d", base, i)
|
|
321
|
+
}
|
|
322
|
+
s.names[path] = local
|
|
323
|
+
s.taken[local] = path
|
|
324
|
+
return local
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// printer spells types in a facade file. It refuses a type the facade cannot
|
|
328
|
+
// name: an internal type no bridge aliases, or an unexported or local type.
|
|
329
|
+
type printer struct {
|
|
330
|
+
imports *importSet
|
|
331
|
+
index aliasIndex
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// errUnnameable reports a type a facade cannot spell.
|
|
335
|
+
type errUnnameable struct{ what string }
|
|
336
|
+
|
|
337
|
+
func (e errUnnameable) Error() string { return "cannot name " + e.what }
|
|
338
|
+
|
|
339
|
+
func (p *printer) qualified(pkg *types.Package, name string) string {
|
|
340
|
+
return p.imports.local(pkg.Path(), pkg.Name()) + "." + name
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
func (p *printer) typeArgs(args *types.TypeList) (string, error) {
|
|
344
|
+
if args.Len() == 0 {
|
|
345
|
+
return "", nil
|
|
346
|
+
}
|
|
347
|
+
parts := make([]string, args.Len())
|
|
348
|
+
for i := range args.Len() {
|
|
349
|
+
part, err := p.typ(args.At(i))
|
|
350
|
+
if err != nil {
|
|
351
|
+
return "", err
|
|
352
|
+
}
|
|
353
|
+
parts[i] = part
|
|
354
|
+
}
|
|
355
|
+
return "[" + strings.Join(parts, ", ") + "]", nil
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
func (p *printer) typeName(obj *types.TypeName, args *types.TypeList) (string, error) {
|
|
359
|
+
if obj.Pkg() == nil {
|
|
360
|
+
return obj.Name(), nil // universe: any, error, comparable
|
|
361
|
+
}
|
|
362
|
+
if !obj.Exported() || obj.Parent() != obj.Pkg().Scope() {
|
|
363
|
+
return "", errUnnameable{obj.Pkg().Path() + "." + obj.Name()}
|
|
364
|
+
}
|
|
365
|
+
base := ""
|
|
366
|
+
if key, internal := internalKey(obj); internal {
|
|
367
|
+
ref, ok := p.index[key]
|
|
368
|
+
if !ok {
|
|
369
|
+
return "", errUnnameable{key}
|
|
370
|
+
}
|
|
371
|
+
base = p.imports.local(ref.bridgePath, bridgeName(ref.bridgePath)) + "." + ref.name
|
|
372
|
+
} else if strings.HasPrefix(obj.Pkg().Path(), internalPrefix) {
|
|
373
|
+
return "", errUnnameable{obj.Pkg().Path() + "." + obj.Name()}
|
|
374
|
+
} else {
|
|
375
|
+
base = p.qualified(obj.Pkg(), obj.Name())
|
|
376
|
+
}
|
|
377
|
+
suffix, err := p.typeArgs(args)
|
|
378
|
+
return base + suffix, err
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// bridgeName is the declared package name of a bridge: its last path element.
|
|
382
|
+
func bridgeName(path string) string {
|
|
383
|
+
return path[strings.LastIndexByte(path, '/')+1:]
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
func (p *printer) typ(t types.Type) (string, error) {
|
|
387
|
+
switch t := t.(type) {
|
|
388
|
+
case *types.Basic:
|
|
389
|
+
if t.Kind() == types.UnsafePointer {
|
|
390
|
+
return p.imports.local("unsafe", "unsafe") + ".Pointer", nil
|
|
391
|
+
}
|
|
392
|
+
return t.Name(), nil
|
|
393
|
+
case *types.Alias:
|
|
394
|
+
obj := t.Obj()
|
|
395
|
+
if obj.Pkg() != nil && strings.HasPrefix(obj.Pkg().Path(), internalPrefix) {
|
|
396
|
+
// An internal alias is spelled by its bridge alias when one exists,
|
|
397
|
+
// otherwise by what it denotes.
|
|
398
|
+
if key, ok := internalKey(obj); ok {
|
|
399
|
+
if _, exposed := p.index[key]; exposed {
|
|
400
|
+
return p.typeName(obj, t.TypeArgs())
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
return p.typ(types.Unalias(t))
|
|
404
|
+
}
|
|
405
|
+
return p.typeName(obj, t.TypeArgs())
|
|
406
|
+
case *types.Named:
|
|
407
|
+
return p.typeName(t.Obj(), t.TypeArgs())
|
|
408
|
+
case *types.TypeParam:
|
|
409
|
+
return t.Obj().Name(), nil
|
|
410
|
+
case *types.Pointer:
|
|
411
|
+
elem, err := p.typ(t.Elem())
|
|
412
|
+
return "*" + elem, err
|
|
413
|
+
case *types.Slice:
|
|
414
|
+
elem, err := p.typ(t.Elem())
|
|
415
|
+
return "[]" + elem, err
|
|
416
|
+
case *types.Array:
|
|
417
|
+
elem, err := p.typ(t.Elem())
|
|
418
|
+
return fmt.Sprintf("[%d]%s", t.Len(), elem), err
|
|
419
|
+
case *types.Map:
|
|
420
|
+
key, err := p.typ(t.Key())
|
|
421
|
+
if err != nil {
|
|
422
|
+
return "", err
|
|
423
|
+
}
|
|
424
|
+
elem, err := p.typ(t.Elem())
|
|
425
|
+
return "map[" + key + "]" + elem, err
|
|
426
|
+
case *types.Chan:
|
|
427
|
+
elem, err := p.typ(t.Elem())
|
|
428
|
+
switch t.Dir() {
|
|
429
|
+
case types.SendOnly:
|
|
430
|
+
return "chan<- " + elem, err
|
|
431
|
+
case types.RecvOnly:
|
|
432
|
+
return "<-chan " + elem, err
|
|
433
|
+
}
|
|
434
|
+
return "chan " + elem, err
|
|
435
|
+
case *types.Signature:
|
|
436
|
+
sig, err := p.signature(t, nil)
|
|
437
|
+
return "func" + sig, err
|
|
438
|
+
case *types.Struct:
|
|
439
|
+
fields := make([]string, t.NumFields())
|
|
440
|
+
for i := range t.NumFields() {
|
|
441
|
+
field := t.Field(i)
|
|
442
|
+
typ, err := p.typ(field.Type())
|
|
443
|
+
if err != nil {
|
|
444
|
+
return "", err
|
|
445
|
+
}
|
|
446
|
+
if !field.Embedded() {
|
|
447
|
+
typ = field.Name() + " " + typ
|
|
448
|
+
}
|
|
449
|
+
if tag := t.Tag(i); tag != "" {
|
|
450
|
+
typ += " " + fmt.Sprintf("%q", tag)
|
|
451
|
+
}
|
|
452
|
+
fields[i] = typ
|
|
453
|
+
}
|
|
454
|
+
return "struct{" + strings.Join(fields, "; ") + "}", nil
|
|
455
|
+
case *types.Interface:
|
|
456
|
+
var parts []string
|
|
457
|
+
for i := range t.NumEmbeddeds() {
|
|
458
|
+
part, err := p.typ(t.EmbeddedType(i))
|
|
459
|
+
if err != nil {
|
|
460
|
+
return "", err
|
|
461
|
+
}
|
|
462
|
+
parts = append(parts, part)
|
|
463
|
+
}
|
|
464
|
+
for i := range t.NumExplicitMethods() {
|
|
465
|
+
method := t.ExplicitMethod(i)
|
|
466
|
+
if !method.Exported() {
|
|
467
|
+
return "", errUnnameable{"unexported interface method " + method.Name()}
|
|
468
|
+
}
|
|
469
|
+
sig, err := p.signature(method.Signature(), nil)
|
|
470
|
+
if err != nil {
|
|
471
|
+
return "", err
|
|
472
|
+
}
|
|
473
|
+
parts = append(parts, method.Name()+sig)
|
|
474
|
+
}
|
|
475
|
+
if t.IsImplicit() && len(parts) == 1 {
|
|
476
|
+
return parts[0], nil
|
|
477
|
+
}
|
|
478
|
+
return "interface{" + strings.Join(parts, "; ") + "}", nil
|
|
479
|
+
case *types.Union:
|
|
480
|
+
terms := make([]string, t.Len())
|
|
481
|
+
for i := range t.Len() {
|
|
482
|
+
term, err := p.typ(t.Term(i).Type())
|
|
483
|
+
if err != nil {
|
|
484
|
+
return "", err
|
|
485
|
+
}
|
|
486
|
+
if t.Term(i).Tilde() {
|
|
487
|
+
term = "~" + term
|
|
488
|
+
}
|
|
489
|
+
terms[i] = term
|
|
490
|
+
}
|
|
491
|
+
return strings.Join(terms, " | "), nil
|
|
492
|
+
}
|
|
493
|
+
return "", errUnnameable{fmt.Sprintf("%T %s", t, t)}
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
// typeParams spells a type parameter list as declared, and as used.
|
|
497
|
+
func (p *printer) typeParams(list *types.TypeParamList) (string, string, error) {
|
|
498
|
+
if list.Len() == 0 {
|
|
499
|
+
return "", "", nil
|
|
500
|
+
}
|
|
501
|
+
decl := make([]string, list.Len())
|
|
502
|
+
use := make([]string, list.Len())
|
|
503
|
+
for i := range list.Len() {
|
|
504
|
+
param := list.At(i)
|
|
505
|
+
constraint, err := p.typ(param.Constraint())
|
|
506
|
+
if err != nil {
|
|
507
|
+
return "", "", err
|
|
508
|
+
}
|
|
509
|
+
decl[i] = param.Obj().Name() + " " + constraint
|
|
510
|
+
use[i] = param.Obj().Name()
|
|
511
|
+
}
|
|
512
|
+
return "[" + strings.Join(decl, ", ") + "]", "[" + strings.Join(use, ", ") + "]", nil
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
// signature spells sig's parameters and results. With names non-nil, the
|
|
516
|
+
// parameters are declared as p0, p1, ... and their names appended to names.
|
|
517
|
+
func (p *printer) signature(sig *types.Signature, names *[]string) (string, error) {
|
|
518
|
+
params := make([]string, sig.Params().Len())
|
|
519
|
+
for i := range sig.Params().Len() {
|
|
520
|
+
typ := sig.Params().At(i).Type()
|
|
521
|
+
spelled := ""
|
|
522
|
+
if sig.Variadic() && i == sig.Params().Len()-1 {
|
|
523
|
+
elem, err := p.typ(typ.(*types.Slice).Elem())
|
|
524
|
+
if err != nil {
|
|
525
|
+
return "", err
|
|
526
|
+
}
|
|
527
|
+
spelled = "..." + elem
|
|
528
|
+
} else {
|
|
529
|
+
var err error
|
|
530
|
+
if spelled, err = p.typ(typ); err != nil {
|
|
531
|
+
return "", err
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
if names != nil {
|
|
535
|
+
name := fmt.Sprintf("p%d", i)
|
|
536
|
+
*names = append(*names, name)
|
|
537
|
+
spelled = name + " " + spelled
|
|
538
|
+
}
|
|
539
|
+
params[i] = spelled
|
|
540
|
+
}
|
|
541
|
+
results := make([]string, sig.Results().Len())
|
|
542
|
+
for i := range sig.Results().Len() {
|
|
543
|
+
spelled, err := p.typ(sig.Results().At(i).Type())
|
|
544
|
+
if err != nil {
|
|
545
|
+
return "", err
|
|
546
|
+
}
|
|
547
|
+
results[i] = spelled
|
|
548
|
+
}
|
|
549
|
+
out := "(" + strings.Join(params, ", ") + ")"
|
|
550
|
+
switch len(results) {
|
|
551
|
+
case 0:
|
|
552
|
+
case 1:
|
|
553
|
+
out += " " + results[0]
|
|
554
|
+
default:
|
|
555
|
+
out += " (" + strings.Join(results, ", ") + ")"
|
|
556
|
+
}
|
|
557
|
+
return out, nil
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
// renderFacade writes the facade of one bridge: an alias of every exported
|
|
561
|
+
// type, a constant or variable of every exported value, and a forwarding
|
|
562
|
+
// function of every exported function. A function whose signature names an
|
|
563
|
+
// internal type no bridge aliases becomes a variable holding the bridge
|
|
564
|
+
// function, which a facade can declare without spelling that type; such a
|
|
565
|
+
// generic function cannot be expressed and fails generation.
|
|
566
|
+
func renderFacade(b bridge, index aliasIndex) ([]byte, []string, error) {
|
|
567
|
+
imports := newImportSet()
|
|
568
|
+
p := &printer{imports: imports, index: index}
|
|
569
|
+
self := imports.local(b.pkg.Path(), b.pkg.Name())
|
|
570
|
+
var body strings.Builder
|
|
571
|
+
var problems []error
|
|
572
|
+
scope := b.pkg.Scope()
|
|
573
|
+
for _, name := range scope.Names() {
|
|
574
|
+
obj := scope.Lookup(name)
|
|
575
|
+
if !obj.Exported() {
|
|
576
|
+
continue
|
|
577
|
+
}
|
|
578
|
+
target := self + "." + name
|
|
579
|
+
switch obj := obj.(type) {
|
|
580
|
+
case *types.TypeName:
|
|
581
|
+
var params *types.TypeParamList
|
|
582
|
+
switch t := obj.Type().(type) {
|
|
583
|
+
case *types.Alias:
|
|
584
|
+
params = t.TypeParams()
|
|
585
|
+
case *types.Named:
|
|
586
|
+
params = t.TypeParams()
|
|
587
|
+
}
|
|
588
|
+
decl, use, err := p.typeParams(params)
|
|
589
|
+
if err != nil {
|
|
590
|
+
problems = append(problems, fmt.Errorf("%s.%s: %w", b.pkg.Path(), name, err))
|
|
591
|
+
continue
|
|
592
|
+
}
|
|
593
|
+
fmt.Fprintf(&body, "type %s%s = %s%s\n\n", name, decl, target, use)
|
|
594
|
+
case *types.Const:
|
|
595
|
+
fmt.Fprintf(&body, "const %s = %s\n\n", name, target)
|
|
596
|
+
case *types.Var:
|
|
597
|
+
fmt.Fprintf(&body, "var %s = %s\n\n", name, target)
|
|
598
|
+
case *types.Func:
|
|
599
|
+
saved := p.imports.clone()
|
|
600
|
+
forward, err := p.forward(name, target, obj.Signature())
|
|
601
|
+
var unnameable errUnnameable
|
|
602
|
+
switch {
|
|
603
|
+
case err == nil:
|
|
604
|
+
body.WriteString(forward)
|
|
605
|
+
case errors.As(err, &unnameable) && obj.Signature().TypeParams().Len() == 0:
|
|
606
|
+
p.imports = saved
|
|
607
|
+
fmt.Fprintf(&body, "// %s holds the bridge function: its signature uses a type no bridge\n// exposes (%s).\nvar %s = %s\n\n", name, unnameable.what, name, target)
|
|
608
|
+
default:
|
|
609
|
+
problems = append(problems, fmt.Errorf("%s.%s: %w", b.pkg.Path(), name, err))
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
if err := errors.Join(problems...); err != nil {
|
|
614
|
+
return nil, nil, err
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
var file strings.Builder
|
|
618
|
+
file.WriteString("// Code generated by packages/ttsc/tools/gen_facade. DO NOT EDIT.\n\n")
|
|
619
|
+
fmt.Fprintf(&file, "// Package %s is the documented %s%s plugin import path.\n", b.pkg.Name(), facadePrefix, b.rel)
|
|
620
|
+
fmt.Fprintf(&file, "// It aliases every exported identity of %s, the\n", b.pkg.Path())
|
|
621
|
+
file.WriteString("// bridge that reaches the compiler's internal packages.\n")
|
|
622
|
+
fmt.Fprintf(&file, "package %s\n\n", b.pkg.Name())
|
|
623
|
+
imports = p.imports
|
|
624
|
+
paths := make([]string, 0, len(imports.names))
|
|
625
|
+
for path := range imports.names {
|
|
626
|
+
paths = append(paths, path)
|
|
627
|
+
}
|
|
628
|
+
slices.Sort(paths)
|
|
629
|
+
file.WriteString("import (\n")
|
|
630
|
+
for _, path := range paths {
|
|
631
|
+
fmt.Fprintf(&file, "\t%s %q\n", imports.names[path], path)
|
|
632
|
+
}
|
|
633
|
+
file.WriteString(")\n\n")
|
|
634
|
+
file.WriteString(body.String())
|
|
635
|
+
|
|
636
|
+
formatted, err := format.Source([]byte(file.String()))
|
|
637
|
+
if err != nil {
|
|
638
|
+
return nil, nil, fmt.Errorf("format facade of %s: %w\n%s", b.pkg.Path(), err, file.String())
|
|
639
|
+
}
|
|
640
|
+
var bridges []string
|
|
641
|
+
for _, path := range paths {
|
|
642
|
+
if strings.HasPrefix(path, bridgePrefix) {
|
|
643
|
+
bridges = append(bridges, path)
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
return spaceIndent(formatted), bridges, nil
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
// facadeManifest returns the facade's go.mod with exactly one requirement and
|
|
650
|
+
// one relative replacement per bridge the facade imports, each replacement
|
|
651
|
+
// pointing from the facade directory into bridgeRoot. Every other line,
|
|
652
|
+
// including the compiler and indirect requirements that go mod tidy records,
|
|
653
|
+
// is preserved; run go mod tidy after a facade gains a bridge so go.sum follows.
|
|
654
|
+
func facadeManifest(path string, rel string, bridgeRoot string, bridges []string) ([]byte, error) {
|
|
655
|
+
data, err := os.ReadFile(path)
|
|
656
|
+
if err != nil {
|
|
657
|
+
return nil, err
|
|
658
|
+
}
|
|
659
|
+
file, err := modfile.Parse(path, data, nil)
|
|
660
|
+
if err != nil {
|
|
661
|
+
return nil, err
|
|
662
|
+
}
|
|
663
|
+
if want := facadePrefix + rel; file.Module == nil || file.Module.Mod.Path != want {
|
|
664
|
+
return nil, fmt.Errorf("%s must declare module %s", path, want)
|
|
665
|
+
}
|
|
666
|
+
needed := map[string]bool{}
|
|
667
|
+
for _, bridge := range bridges {
|
|
668
|
+
needed[bridge] = true
|
|
669
|
+
}
|
|
670
|
+
for _, require := range slices.Clone(file.Require) {
|
|
671
|
+
if strings.HasPrefix(require.Mod.Path, bridgePrefix) && !needed[require.Mod.Path] {
|
|
672
|
+
if err := file.DropRequire(require.Mod.Path); err != nil {
|
|
673
|
+
return nil, err
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
for _, replace := range slices.Clone(file.Replace) {
|
|
678
|
+
if strings.HasPrefix(replace.Old.Path, bridgePrefix) && !needed[replace.Old.Path] {
|
|
679
|
+
if err := file.DropReplace(replace.Old.Path, replace.Old.Version); err != nil {
|
|
680
|
+
return nil, err
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
for _, bridge := range bridges {
|
|
685
|
+
if err := file.AddRequire(bridge, "v0.0.0"); err != nil {
|
|
686
|
+
return nil, err
|
|
687
|
+
}
|
|
688
|
+
target, err := filepath.Rel(filepath.Dir(path), filepath.Join(bridgeRoot, filepath.FromSlash(strings.TrimPrefix(bridge, bridgePrefix))))
|
|
689
|
+
if err != nil {
|
|
690
|
+
return nil, err
|
|
691
|
+
}
|
|
692
|
+
if err := file.AddReplace(bridge, "", filepath.ToSlash(target), ""); err != nil {
|
|
693
|
+
return nil, err
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
file.Cleanup()
|
|
697
|
+
return modfile.Format(file.Syntax), nil
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
// forward spells a function that calls the bridge function target.
|
|
701
|
+
func (p *printer) forward(name string, target string, sig *types.Signature) (string, error) {
|
|
702
|
+
decl, use, err := p.typeParams(sig.TypeParams())
|
|
703
|
+
if err != nil {
|
|
704
|
+
return "", err
|
|
705
|
+
}
|
|
706
|
+
var names []string
|
|
707
|
+
spelled, err := p.signature(sig, &names)
|
|
708
|
+
if err != nil {
|
|
709
|
+
return "", err
|
|
710
|
+
}
|
|
711
|
+
args := strings.Join(names, ", ")
|
|
712
|
+
if sig.Variadic() {
|
|
713
|
+
args += "..."
|
|
714
|
+
}
|
|
715
|
+
call := target + use + "(" + args + ")"
|
|
716
|
+
if sig.Results().Len() > 0 {
|
|
717
|
+
call = "return " + call
|
|
718
|
+
}
|
|
719
|
+
return fmt.Sprintf("func %s%s%s {\n\t%s\n}\n\n", name, decl, spelled, call), nil
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
// spaceIndent applies the repository's Go layout, gofmt with two-space
|
|
723
|
+
// indentation, so committed facades are byte-identical to generator output.
|
|
724
|
+
// Generated facades contain no multi-line literal, so every tab is indentation.
|
|
725
|
+
func spaceIndent(source []byte) []byte {
|
|
726
|
+
return bytes.ReplaceAll(source, []byte("\t"), []byte(" "))
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
// standaloneModuleEnv resolves a bridge by its own go.mod. A target's bridges
|
|
730
|
+
// are standalone modules outside the repository workspace, whose shim modules
|
|
731
|
+
// share the facades' import paths.
|
|
732
|
+
func standaloneModuleEnv() []string {
|
|
733
|
+
return append(os.Environ(), "GOWORK=off")
|
|
734
|
+
}
|