typia 13.1.1 → 13.1.19
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 +3 -0
- package/lib/_virtual/_rolldown/runtime.mjs +1 -5
- package/lib/executable/FileSystemIdentity.d.ts +21 -0
- package/lib/executable/FileSystemIdentity.js +183 -0
- package/lib/executable/FileSystemIdentity.js.map +1 -0
- package/lib/executable/FileSystemIdentity.mjs +129 -0
- package/lib/executable/FileSystemIdentity.mjs.map +1 -0
- package/lib/executable/TypiaGenerateWizard.js +264 -104
- package/lib/executable/TypiaGenerateWizard.js.map +1 -1
- package/lib/executable/TypiaGenerateWizard.mjs +233 -93
- package/lib/executable/TypiaGenerateWizard.mjs.map +1 -1
- package/lib/functional.d.ts +15 -12
- package/lib/functional.js.map +1 -1
- package/lib/functional.mjs.map +1 -1
- package/lib/internal/_ProtobufReader.d.ts +17 -0
- package/lib/internal/_ProtobufReader.js +117 -45
- package/lib/internal/_ProtobufReader.js.map +1 -1
- package/lib/internal/_ProtobufReader.mjs +108 -39
- package/lib/internal/_ProtobufReader.mjs.map +1 -1
- package/lib/internal/_createStandardSchema.js +18 -1
- package/lib/internal/_createStandardSchema.js.map +1 -1
- package/lib/internal/_createStandardSchema.mjs +12 -1
- package/lib/internal/_createStandardSchema.mjs.map +1 -1
- package/lib/internal/_decimal.d.ts +14 -0
- package/lib/internal/_decimal.js +61 -0
- package/lib/internal/_decimal.js.map +1 -0
- package/lib/internal/_decimal.mjs +49 -0
- package/lib/internal/_decimal.mjs.map +1 -0
- package/lib/internal/_httpQueryParseURLSearchParams.js +23 -2
- package/lib/internal/_httpQueryParseURLSearchParams.js.map +1 -1
- package/lib/internal/_httpQueryParseURLSearchParams.mjs +20 -2
- package/lib/internal/_httpQueryParseURLSearchParams.mjs.map +1 -1
- package/lib/internal/_isFormatByte.js +2 -5
- package/lib/internal/_isFormatByte.js.map +1 -1
- package/lib/internal/_isFormatByte.mjs +2 -5
- package/lib/internal/_isFormatByte.mjs.map +1 -1
- package/lib/internal/_isFormatDate.js +15 -2
- package/lib/internal/_isFormatDate.js.map +1 -1
- package/lib/internal/_isFormatDate.mjs +22 -2
- package/lib/internal/_isFormatDate.mjs.map +1 -1
- package/lib/internal/_isFormatDateTime.js +21 -2
- package/lib/internal/_isFormatDateTime.js.map +1 -1
- package/lib/internal/_isFormatDateTime.mjs +13 -2
- package/lib/internal/_isFormatDateTime.mjs.map +1 -1
- package/lib/internal/_isFormatIri.js +3 -2
- package/lib/internal/_isFormatIri.js.map +1 -1
- package/lib/internal/_isFormatIri.mjs +3 -2
- package/lib/internal/_isFormatIri.mjs.map +1 -1
- package/lib/internal/_isFormatIriReference.js +10 -2
- package/lib/internal/_isFormatIriReference.js.map +1 -1
- package/lib/internal/_isFormatIriReference.mjs +9 -2
- package/lib/internal/_isFormatIriReference.mjs.map +1 -1
- package/lib/internal/_isFormatUriReference.js +1 -1
- package/lib/internal/_isFormatUriReference.js.map +1 -1
- package/lib/internal/_isFormatUriReference.mjs +1 -1
- package/lib/internal/_isFormatUriReference.mjs.map +1 -1
- package/lib/internal/_isMultipleOf.d.ts +1 -0
- package/lib/internal/_isMultipleOf.js +13 -0
- package/lib/internal/_isMultipleOf.js.map +1 -0
- package/lib/internal/_isMultipleOf.mjs +12 -0
- package/lib/internal/_isMultipleOf.mjs.map +1 -0
- package/lib/internal/_isTypeFloat.js +1 -1
- package/lib/internal/_isTypeFloat.js.map +1 -1
- package/lib/internal/_isTypeFloat.mjs +1 -1
- package/lib/internal/_isTypeFloat.mjs.map +1 -1
- package/lib/internal/_isTypeInt64.js +1 -0
- package/lib/internal/_isTypeInt64.js.map +1 -1
- package/lib/internal/_isTypeInt64.mjs.map +1 -1
- package/lib/internal/_isTypeInt64Bigint.d.ts +1 -0
- package/lib/internal/_isTypeInt64Bigint.js +15 -0
- package/lib/internal/_isTypeInt64Bigint.js.map +1 -0
- package/lib/internal/_isTypeInt64Bigint.mjs +8 -0
- package/lib/internal/_isTypeInt64Bigint.mjs.map +1 -0
- package/lib/internal/_isTypeUint64.js +1 -0
- package/lib/internal/_isTypeUint64.js.map +1 -1
- package/lib/internal/_isTypeUint64.mjs.map +1 -1
- package/lib/internal/_isTypeUint64Bigint.d.ts +1 -0
- package/lib/internal/_isTypeUint64Bigint.js +10 -0
- package/lib/internal/_isTypeUint64Bigint.js.map +1 -0
- package/lib/internal/_isTypeUint64Bigint.mjs +8 -0
- package/lib/internal/_isTypeUint64Bigint.mjs.map +1 -0
- package/lib/internal/_isUniqueItems.js +96 -109
- package/lib/internal/_isUniqueItems.js.map +1 -1
- package/lib/internal/_isUniqueItems.mjs +62 -50
- package/lib/internal/_isUniqueItems.mjs.map +1 -1
- package/lib/internal/_notationAny.js +8 -1
- package/lib/internal/_notationAny.js.map +1 -1
- package/lib/internal/_notationAny.mjs +7 -1
- package/lib/internal/_notationAny.mjs.map +1 -1
- package/lib/internal/_notationAssign.d.ts +1 -0
- package/lib/internal/_notationAssign.js +18 -0
- package/lib/internal/_notationAssign.js.map +1 -0
- package/lib/internal/_notationAssign.mjs +17 -0
- package/lib/internal/_notationAssign.mjs.map +1 -0
- package/lib/internal/_notationCamel.js +30 -9
- package/lib/internal/_notationCamel.js.map +1 -1
- package/lib/internal/_notationCamel.mjs +13 -5
- package/lib/internal/_notationCamel.mjs.map +1 -1
- package/lib/internal/_notationKebab.d.ts +1 -0
- package/lib/internal/_notationKebab.js +15 -0
- package/lib/internal/_notationKebab.js.map +1 -0
- package/lib/internal/_notationKebab.mjs +15 -0
- package/lib/internal/_notationKebab.mjs.map +1 -0
- package/lib/internal/_notationKeyCollision.d.ts +1 -0
- package/lib/internal/_notationKeyCollision.js +8 -0
- package/lib/internal/_notationKeyCollision.js.map +1 -0
- package/lib/internal/_notationKeyCollision.mjs +8 -0
- package/lib/internal/_notationKeyCollision.mjs.map +1 -0
- package/lib/internal/_notationPascal.js +20 -5
- package/lib/internal/_notationPascal.js.map +1 -1
- package/lib/internal/_notationPascal.mjs +10 -5
- package/lib/internal/_notationPascal.mjs.map +1 -1
- package/lib/internal/_notationSnake.js +25 -22
- package/lib/internal/_notationSnake.js.map +1 -1
- package/lib/internal/_notationSnake.mjs +11 -11
- package/lib/internal/_notationSnake.mjs.map +1 -1
- package/lib/internal/_plainCloneAny.js +174 -38
- package/lib/internal/_plainCloneAny.js.map +1 -1
- package/lib/internal/_plainCloneAny.mjs +126 -22
- package/lib/internal/_plainCloneAny.mjs.map +1 -1
- package/lib/internal/_randomArray.d.ts +1 -1
- package/lib/internal/_randomArray.js +11 -4
- package/lib/internal/_randomArray.js.map +1 -1
- package/lib/internal/_randomArray.mjs +9 -3
- package/lib/internal/_randomArray.mjs.map +1 -1
- package/lib/internal/_randomFormatByte.d.ts +2 -1
- package/lib/internal/_randomFormatByte.js +2 -1
- package/lib/internal/_randomFormatByte.js.map +1 -1
- package/lib/internal/_randomFormatByte.mjs +2 -1
- package/lib/internal/_randomFormatByte.mjs.map +1 -1
- package/lib/internal/_randomFormatDate.d.ts +2 -0
- package/lib/internal/_randomFormatDate.js +3 -2
- package/lib/internal/_randomFormatDate.js.map +1 -1
- package/lib/internal/_randomFormatDate.mjs +3 -2
- package/lib/internal/_randomFormatDate.mjs.map +1 -1
- package/lib/internal/_randomFormatDatetime.d.ts +2 -0
- package/lib/internal/_randomFormatDatetime.js +3 -2
- package/lib/internal/_randomFormatDatetime.js.map +1 -1
- package/lib/internal/_randomFormatDatetime.mjs +3 -2
- package/lib/internal/_randomFormatDatetime.mjs.map +1 -1
- package/lib/internal/_randomFormatDuration.d.ts +2 -1
- package/lib/internal/_randomFormatDuration.js +3 -2
- package/lib/internal/_randomFormatDuration.js.map +1 -1
- package/lib/internal/_randomFormatDuration.mjs +3 -2
- package/lib/internal/_randomFormatDuration.mjs.map +1 -1
- package/lib/internal/_randomFormatEmail.d.ts +2 -1
- package/lib/internal/_randomFormatEmail.js +8 -1
- package/lib/internal/_randomFormatEmail.js.map +1 -1
- package/lib/internal/_randomFormatEmail.mjs +5 -1
- package/lib/internal/_randomFormatEmail.mjs.map +1 -1
- package/lib/internal/_randomFormatHostname.d.ts +8 -1
- package/lib/internal/_randomFormatHostname.js +45 -2
- package/lib/internal/_randomFormatHostname.js.map +1 -1
- package/lib/internal/_randomFormatHostname.mjs +38 -2
- package/lib/internal/_randomFormatHostname.mjs.map +1 -1
- package/lib/internal/_randomFormatIdnEmail.d.ts +2 -1
- package/lib/internal/_randomFormatIdnEmail.js +16 -2
- package/lib/internal/_randomFormatIdnEmail.js.map +1 -1
- package/lib/internal/_randomFormatIdnEmail.mjs +11 -2
- package/lib/internal/_randomFormatIdnEmail.mjs.map +1 -1
- package/lib/internal/_randomFormatIdnHostname.d.ts +2 -1
- package/lib/internal/_randomFormatIdnHostname.js +26 -1
- package/lib/internal/_randomFormatIdnHostname.js.map +1 -1
- package/lib/internal/_randomFormatIdnHostname.mjs +25 -2
- package/lib/internal/_randomFormatIdnHostname.mjs.map +1 -1
- package/lib/internal/_randomFormatIpv4.d.ts +2 -1
- package/lib/internal/_randomFormatIpv4.js +2 -1
- package/lib/internal/_randomFormatIpv4.js.map +1 -1
- package/lib/internal/_randomFormatIpv4.mjs +2 -1
- package/lib/internal/_randomFormatIpv4.mjs.map +1 -1
- package/lib/internal/_randomFormatIpv6.d.ts +2 -1
- package/lib/internal/_randomFormatIpv6.js +2 -1
- package/lib/internal/_randomFormatIpv6.js.map +1 -1
- package/lib/internal/_randomFormatIpv6.mjs +2 -1
- package/lib/internal/_randomFormatIpv6.mjs.map +1 -1
- package/lib/internal/_randomFormatIri.d.ts +2 -1
- package/lib/internal/_randomFormatIri.js +1 -1
- package/lib/internal/_randomFormatIri.js.map +1 -1
- package/lib/internal/_randomFormatIri.mjs +1 -1
- package/lib/internal/_randomFormatIri.mjs.map +1 -1
- package/lib/internal/_randomFormatIriReference.d.ts +2 -1
- package/lib/internal/_randomFormatIriReference.js +1 -1
- package/lib/internal/_randomFormatIriReference.js.map +1 -1
- package/lib/internal/_randomFormatIriReference.mjs +1 -1
- package/lib/internal/_randomFormatIriReference.mjs.map +1 -1
- package/lib/internal/_randomFormatJsonPointer.d.ts +2 -1
- package/lib/internal/_randomFormatJsonPointer.js +8 -1
- package/lib/internal/_randomFormatJsonPointer.js.map +1 -1
- package/lib/internal/_randomFormatJsonPointer.mjs +5 -1
- package/lib/internal/_randomFormatJsonPointer.mjs.map +1 -1
- package/lib/internal/_randomFormatPassword.d.ts +2 -1
- package/lib/internal/_randomFormatPassword.js +7 -5
- package/lib/internal/_randomFormatPassword.js.map +1 -1
- package/lib/internal/_randomFormatPassword.mjs +5 -1
- package/lib/internal/_randomFormatPassword.mjs.map +1 -1
- package/lib/internal/_randomFormatRegex.d.ts +2 -1
- package/lib/internal/_randomFormatRegex.js +2 -1
- package/lib/internal/_randomFormatRegex.js.map +1 -1
- package/lib/internal/_randomFormatRegex.mjs +2 -1
- package/lib/internal/_randomFormatRegex.mjs.map +1 -1
- package/lib/internal/_randomFormatRelativeJsonPointer.d.ts +2 -1
- package/lib/internal/_randomFormatRelativeJsonPointer.js +3 -2
- package/lib/internal/_randomFormatRelativeJsonPointer.js.map +1 -1
- package/lib/internal/_randomFormatRelativeJsonPointer.mjs +3 -2
- package/lib/internal/_randomFormatRelativeJsonPointer.mjs.map +1 -1
- package/lib/internal/_randomFormatTime.d.ts +2 -1
- package/lib/internal/_randomFormatTime.js +3 -2
- package/lib/internal/_randomFormatTime.js.map +1 -1
- package/lib/internal/_randomFormatTime.mjs +3 -2
- package/lib/internal/_randomFormatTime.mjs.map +1 -1
- package/lib/internal/_randomFormatUri.d.ts +2 -1
- package/lib/internal/_randomFormatUri.js +1 -1
- package/lib/internal/_randomFormatUri.js.map +1 -1
- package/lib/internal/_randomFormatUri.mjs +1 -1
- package/lib/internal/_randomFormatUri.mjs.map +1 -1
- package/lib/internal/_randomFormatUriReference.d.ts +2 -1
- package/lib/internal/_randomFormatUriReference.js +1 -1
- package/lib/internal/_randomFormatUriReference.js.map +1 -1
- package/lib/internal/_randomFormatUriReference.mjs +1 -1
- package/lib/internal/_randomFormatUriReference.mjs.map +1 -1
- package/lib/internal/_randomFormatUriTemplate.d.ts +2 -1
- package/lib/internal/_randomFormatUriTemplate.js +1 -1
- package/lib/internal/_randomFormatUriTemplate.js.map +1 -1
- package/lib/internal/_randomFormatUriTemplate.mjs +1 -1
- package/lib/internal/_randomFormatUriTemplate.mjs.map +1 -1
- package/lib/internal/_randomFormatUrl.d.ts +2 -1
- package/lib/internal/_randomFormatUrl.js +21 -1
- package/lib/internal/_randomFormatUrl.js.map +1 -1
- package/lib/internal/_randomFormatUrl.mjs +18 -1
- package/lib/internal/_randomFormatUrl.mjs.map +1 -1
- package/lib/internal/_randomFormatUuid.d.ts +2 -1
- package/lib/internal/_randomFormatUuid.js +3 -2
- package/lib/internal/_randomFormatUuid.js.map +1 -1
- package/lib/internal/_randomFormatUuid.mjs +3 -2
- package/lib/internal/_randomFormatUuid.mjs.map +1 -1
- package/lib/internal/_randomInteger.js +59 -28
- package/lib/internal/_randomInteger.js.map +1 -1
- package/lib/internal/_randomInteger.mjs +56 -16
- package/lib/internal/_randomInteger.mjs.map +1 -1
- package/lib/internal/_randomMultiple.d.ts +8 -0
- package/lib/internal/_randomMultiple.js +168 -0
- package/lib/internal/_randomMultiple.js.map +1 -0
- package/lib/internal/_randomMultiple.mjs +158 -0
- package/lib/internal/_randomMultiple.mjs.map +1 -0
- package/lib/internal/_randomNumber.js +42 -42
- package/lib/internal/_randomNumber.js.map +1 -1
- package/lib/internal/_randomNumber.mjs +41 -27
- package/lib/internal/_randomNumber.mjs.map +1 -1
- package/lib/internal/_randomPattern.d.ts +2 -1
- package/lib/internal/_randomPattern.js +19 -4
- package/lib/internal/_randomPattern.js.map +1 -1
- package/lib/internal/_randomPattern.mjs +10 -4
- package/lib/internal/_randomPattern.mjs.map +1 -1
- package/lib/internal/_randomStringLength.d.ts +33 -0
- package/lib/internal/_randomStringLength.js +48 -0
- package/lib/internal/_randomStringLength.js.map +1 -0
- package/lib/internal/_randomStringLength.mjs +44 -0
- package/lib/internal/_randomStringLength.mjs.map +1 -0
- package/lib/internal/_stringLength.d.ts +1 -0
- package/lib/internal/_stringLength.js +11 -0
- package/lib/internal/_stringLength.js.map +1 -0
- package/lib/internal/_stringLength.mjs +10 -0
- package/lib/internal/_stringLength.mjs.map +1 -0
- package/lib/internal/_validateReport.js +4 -1
- package/lib/internal/_validateReport.js.map +1 -1
- package/lib/internal/_validateReport.mjs +2 -1
- package/lib/internal/_validateReport.mjs.map +1 -1
- package/lib/internal/private/__notationRename.d.ts +14 -0
- package/lib/internal/private/__notationRename.js +25 -0
- package/lib/internal/private/__notationRename.js.map +1 -0
- package/lib/internal/private/__notationRename.mjs +24 -0
- package/lib/internal/private/__notationRename.mjs.map +1 -0
- package/lib/json.d.ts +2 -2
- package/lib/json.mjs.map +1 -1
- package/lib/module.d.ts +2 -2
- package/lib/module.js.map +1 -1
- package/lib/module.mjs.map +1 -1
- package/lib/notations.d.ts +20 -4
- package/lib/notations.js.map +1 -1
- package/lib/notations.mjs.map +1 -1
- package/native/adapter/plugin_options.go +117 -0
- package/native/adapter/plugin_options_payload_matrix_test.go +181 -0
- package/native/cmd/ttsc-typia/any_array_type_tags_transform_test.go +63 -9
- package/native/cmd/ttsc-typia/assert_guard_factory_contract_test.go +152 -0
- package/native/cmd/ttsc-typia/build.go +81 -64
- package/native/cmd/ttsc-typia/build_no_emit_preserves_analysis_options_test.go +67 -0
- package/native/cmd/ttsc-typia/build_no_emit_transform_diagnostics_test.go +138 -0
- package/native/cmd/ttsc-typia/build_plugin_options_come_from_payload_test.go +48 -0
- package/native/cmd/ttsc-typia/build_transactional_emit_success_test.go +81 -0
- package/native/cmd/ttsc-typia/build_transform_failure_atomicity_test.go +138 -0
- package/native/cmd/ttsc-typia/command_routes_and_diagnostics_coverage_test.go +3 -1
- package/native/cmd/ttsc-typia/compare_less_nan_transform_test.go +98 -0
- package/native/cmd/ttsc-typia/compare_native_object_overmatch_transform_test.go +161 -0
- package/native/cmd/ttsc-typia/compare_nondiscriminable_union_transform_test.go +343 -0
- package/native/cmd/ttsc-typia/compare_union_discrimination_transform_test.go +289 -0
- package/native/cmd/ttsc-typia/escaped_property_key_path_transform_test.go +193 -0
- package/native/cmd/ttsc-typia/finite_option_number_leaf_transform_test.go +240 -0
- package/native/cmd/ttsc-typia/functional_promised_type_transform_test.go +220 -0
- package/native/cmd/ttsc-typia/functional_receiver_transform_test.go +232 -0
- package/native/cmd/ttsc-typia/is_object_function_member_transform_test.go +205 -0
- package/native/cmd/ttsc-typia/json_application_alias_function_validation_transform_test.go +151 -0
- package/native/cmd/ttsc-typia/json_is_stringify_finite_number_transform_test.go +198 -0
- package/native/cmd/ttsc-typia/json_stringify_special_key_transform_test.go +238 -0
- package/native/cmd/ttsc-typia/main_wasm.go +21 -2
- package/native/cmd/ttsc-typia/native_collection_identity_is_transform_test.go +234 -0
- package/native/cmd/ttsc-typia/native_generic_name_guard_is_transform_test.go +194 -0
- package/native/cmd/ttsc-typia/native_name_collision_is_transform_test.go +204 -0
- package/native/cmd/ttsc-typia/non_trailing_rest_tuple_transform_test.go +23 -11
- package/native/cmd/ttsc-typia/notation_dynamic_keys_transform_test.go +286 -0
- package/native/cmd/ttsc-typia/notation_kebab_case_transform_test.go +1 -1
- package/native/cmd/ttsc-typia/notation_literal_collision_transform_test.go +164 -0
- package/native/cmd/ttsc-typia/notation_pascal_case_transform_test.go +230 -0
- package/native/cmd/ttsc-typia/notation_unicode_key_transform_test.go +309 -0
- package/native/cmd/ttsc-typia/pattern_line_terminator_escape_transform_test.go +224 -0
- package/native/cmd/ttsc-typia/plain_prune_union_object_overmatch_transform_test.go +219 -0
- package/native/cmd/ttsc-typia/plugin_options_payload_helpers_test.go +181 -0
- package/native/cmd/ttsc-typia/private_field_filter_is_transform_test.go +278 -0
- package/native/cmd/ttsc-typia/project_catalog_transform_coverage_test.go +73 -27
- package/native/cmd/ttsc-typia/project_dependencies_barrel_reexport_transform_test.go +120 -0
- package/native/cmd/ttsc-typia/project_dependencies_collapsed_alias_transform_test.go +134 -0
- package/native/cmd/ttsc-typia/project_dependencies_custom_lib_name_transform_test.go +135 -0
- package/native/cmd/ttsc-typia/project_dependencies_default_barrel_transform_test.go +114 -0
- package/native/cmd/ttsc-typia/project_dependencies_empty_heritage_transform_test.go +100 -0
- package/native/cmd/ttsc-typia/project_dependencies_envelope_transform_test.go +148 -0
- package/native/cmd/ttsc-typia/project_dependencies_index_signature_alias_transform_test.go +139 -0
- package/native/cmd/ttsc-typia/project_dependencies_local_reexport_transform_test.go +122 -0
- package/native/cmd/ttsc-typia/project_dependencies_signature_alias_transform_test.go +125 -0
- package/native/cmd/ttsc-typia/project_dependencies_star_barrel_transform_test.go +112 -0
- package/native/cmd/ttsc-typia/project_reference_graph_envelope_transform_test.go +190 -0
- package/native/cmd/ttsc-typia/protobuf_is_encode_finite_number_transform_test.go +98 -0
- package/native/cmd/ttsc-typia/protobuf_sequence_field_numbers_transform_test.go +52 -22
- package/native/cmd/ttsc-typia/symbol_key_member_filter_transform_test.go +279 -0
- package/native/cmd/ttsc-typia/template_interpolation_type_tags_transform_test.go +86 -23
- package/native/cmd/ttsc-typia/template_literal_type_tags_transform_test.go +3 -1
- package/native/cmd/ttsc-typia/transform.go +228 -39
- package/native/cmd/ttsc-typia/{transform_declaration_source_produces_no_js_test.go → transform_declaration_source_produces_no_javascript_test.go} +10 -2
- package/native/cmd/ttsc-typia/transform_fixtures_emit_coverage_test.go +21 -4
- package/native/cmd/ttsc-typia/transform_helpers_test.go +159 -1
- package/native/cmd/ttsc-typia/transform_plugin_options_come_from_payload_test.go +43 -0
- package/native/cmd/ttsc-typia/transform_single_file_failure_atomicity_test.go +114 -0
- package/native/cmd/ttsc-typia/transform_single_file_failure_writes_no_stdout_test.go +43 -0
- package/native/cmd/ttsc-typia/transform_single_file_js_distinguishes_same_basename_sources_test.go +81 -0
- package/native/cmd/ttsc-typia/transform_single_file_js_empty_emit_reports_no_output_test.go +100 -0
- package/native/cmd/ttsc-typia/transform_single_file_js_locates_output_across_layouts_test.go +160 -0
- package/native/cmd/ttsc-typia/transform_single_file_success_publishes_artifact_test.go +54 -0
- package/native/cmd/ttsc-typia/transform_wasm_host_argv_reports_diagnostics_test.go +39 -0
- package/native/cmd/ttsc-typia/tuple_optional_compare_clone_transform_test.go +227 -0
- package/native/core/factories/FormatCheatSheet.go +40 -7
- package/native/core/factories/IdentifierFactory.go +131 -4
- package/native/core/factories/MetadataCommentTagFactory.go +83 -40
- package/native/core/factories/MetadataTypeTagFactory.go +13 -1
- package/native/core/factories/NumericRangeFactory.go +60 -17
- package/native/core/factories/ProtobufFactory.go +7 -4
- package/native/core/factories/factory_utility_coverage_test.go +8 -2
- package/native/core/factories/format_alias_resolves_to_cheat_sheet_test.go +57 -0
- package/native/core/factories/format_alias_table_targets_the_cheat_sheet_test.go +44 -0
- package/native/core/factories/identifier_factory_postfix_escapes_every_key_test.go +147 -0
- package/native/core/factories/identifier_factory_postfix_survives_every_code_point_test.go +86 -0
- package/native/core/factories/internal/metadata/MetadataHelper.go +60 -6
- package/native/core/factories/internal/metadata/emplace_metadata_object.go +116 -8
- package/native/core/factories/internal/metadata/iterate_metadata.go +6 -0
- package/native/core/factories/internal/metadata/iterate_metadata_function.go +4 -11
- package/native/core/factories/internal/metadata/iterate_metadata_intersection.go +8 -6
- package/native/core/factories/internal/metadata/iterate_metadata_map.go +9 -0
- package/native/core/factories/internal/metadata/iterate_metadata_native.go +27 -2
- package/native/core/factories/internal/metadata/iterate_metadata_set.go +9 -0
- package/native/core/factories/internal/metadata/type_arguments_precondition_test.go +70 -0
- package/native/core/factories/metadata_comment_tag_factory_coverage_test.go +39 -0
- package/native/core/factories/metadata_comment_tag_factory_exclusivity_matches_interface_test.go +84 -0
- package/native/core/factories/metadata_type_tag_factory_accepts_legal_tag_combinations_test.go +60 -0
- package/native/core/factories/metadata_type_tag_factory_declarations_test.go +86 -0
- package/native/core/factories/metadata_type_tag_factory_keeps_bool_form_exclusivity_test.go +38 -0
- package/native/core/factories/metadata_type_tag_factory_rejects_cross_kind_exclusive_tags_test.go +65 -0
- package/native/core/factories/metadata_type_tag_factory_rejects_duplicated_array_form_tags_test.go +41 -0
- package/native/core/factories/numeric_range_factory_enforces_64bit_bounds_test.go +69 -0
- package/native/core/factories/protobuf_recovery_ownership_test.go +64 -0
- package/native/core/programmers/IsProgrammer.go +15 -1
- package/native/core/programmers/RandomProgrammer.go +51 -14
- package/native/core/programmers/compare/CompareEqualProgrammer.go +393 -5
- package/native/core/programmers/compare/CompareLessProgrammer.go +4 -2
- package/native/core/programmers/functional/FunctionalAssertFunctionProgrammer.go +4 -6
- package/native/core/programmers/functional/FunctionalAssertParametersProgrammer.go +5 -13
- package/native/core/programmers/functional/FunctionalAssertReturnProgrammer.go +6 -14
- package/native/core/programmers/functional/FunctionalIsFunctionProgrammer.go +4 -6
- package/native/core/programmers/functional/FunctionalIsParametersProgrammer.go +49 -14
- package/native/core/programmers/functional/FunctionalIsReturnProgrammer.go +5 -13
- package/native/core/programmers/functional/FunctionalValidateFunctionProgrammer.go +4 -6
- package/native/core/programmers/functional/FunctionalValidateParametersProgrammer.go +5 -13
- package/native/core/programmers/functional/FunctionalValidateReturnProgrammer.go +5 -13
- package/native/core/programmers/functional/internal/FunctionalGeneralProgrammer.go +4 -17
- package/native/core/programmers/helpers/CloneJoiner.go +32 -0
- package/native/core/programmers/helpers/NotationJoiner.go +86 -28
- package/native/core/programmers/helpers/StringifyJoinder.go +32 -1
- package/native/core/programmers/helpers/UnionExplorer.go +203 -61
- package/native/core/programmers/helpers/joiner_branch_coverage_test.go +5 -3
- package/native/core/programmers/helpers/union_explorer_coverage_test.go +1 -1
- package/native/core/programmers/internal/CheckerProgrammer.go +100 -48
- package/native/core/programmers/iterate/check_template.go +344 -32
- package/native/core/programmers/iterate/json_schema_discriminator.go +36 -10
- package/native/core/programmers/iterate/json_schema_discriminator_declaration_syntax_test.go +205 -0
- package/native/core/programmers/iterate/openapi_v3_downgrader.go +641 -0
- package/native/core/programmers/iterate/openapi_v3_downgrader_boolean_default_test.go +95 -0
- package/native/core/programmers/iterate/openapi_v3_downgrader_test.go +123 -0
- package/native/core/programmers/iterate/template_interpolation_tags_test.go +40 -8
- package/native/core/programmers/iterate/template_runtime_pattern.go +52 -7
- package/native/core/programmers/json/JsonApplicationProgrammer.go +45 -11
- package/native/core/programmers/json/JsonSchemasProgrammer.go +12 -2
- package/native/core/programmers/llm/LlmApplicationProgrammer.go +12 -10
- package/native/core/programmers/llm/LlmSchemaProgrammer.go +23 -6
- package/native/core/programmers/llm/llm_reference_codec_test.go +24 -0
- package/native/core/programmers/notations/NotationGeneralProgrammer.go +183 -67
- package/native/core/programmers/notations/notation_general_helpers_test.go +1 -3
- package/native/core/programmers/notations/notation_general_programmer_pascal_multiword_test.go +72 -0
- package/native/core/programmers/notations/notation_general_programmer_underscore_boundary_test.go +68 -0
- package/native/core/programmers/plain/PlainClassifyProgrammer.go +23 -15
- package/native/core/programmers/plain/PlainCloneProgrammer.go +20 -7
- package/native/core/programmers/plain/PlainPruneProgrammer.go +19 -5
- package/native/core/programmers/plain/plain_tuple_seed_recovery_ownership_test.go +25 -0
- package/native/core/programmers/protobuf/ProtobufDecodeProgrammer.go +37 -28
- package/native/core/programmers/protobuf/ProtobufMessageProgrammer.go +40 -21
- package/native/core/programmers/protobuf/protobuf_programmer_helper_coverage_test.go +26 -0
- package/native/core/programmers/random_programmer_length_argument_test.go +53 -0
- package/native/core/schemas/metadata/MetadataCollection.go +270 -20
- package/native/core/schemas/metadata/MetadataDependency.go +388 -0
- package/native/core/schemas/metadata/MetadataObjectType.go +17 -4
- package/native/core/schemas/metadata/metadata_collection_generic_argument_dot_test.go +122 -0
- package/native/core/schemas/metadata/metadata_collection_name_allocation_test.go +147 -0
- package/native/core/schemas/metadata/metadata_collection_openapi_name_cascade_test.go +55 -0
- package/native/core/schemas/metadata/metadata_collection_openapi_name_test.go +68 -0
- package/native/core/utils/PatternUtil.go +13 -0
- package/native/core/utils/PromiseTypeFactory.go +59 -0
- package/native/core/utils/ProtobufNameEncoder.go +8 -0
- package/native/core/utils/promise_type_factory_semantics_test.go +118 -0
- package/native/go.mod +9 -1
- package/native/transform/CallExpressionTransformer.go +12 -0
- package/native/transform/features/json/JsonApplicationTransformer.go +1 -1
- package/native/transform/features/json/JsonSchemaTransformer.go +1 -1
- package/native/transform/features/json/JsonSchemasTransformer.go +5 -4
- package/package.json +16 -4
- package/src/executable/FileSystemIdentity.ts +189 -0
- package/src/executable/TypiaGenerateWizard.ts +377 -110
- package/src/functional.ts +30 -60
- package/src/internal/_ProtobufReader.ts +129 -43
- package/src/internal/_createStandardSchema.ts +15 -1
- package/src/internal/_decimal.ts +69 -0
- package/src/internal/_httpQueryParseURLSearchParams.ts +24 -2
- package/src/internal/_isFormatByte.ts +2 -5
- package/src/internal/_isFormatDate.ts +15 -2
- package/src/internal/_isFormatDateTime.ts +28 -2
- package/src/internal/_isFormatIri.ts +5 -2
- package/src/internal/_isFormatIriReference.ts +11 -3
- package/src/internal/_isFormatUriReference.ts +1 -1
- package/src/internal/_isMultipleOf.ts +8 -0
- package/src/internal/_isTypeFloat.ts +1 -1
- package/src/internal/_isTypeInt64.ts +1 -0
- package/src/internal/_isTypeInt64Bigint.ts +12 -0
- package/src/internal/_isTypeUint64.ts +1 -0
- package/src/internal/_isTypeUint64Bigint.ts +7 -0
- package/src/internal/_isUniqueItems.ts +134 -132
- package/src/internal/_notationAny.ts +9 -4
- package/src/internal/_notationAssign.ts +20 -0
- package/src/internal/_notationCamel.ts +31 -10
- package/src/internal/_notationKebab.ts +11 -0
- package/src/internal/_notationKeyCollision.ts +9 -0
- package/src/internal/_notationPascal.ts +19 -6
- package/src/internal/_notationSnake.ts +24 -21
- package/src/internal/_plainCloneAny.ts +208 -33
- package/src/internal/_randomArray.ts +13 -4
- package/src/internal/_randomFormatByte.ts +4 -1
- package/src/internal/_randomFormatDate.ts +17 -12
- package/src/internal/_randomFormatDatetime.ts +15 -10
- package/src/internal/_randomFormatDuration.ts +16 -14
- package/src/internal/_randomFormatEmail.ts +8 -2
- package/src/internal/_randomFormatHostname.ts +48 -1
- package/src/internal/_randomFormatIdnEmail.ts +18 -2
- package/src/internal/_randomFormatIdnHostname.ts +34 -2
- package/src/internal/_randomFormatIpv4.ts +3 -2
- package/src/internal/_randomFormatIpv6.ts +3 -2
- package/src/internal/_randomFormatIri.ts +3 -1
- package/src/internal/_randomFormatIriReference.ts +3 -1
- package/src/internal/_randomFormatJsonPointer.ts +8 -2
- package/src/internal/_randomFormatPassword.ts +11 -6
- package/src/internal/_randomFormatRegex.ts +4 -1
- package/src/internal/_randomFormatRelativeJsonPointer.ts +13 -6
- package/src/internal/_randomFormatTime.ts +13 -10
- package/src/internal/_randomFormatUri.ts +3 -1
- package/src/internal/_randomFormatUriReference.ts +3 -1
- package/src/internal/_randomFormatUriTemplate.ts +3 -1
- package/src/internal/_randomFormatUrl.ts +25 -2
- package/src/internal/_randomFormatUuid.ts +10 -6
- package/src/internal/_randomInteger.ts +87 -40
- package/src/internal/_randomMultiple.ts +245 -0
- package/src/internal/_randomNumber.ts +72 -55
- package/src/internal/_randomPattern.ts +26 -4
- package/src/internal/_randomStringLength.ts +72 -0
- package/src/internal/_stringLength.ts +5 -0
- package/src/internal/_validateReport.ts +5 -1
- package/src/internal/private/__notationRename.ts +24 -0
- package/src/json.ts +2 -2
- package/src/module.ts +4 -6
- package/src/notations.ts +20 -4
- package/lib/internal/private/__notationCapitalize.d.ts +0 -1
- package/lib/internal/private/__notationCapitalize.js +0 -6
- package/lib/internal/private/__notationCapitalize.js.map +0 -1
- package/lib/internal/private/__notationCapitalize.mjs +0 -6
- package/lib/internal/private/__notationCapitalize.mjs.map +0 -1
- package/lib/internal/private/__notationUnsnake.d.ts +0 -4
- package/lib/internal/private/__notationUnsnake.js +0 -26
- package/lib/internal/private/__notationUnsnake.js.map +0 -1
- package/lib/internal/private/__notationUnsnake.mjs +0 -15
- package/lib/internal/private/__notationUnsnake.mjs.map +0 -1
- package/native/cmd/ttsc-typia/plugin_options_missing_config_test.go +0 -26
- package/native/cmd/ttsc-typia/plugin_options_undefined_false_test.go +0 -36
- package/src/internal/private/__notationCapitalize.ts +0 -2
- package/src/internal/private/__notationUnsnake.ts +0 -24
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
package factories
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"slices"
|
|
5
|
+
"testing"
|
|
6
|
+
|
|
7
|
+
schemametadata "github.com/samchon/typia/packages/typia/native/core/schemas/metadata"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
// TestProtobufEmplacerRecoveryOwnership verifies unexpected panics stay visible.
|
|
11
|
+
//
|
|
12
|
+
// Unsupported metadata is diagnosed before emission, but an invariant failure
|
|
13
|
+
// inside the Protobuf emplacer must not be converted into a successful semantic
|
|
14
|
+
// result by a blanket recover.
|
|
15
|
+
//
|
|
16
|
+
// 1. Verify unsupported metadata remains an ordinary diagnostic.
|
|
17
|
+
// 2. Build a static object with an impossible empty semantic schema.
|
|
18
|
+
// 3. Require the panic to escape the post-validation emplacement pass.
|
|
19
|
+
func TestProtobufEmplacerRecoveryOwnership(t *testing.T) {
|
|
20
|
+
unsupported := schemametadata.MetadataSchema_initialize()
|
|
21
|
+
unsupported.Any = true
|
|
22
|
+
errors := protobufFactory_validate()(struct {
|
|
23
|
+
Metadata *schemametadata.MetadataSchema
|
|
24
|
+
Explore MetadataFactory_IExplore
|
|
25
|
+
Top *schemametadata.MetadataSchema
|
|
26
|
+
}{
|
|
27
|
+
Metadata: unsupported,
|
|
28
|
+
Explore: MetadataFactory_IExplore{Top: true},
|
|
29
|
+
Top: unsupported,
|
|
30
|
+
})
|
|
31
|
+
if !slices.Contains(errors, "does not support any type") {
|
|
32
|
+
t.Fatalf("unsupported any fallback mismatch: %v", errors)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
key := MetadataFactory.SoleLiteral("value")
|
|
36
|
+
dynamicKey := schemametadata.MetadataSchema_initialize()
|
|
37
|
+
dynamicKey.Atomics = append(dynamicKey.Atomics, schemametadata.MetadataAtomic_create(schemametadata.MetadataAtomic{Type: "string"}))
|
|
38
|
+
dynamic := schemametadata.MetadataObjectType_create(schemametadata.MetadataObjectType{
|
|
39
|
+
Name: "BrokenMap",
|
|
40
|
+
Properties: []*schemametadata.MetadataProperty{
|
|
41
|
+
schemametadata.MetadataProperty_create(schemametadata.MetadataProperty{
|
|
42
|
+
Key: dynamicKey,
|
|
43
|
+
Value: schemametadata.MetadataSchema_initialize(),
|
|
44
|
+
}),
|
|
45
|
+
},
|
|
46
|
+
})
|
|
47
|
+
value := schemametadata.MetadataSchema_initialize()
|
|
48
|
+
value.Objects = append(value.Objects, schemametadata.MetadataObject_create(schemametadata.MetadataObject{Type: dynamic}))
|
|
49
|
+
object := schemametadata.MetadataObjectType_create(schemametadata.MetadataObjectType{
|
|
50
|
+
Name: "Broken",
|
|
51
|
+
Properties: []*schemametadata.MetadataProperty{
|
|
52
|
+
schemametadata.MetadataProperty_create(schemametadata.MetadataProperty{
|
|
53
|
+
Key: key,
|
|
54
|
+
Value: value,
|
|
55
|
+
}),
|
|
56
|
+
},
|
|
57
|
+
})
|
|
58
|
+
defer func() {
|
|
59
|
+
if recover() == nil {
|
|
60
|
+
t.Fatal("unexpected Protobuf emplacer panic was swallowed")
|
|
61
|
+
}
|
|
62
|
+
}()
|
|
63
|
+
protobufFactory_emplaceObjects([]*schemametadata.MetadataObjectType{object})
|
|
64
|
+
}
|
|
@@ -18,6 +18,7 @@ var IsProgrammer = isProgrammerNamespace{}
|
|
|
18
18
|
|
|
19
19
|
type IsProgrammer_CONFIG_IOptions struct {
|
|
20
20
|
Numeric *bool
|
|
21
|
+
Finite *bool
|
|
21
22
|
Undefined *bool
|
|
22
23
|
Object func(props IsProgrammer_CONFIG_IOptions_ObjectProps) *shimast.Node
|
|
23
24
|
}
|
|
@@ -182,6 +183,7 @@ func (isProgrammerNamespace) Decompose(props IsProgrammer_DecomposeProps) native
|
|
|
182
183
|
f := nativecontext.EmitFactoryOf(isProgrammer_factory, props.Context.Emit)
|
|
183
184
|
options := &IsProgrammer_CONFIG_IOptions{
|
|
184
185
|
Numeric: props.Context.Options.Numeric,
|
|
186
|
+
Finite: props.Context.Options.Finite,
|
|
185
187
|
Object: func(v IsProgrammer_CONFIG_IOptions_ObjectProps) *shimast.Node {
|
|
186
188
|
return nativeiterate.Check_object(nativeiterate.Check_objectProps{
|
|
187
189
|
Config: nativeiterate.Check_object_IConfig{
|
|
@@ -397,8 +399,20 @@ func isProgrammer_binary(left *shimast.Expression, operator shimast.Kind, right
|
|
|
397
399
|
)
|
|
398
400
|
}
|
|
399
401
|
|
|
402
|
+
// isProgrammer_option_numeric reports whether the number leaf gate must be
|
|
403
|
+
// emitted at all. It opens on `finite` as well as `numeric` so that `finite:true`
|
|
404
|
+
// alone rejects NaN and Infinity, matching how assert/validate open the same gate
|
|
405
|
+
// via OptionPredicator.Numeric (which is likewise finite || numeric) and the
|
|
406
|
+
// documented independence of the two flags (samchon/typia#2196). The gate only
|
|
407
|
+
// decides whether check_number emits a guard; check_number's own inner selection
|
|
408
|
+
// then picks Number.isFinite for `finite` or !Number.isNaN for `numeric`.
|
|
400
409
|
func isProgrammer_option_numeric(options *IsProgrammer_CONFIG_IOptions) bool {
|
|
401
|
-
|
|
410
|
+
if options == nil {
|
|
411
|
+
return false
|
|
412
|
+
}
|
|
413
|
+
finite := options.Finite != nil && *options.Finite
|
|
414
|
+
numeric := options.Numeric != nil && *options.Numeric
|
|
415
|
+
return finite || numeric
|
|
402
416
|
}
|
|
403
417
|
|
|
404
418
|
func isProgrammer_option_undefined(options *IsProgrammer_CONFIG_IOptions) bool {
|
|
@@ -615,27 +615,36 @@ type randomProgrammer_composedAtomic struct {
|
|
|
615
615
|
func randomProgrammer_compose_atomic(atomicType string, schema nativeiterate.JsonSchema, emit *shimprinter.EmitContext) randomProgrammer_composedAtomic {
|
|
616
616
|
f := nativecontext.EmitFactoryOf(randomProgrammer_factory, emit)
|
|
617
617
|
if atomicType == "string" {
|
|
618
|
+
// A string leaf that also carries a length tag needs the bounds forwarded
|
|
619
|
+
// to the format and pattern generators; only the plain-string fall-through
|
|
620
|
+
// used to receive the full schema, so a format or pattern combined with
|
|
621
|
+
// minLength/maxLength was generated at the wrong length and failed its own
|
|
622
|
+
// validator (issue #2189).
|
|
623
|
+
lengthArgs := randomProgrammer_length_argument(schema, emit)
|
|
618
624
|
if raw, ok := schema["format"].(string); ok && raw != "" {
|
|
619
625
|
if raw == "date-time" {
|
|
620
|
-
return randomProgrammer_composedAtomic{Method: "datetime", Internal: "randomFormatDatetime"}
|
|
626
|
+
return randomProgrammer_composedAtomic{Method: "datetime", Internal: "randomFormatDatetime", Arguments: lengthArgs}
|
|
621
627
|
}
|
|
622
628
|
method := randomProgrammer_format_method(raw)
|
|
623
629
|
return randomProgrammer_composedAtomic{
|
|
624
|
-
Method:
|
|
625
|
-
Internal:
|
|
630
|
+
Method: method,
|
|
631
|
+
Internal: "randomFormat" + randomProgrammer_format_pascal(raw),
|
|
632
|
+
Arguments: lengthArgs,
|
|
626
633
|
}
|
|
627
634
|
}
|
|
628
635
|
if pattern, ok := schema["pattern"].(string); ok && pattern != "" {
|
|
636
|
+
arguments := []*shimast.Node{
|
|
637
|
+
f.NewNewExpression(
|
|
638
|
+
f.NewIdentifier("RegExp"),
|
|
639
|
+
nil,
|
|
640
|
+
f.NewNodeList([]*shimast.Node{f.NewStringLiteral(pattern, shimast.TokenFlagsNone)}),
|
|
641
|
+
),
|
|
642
|
+
}
|
|
643
|
+
arguments = append(arguments, lengthArgs...)
|
|
629
644
|
return randomProgrammer_composedAtomic{
|
|
630
|
-
Method:
|
|
631
|
-
Internal:
|
|
632
|
-
Arguments:
|
|
633
|
-
f.NewNewExpression(
|
|
634
|
-
f.NewIdentifier("RegExp"),
|
|
635
|
-
nil,
|
|
636
|
-
f.NewNodeList([]*shimast.Node{f.NewStringLiteral(pattern, shimast.TokenFlagsNone)}),
|
|
637
|
-
),
|
|
638
|
-
},
|
|
645
|
+
Method: "pattern",
|
|
646
|
+
Internal: "randomPattern",
|
|
647
|
+
Arguments: arguments,
|
|
639
648
|
}
|
|
640
649
|
}
|
|
641
650
|
} else if atomicType == "number" {
|
|
@@ -659,6 +668,24 @@ func randomProgrammer_compose_atomic(atomicType string, schema nativeiterate.Jso
|
|
|
659
668
|
}
|
|
660
669
|
}
|
|
661
670
|
|
|
671
|
+
// randomProgrammer_length_argument forwards the minLength/maxLength bounds of a
|
|
672
|
+
// string leaf to the format and pattern generators as a
|
|
673
|
+
// `{ minLength?, maxLength? }` object literal, or nil when the leaf carries no
|
|
674
|
+
// length tag so the format-only and pattern-only emission stays byte-identical.
|
|
675
|
+
func randomProgrammer_length_argument(schema nativeiterate.JsonSchema, emit *shimprinter.EmitContext) []*shimast.Node {
|
|
676
|
+
length := map[string]any{}
|
|
677
|
+
if value, ok := schema["minLength"]; ok {
|
|
678
|
+
length["minLength"] = value
|
|
679
|
+
}
|
|
680
|
+
if value, ok := schema["maxLength"]; ok {
|
|
681
|
+
length["maxLength"] = value
|
|
682
|
+
}
|
|
683
|
+
if len(length) == 0 {
|
|
684
|
+
return nil
|
|
685
|
+
}
|
|
686
|
+
return []*shimast.Node{nativefactories.LiteralFactory.Write(length, emit)}
|
|
687
|
+
}
|
|
688
|
+
|
|
662
689
|
func randomProgrammer_decode_template(props struct {
|
|
663
690
|
Context nativecontext.ITypiaContext
|
|
664
691
|
Functor *nativehelpers.FunctionProgrammer
|
|
@@ -1407,6 +1434,16 @@ func randomProgrammer_is_typed_array(name string) bool {
|
|
|
1407
1434
|
}
|
|
1408
1435
|
}
|
|
1409
1436
|
|
|
1437
|
+
// randomProgrammer_typed_array_range reports the type tag and range a TypedArray's
|
|
1438
|
+
// elements are generated from.
|
|
1439
|
+
//
|
|
1440
|
+
// These bounds are a generation hint, not a validation gate, and they are the one
|
|
1441
|
+
// copy of the 64-bit bound that is deliberately inexact. They become `minimum` and
|
|
1442
|
+
// `maximum` comment tags on a number-typed JSON schema, and `number` cannot
|
|
1443
|
+
// represent 2**63 - 1 or 2**64 - 1 -- both arrive rounded up to the next power of
|
|
1444
|
+
// two. That costs nothing here: the generator only picks a value from the range,
|
|
1445
|
+
// and the TypedArray constructor wraps whatever it is handed. Validation owns
|
|
1446
|
+
// exactness instead, in _isTypeInt64Bigint and its siblings.
|
|
1410
1447
|
func randomProgrammer_typed_array_range(name string) (string, string, string) {
|
|
1411
1448
|
switch name {
|
|
1412
1449
|
case "Uint8Array", "Uint8ClampedArray":
|
|
@@ -1424,9 +1461,9 @@ func randomProgrammer_typed_array_range(name string) (string, string, string) {
|
|
|
1424
1461
|
case "Int32Array":
|
|
1425
1462
|
return "int32", "-2147483648", "2147483647"
|
|
1426
1463
|
case "BigInt64Array":
|
|
1427
|
-
return "
|
|
1464
|
+
return "int64", "-9223372036854775808", "9223372036854775807"
|
|
1428
1465
|
case "Float32Array":
|
|
1429
|
-
return "float", "-
|
|
1466
|
+
return "float", "-3.4028235e38", "3.4028235e38"
|
|
1430
1467
|
default:
|
|
1431
1468
|
return "double", fmt.Sprint(math.SmallestNonzeroFloat64), fmt.Sprint(math.MaxFloat64)
|
|
1432
1469
|
}
|
|
@@ -34,6 +34,10 @@ type compareEqualProgrammerGenerator struct {
|
|
|
34
34
|
Config CompareEqualProgrammer_IConfig
|
|
35
35
|
Recursive bool
|
|
36
36
|
Counter int
|
|
37
|
+
// Member-resolution checkers (`_ui<index>`) emitted on demand for the object
|
|
38
|
+
// unions that need the is-match ladder, keyed by the object's collection index.
|
|
39
|
+
Matchers []string
|
|
40
|
+
MatcherIndex map[int]bool
|
|
37
41
|
}
|
|
38
42
|
|
|
39
43
|
var compareEqualProgrammer_factory = shimast.NewNodeFactory(shimast.NodeFactoryHooks{})
|
|
@@ -71,8 +75,9 @@ func (compareEqualProgrammerNamespace) Write(props CompareEqualProgrammer_IProps
|
|
|
71
75
|
}
|
|
72
76
|
|
|
73
77
|
generator := &compareEqualProgrammerGenerator{
|
|
74
|
-
Config:
|
|
75
|
-
Recursive:
|
|
78
|
+
Config: props.Config,
|
|
79
|
+
Recursive: nativeinternal.FeatureProgrammer.CollectionRecursive(collection),
|
|
80
|
+
MatcherIndex: map[int]bool{},
|
|
76
81
|
}
|
|
77
82
|
body := generator.schema(result.Data, "x", "y")
|
|
78
83
|
statements := []string{}
|
|
@@ -89,6 +94,12 @@ func (compareEqualProgrammerNamespace) Write(props CompareEqualProgrammer_IProps
|
|
|
89
94
|
statements = append(statements, generator.tupleFunction(tuple))
|
|
90
95
|
}
|
|
91
96
|
}
|
|
97
|
+
// The member matchers are collected last because every generation step above
|
|
98
|
+
// may request one. They are `const` arrow functions in the same scope as the
|
|
99
|
+
// `_eo`/`_ea`/`_et` helpers and are only ever called after this IIFE returns,
|
|
100
|
+
// so declaring them at the end is free of temporal-dead-zone hazards — the
|
|
101
|
+
// same placement `is` uses for the `_io` checkers it appends after `_cu`.
|
|
102
|
+
statements = append(statements, generator.Matchers...)
|
|
92
103
|
if generator.Recursive {
|
|
93
104
|
statements = append(statements, "return (x, y) => { const _vctx = {}; return "+body+"; };")
|
|
94
105
|
} else {
|
|
@@ -155,8 +166,28 @@ func (g *compareEqualProgrammerGenerator) schema(metadata *schemametadata.Metada
|
|
|
155
166
|
for _, array := range metadata.Arrays {
|
|
156
167
|
branches = append(branches, g.array(array, x, y))
|
|
157
168
|
}
|
|
158
|
-
|
|
159
|
-
|
|
169
|
+
// A union of two or more object types must discriminate: route each operand
|
|
170
|
+
// to exactly one member and compare within that single member. A flat OR of
|
|
171
|
+
// member comparators lets a wrong member's comparator match spuriously — its
|
|
172
|
+
// literal discriminant is satisfied by the always-present `x[k] === y[k]`
|
|
173
|
+
// branch and its absent payload keys compare `undefined === undefined`. The
|
|
174
|
+
// discrimination reuses the shared UnionPredicator specialization the sibling
|
|
175
|
+
// programmers (is/clone/classify/...) route through, so `equals` agrees with
|
|
176
|
+
// `is` on which member a value is. A union no discriminant can split (every
|
|
177
|
+
// distinguishing key optional, e.g. `{ a?: number } | { b?: string }`) routes
|
|
178
|
+
// through the first-is-match ladder instead — never a flat OR, which admits
|
|
179
|
+
// the same spurious match through absent keys comparing
|
|
180
|
+
// `undefined === undefined` (issue #2225).
|
|
181
|
+
if len(metadata.Objects) >= 2 {
|
|
182
|
+
expr := g.objectUnion(metadata.Objects, x, y)
|
|
183
|
+
if guard := g.notNatives(metadata.Natives, x, y); guard != "" {
|
|
184
|
+
expr = g.and(guard, expr)
|
|
185
|
+
}
|
|
186
|
+
branches = append(branches, expr)
|
|
187
|
+
} else {
|
|
188
|
+
for _, object := range metadata.Objects {
|
|
189
|
+
branches = append(branches, g.objectFlatBranch(object.Type, metadata.Natives, x, y))
|
|
190
|
+
}
|
|
160
191
|
}
|
|
161
192
|
for _, alias := range metadata.Aliases {
|
|
162
193
|
branches = append(branches, g.schema(alias.Type.Value, x, y))
|
|
@@ -233,7 +264,27 @@ func (g *compareEqualProgrammerGenerator) tupleInline(tuple *schemametadata.Meta
|
|
|
233
264
|
g.same(g.access(x, "length"), g.access(y, "length")),
|
|
234
265
|
}
|
|
235
266
|
if rest == nil {
|
|
236
|
-
|
|
267
|
+
// An omitted optional trailing element makes the tuple's length a range
|
|
268
|
+
// [required, fixed] — exactly the gate `is` emits. A hard `=== fixed`
|
|
269
|
+
// rejects a value `is` accepts and breaks reflexivity of `equals`; the
|
|
270
|
+
// per-element `x[i] === y[i]` prefix already treats both-absent as equal,
|
|
271
|
+
// so only the length gate needs the range. A fully-required tuple keeps
|
|
272
|
+
// its byte-identical `x.length === fixed`.
|
|
273
|
+
required := 0
|
|
274
|
+
allRequired := true
|
|
275
|
+
for i := 0; i < fixed; i++ {
|
|
276
|
+
if tuple.Elements[i].Optional {
|
|
277
|
+
allRequired = false
|
|
278
|
+
} else {
|
|
279
|
+
required++
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
if allRequired {
|
|
283
|
+
checks = append(checks, g.same(g.access(x, "length"), strconv.Itoa(fixed)))
|
|
284
|
+
} else {
|
|
285
|
+
length := g.access(x, "length")
|
|
286
|
+
checks = append(checks, fmt.Sprintf("%d <= %s && %d >= %s", required, length, fixed, length))
|
|
287
|
+
}
|
|
237
288
|
} else {
|
|
238
289
|
checks = append(checks, fmt.Sprintf("%s.length >= %d", g.wrap(x), fixed))
|
|
239
290
|
}
|
|
@@ -256,6 +307,328 @@ func (g *compareEqualProgrammerGenerator) objectCall(object *schemametadata.Meta
|
|
|
256
307
|
return fmt.Sprintf("_eo%d(%s, %s)", object.Index, g.wrap(x), g.wrap(y))
|
|
257
308
|
}
|
|
258
309
|
|
|
310
|
+
// objectFlatBranch renders one member of an object union as a guarded member
|
|
311
|
+
// comparator (the pre-discrimination form). It is used for a single-object
|
|
312
|
+
// "union" and as the fallback for a union no supported predicate can split.
|
|
313
|
+
func (g *compareEqualProgrammerGenerator) objectFlatBranch(object *schemametadata.MetadataObjectType, natives []*schemametadata.MetadataNative, x string, y string) string {
|
|
314
|
+
// Guard the object branch against the sibling native instances. `_eo` admits
|
|
315
|
+
// any `typeof === "object" && !Array.isArray` value, so a native (a Date is
|
|
316
|
+
// an object) would be compared by the object's declared keys, which the
|
|
317
|
+
// native lacks — two different Dates then look equal on their absent keys and
|
|
318
|
+
// the OR wrongly accepts. Excluding what a native branch owns makes the arms
|
|
319
|
+
// mutually exclusive, matching the clone/classify ladder whose object arm is
|
|
320
|
+
// unreachable once a native arm matches.
|
|
321
|
+
call := g.objectCall(object, x, y)
|
|
322
|
+
if guard := g.notNatives(natives, x, y); guard != "" {
|
|
323
|
+
call = g.and(guard, call)
|
|
324
|
+
}
|
|
325
|
+
return call
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// objectUnion renders a discriminated comparison for a union of two or more
|
|
329
|
+
// object types. It mirrors the is/clone/classify discrimination: each operand is
|
|
330
|
+
// routed to exactly one member, and only when both land on the same member does
|
|
331
|
+
// that member's comparator run. This replaces the flat OR whose wrong-member
|
|
332
|
+
// comparator could match spuriously.
|
|
333
|
+
//
|
|
334
|
+
// Routing prefers the shared UnionPredicator discriminants (issue #2214). When
|
|
335
|
+
// no discriminant splits the members — every distinguishing key is optional, so
|
|
336
|
+
// UnionPredicator yields no specialization, or more than one member is left
|
|
337
|
+
// unspecialized — routing falls back to the first-is-match ladder that
|
|
338
|
+
// clone/classify/prune reach through Decode_union_object (issue #2225). There is
|
|
339
|
+
// no flat-OR fallback: the flat OR is the defect both issues describe.
|
|
340
|
+
func (g *compareEqualProgrammerGenerator) objectUnion(objects []*schemametadata.MetadataObject, x string, y string) string {
|
|
341
|
+
types := make([]*schemametadata.MetadataObjectType, 0, len(objects))
|
|
342
|
+
for _, object := range objects {
|
|
343
|
+
types = append(types, object.Type)
|
|
344
|
+
}
|
|
345
|
+
ladder, ok := g.discriminantLadder(types)
|
|
346
|
+
if ok == false {
|
|
347
|
+
ladder = g.matchLadder(types)
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
tag := g.local("utag")
|
|
351
|
+
tx := g.local("utx")
|
|
352
|
+
// Dispatch: with the shared member index, run only that member's comparator.
|
|
353
|
+
dispatch := "false"
|
|
354
|
+
for i := len(types) - 1; i >= 0; i-- {
|
|
355
|
+
dispatch = fmt.Sprintf("%s === %d ? %s : %s", tx, types[i].Index, g.objectCall(types[i], "x", "y"), dispatch)
|
|
356
|
+
}
|
|
357
|
+
body := fmt.Sprintf(
|
|
358
|
+
"((x, y) => { const %s = (v) => (%s) ? (%s) : -1; const %s = %s(x); return %s !== -1 && %s === %s(y) && (%s); })(%s, %s)",
|
|
359
|
+
tag, g.isObject("v"), ladder, tx, tag, tx, tx, tag, dispatch, g.wrap(x), g.wrap(y),
|
|
360
|
+
)
|
|
361
|
+
return body
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// discriminantLadder renders the routing ternary from the shared UnionPredicator
|
|
365
|
+
// specialization: `<discriminant of member i> ? <index of member i> : ...`,
|
|
366
|
+
// ending in the lone unspecialized member (the unconditional else the
|
|
367
|
+
// discriminant ladder leaves) or -1 for "no member". It reports ok=false when
|
|
368
|
+
// the members carry no usable discriminant, when more than one member is left
|
|
369
|
+
// unspecialized, or when a discriminant value cannot be rendered as a check —
|
|
370
|
+
// the caller then routes by is-match instead.
|
|
371
|
+
func (g *compareEqualProgrammerGenerator) discriminantLadder(types []*schemametadata.MetadataObjectType) (string, bool) {
|
|
372
|
+
specs := nativehelpers.UnionPredicator.Object(types)
|
|
373
|
+
if len(specs) == 0 {
|
|
374
|
+
return "", false
|
|
375
|
+
}
|
|
376
|
+
specialized := map[*schemametadata.MetadataObjectType]bool{}
|
|
377
|
+
for _, spec := range specs {
|
|
378
|
+
specialized[spec.Object] = true
|
|
379
|
+
}
|
|
380
|
+
remained := []*schemametadata.MetadataObjectType{}
|
|
381
|
+
for _, object := range types {
|
|
382
|
+
if specialized[object] == false {
|
|
383
|
+
remained = append(remained, object)
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
if len(remained) > 1 {
|
|
387
|
+
return "", false
|
|
388
|
+
}
|
|
389
|
+
fallback := "-1"
|
|
390
|
+
if len(remained) == 1 {
|
|
391
|
+
fallback = strconv.Itoa(remained[0].Index)
|
|
392
|
+
}
|
|
393
|
+
ladder := fallback
|
|
394
|
+
for i := len(specs) - 1; i >= 0; i-- {
|
|
395
|
+
check, ok := g.discriminant(specs[i], "v")
|
|
396
|
+
if ok == false {
|
|
397
|
+
return "", false
|
|
398
|
+
}
|
|
399
|
+
ladder = fmt.Sprintf("%s ? %d : %s", check, specs[i].Object.Index, ladder)
|
|
400
|
+
}
|
|
401
|
+
return ladder, true
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// matchLadder renders the routing ternary for a union no discriminant splits:
|
|
405
|
+
// the first member the value is-matches wins, exactly as `clone`/`classify`/
|
|
406
|
+
// `prune` resolve membership through Decode_union_object's `if (_io0(input))
|
|
407
|
+
// return ...; if (_io1(input)) ...` ladder. A value matching no member yields
|
|
408
|
+
// -1, which makes `equals` false rather than letting a wrong member's comparator
|
|
409
|
+
// decide.
|
|
410
|
+
func (g *compareEqualProgrammerGenerator) matchLadder(types []*schemametadata.MetadataObjectType) string {
|
|
411
|
+
calls := make([]string, 0, len(types))
|
|
412
|
+
for _, object := range types {
|
|
413
|
+
// Declared in member order so the emitted matchers read in the same order
|
|
414
|
+
// as the ladder that calls them; the ladder itself is folded back to front.
|
|
415
|
+
calls = append(calls, g.matchCall(object, "v"))
|
|
416
|
+
}
|
|
417
|
+
ladder := "-1"
|
|
418
|
+
for i := len(types) - 1; i >= 0; i-- {
|
|
419
|
+
ladder = fmt.Sprintf("%s ? %d : %s", calls[i], types[i].Index, ladder)
|
|
420
|
+
}
|
|
421
|
+
return ladder
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// matchCall returns a call to the member's `_ui<index>` matcher, declaring the
|
|
425
|
+
// matcher on first request. The index is registered before the body is rendered
|
|
426
|
+
// so a recursive member refers to its own matcher instead of recursing forever
|
|
427
|
+
// at generation time.
|
|
428
|
+
func (g *compareEqualProgrammerGenerator) matchCall(object *schemametadata.MetadataObjectType, v string) string {
|
|
429
|
+
name := fmt.Sprintf("_ui%d", object.Index)
|
|
430
|
+
if g.MatcherIndex[object.Index] == false {
|
|
431
|
+
g.MatcherIndex[object.Index] = true
|
|
432
|
+
g.Matchers = append(g.Matchers, fmt.Sprintf("const %s = (v) => %s;", name, g.matchObject(object, "v")))
|
|
433
|
+
}
|
|
434
|
+
return fmt.Sprintf("%s(%s)", name, g.wrap(v))
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// matchObject renders the structural is-check of one object member: every
|
|
438
|
+
// declared regular key must hold a value of its declared type (an optional key
|
|
439
|
+
// may be absent), and every extra key a dynamic index signature declares must
|
|
440
|
+
// hold a value of the signature's type. It mirrors the `_io` checkers `is`
|
|
441
|
+
// emits, at the abstraction level the rest of this programmer works at — shape
|
|
442
|
+
// and typeof, not the value constraints (`typia.tags.*`, template patterns)
|
|
443
|
+
// `compare` deliberately ignores.
|
|
444
|
+
func (g *compareEqualProgrammerGenerator) matchObject(object *schemametadata.MetadataObjectType, v string) string {
|
|
445
|
+
checks := []string{}
|
|
446
|
+
regularKeys := []string{}
|
|
447
|
+
dynamic := []*schemametadata.MetadataProperty{}
|
|
448
|
+
for _, property := range object.Properties {
|
|
449
|
+
if compareProgrammer_isMethod(property) {
|
|
450
|
+
continue // methods carry no comparable data, so they do not route either
|
|
451
|
+
}
|
|
452
|
+
if sole := property.Key.GetSoleLiteral(); sole != nil {
|
|
453
|
+
regularKeys = append(regularKeys, *sole)
|
|
454
|
+
checks = append(checks, g.matchSlot(property.Value, g.property(v, *sole)))
|
|
455
|
+
} else {
|
|
456
|
+
dynamic = append(dynamic, property)
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
if len(dynamic) != 0 {
|
|
460
|
+
key := g.local("key")
|
|
461
|
+
regularCheck := compareEqualProgrammer_regularKeyCheck(regularKeys)
|
|
462
|
+
conditions := []string{}
|
|
463
|
+
for _, property := range dynamic {
|
|
464
|
+
conditions = append(conditions, g.and(g.dynamicKey(property.Key, key), g.matchSlot(property.Value, g.index(v, key))))
|
|
465
|
+
}
|
|
466
|
+
checks = append(checks, fmt.Sprintf("Object.keys(%s).every((%s) => %s)", g.wrap(v), key, g.or(regularCheck(key), g.or(conditions...))))
|
|
467
|
+
}
|
|
468
|
+
return g.and(checks...)
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
// matchSlot renders the is-check of a value slot — an object property or a tuple
|
|
472
|
+
// element — allowing the slot to be absent when it is optional.
|
|
473
|
+
func (g *compareEqualProgrammerGenerator) matchSlot(metadata *schemametadata.MetadataSchema, v string) string {
|
|
474
|
+
check := g.match(metadata, v)
|
|
475
|
+
if metadata != nil && metadata.IsRequired() == false {
|
|
476
|
+
return g.or(g.same(v, "undefined"), check)
|
|
477
|
+
}
|
|
478
|
+
return check
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
// match renders the structural is-check of one metadata schema as the OR of its
|
|
482
|
+
// buckets, the same bucket walk `schema` compares over. An unconstrained bucket
|
|
483
|
+
// (anything the compare feature already rejects, or a bucket carrying no shape
|
|
484
|
+
// to test) renders as "true", which keeps the ladder's first-match order the
|
|
485
|
+
// deciding factor exactly as it is in `is`.
|
|
486
|
+
func (g *compareEqualProgrammerGenerator) match(metadata *schemametadata.MetadataSchema, v string) string {
|
|
487
|
+
if metadata == nil {
|
|
488
|
+
return "true"
|
|
489
|
+
}
|
|
490
|
+
metadata = schemametadata.MetadataSchema_unalias(metadata)
|
|
491
|
+
if metadata.Any {
|
|
492
|
+
return "true"
|
|
493
|
+
}
|
|
494
|
+
branches := []string{}
|
|
495
|
+
if metadata.Nullable {
|
|
496
|
+
branches = append(branches, g.same(v, "null"))
|
|
497
|
+
}
|
|
498
|
+
for _, constant := range metadata.Constants {
|
|
499
|
+
for _, value := range constant.Values {
|
|
500
|
+
branches = append(branches, g.same(v, compareEqualProgrammer_literal(value.Value, constant.Type)))
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
for _, atomic := range metadata.Atomics {
|
|
504
|
+
branches = append(branches, g.typeof(v, atomic.Type))
|
|
505
|
+
}
|
|
506
|
+
if len(metadata.Templates) != 0 {
|
|
507
|
+
branches = append(branches, g.typeof(v, "string"))
|
|
508
|
+
}
|
|
509
|
+
if len(metadata.Functions) != 0 {
|
|
510
|
+
branches = append(branches, g.typeof(v, "function"))
|
|
511
|
+
}
|
|
512
|
+
for _, native := range metadata.Natives {
|
|
513
|
+
branches = append(branches, g.instanceof(v, native.Name))
|
|
514
|
+
}
|
|
515
|
+
for _, tuple := range metadata.Tuples {
|
|
516
|
+
branches = append(branches, g.matchTuple(tuple.Type, v))
|
|
517
|
+
}
|
|
518
|
+
for _, array := range metadata.Arrays {
|
|
519
|
+
elem := g.local("elem")
|
|
520
|
+
branches = append(branches, g.and(g.isArray(v), fmt.Sprintf("%s.every((%s) => %s)", g.wrap(v), elem, g.match(array.Type.Value, elem))))
|
|
521
|
+
}
|
|
522
|
+
if len(metadata.Objects) != 0 {
|
|
523
|
+
calls := []string{}
|
|
524
|
+
for _, object := range metadata.Objects {
|
|
525
|
+
calls = append(calls, g.matchCall(object.Type, v))
|
|
526
|
+
}
|
|
527
|
+
branches = append(branches, g.and(g.isObject(v), g.or(calls...)))
|
|
528
|
+
}
|
|
529
|
+
for _, alias := range metadata.Aliases {
|
|
530
|
+
branches = append(branches, g.match(alias.Type.Value, v))
|
|
531
|
+
}
|
|
532
|
+
if metadata.Escaped != nil {
|
|
533
|
+
branches = append(branches, g.match(metadata.Escaped.Original, v))
|
|
534
|
+
}
|
|
535
|
+
if metadata.Rest != nil {
|
|
536
|
+
branches = append(branches, g.match(metadata.Rest, v))
|
|
537
|
+
}
|
|
538
|
+
if len(branches) == 0 {
|
|
539
|
+
return "true"
|
|
540
|
+
}
|
|
541
|
+
return g.or(branches...)
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
// matchTuple renders the is-check of a tuple: the array gate, the length range
|
|
545
|
+
// an omitted optional trailing element makes legal (the same range `tupleInline`
|
|
546
|
+
// compares over), and each element's own check.
|
|
547
|
+
func (g *compareEqualProgrammerGenerator) matchTuple(tuple *schemametadata.MetadataTupleType, v string) string {
|
|
548
|
+
fixed := len(tuple.Elements)
|
|
549
|
+
var rest *schemametadata.MetadataSchema
|
|
550
|
+
if fixed != 0 && tuple.Elements[fixed-1].Rest != nil {
|
|
551
|
+
rest = tuple.Elements[fixed-1].Rest
|
|
552
|
+
fixed--
|
|
553
|
+
}
|
|
554
|
+
checks := []string{g.isArray(v)}
|
|
555
|
+
length := g.access(v, "length")
|
|
556
|
+
if rest == nil {
|
|
557
|
+
required := 0
|
|
558
|
+
allRequired := true
|
|
559
|
+
for i := 0; i < fixed; i++ {
|
|
560
|
+
if tuple.Elements[i].Optional {
|
|
561
|
+
allRequired = false
|
|
562
|
+
} else {
|
|
563
|
+
required++
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
if allRequired {
|
|
567
|
+
checks = append(checks, g.same(length, strconv.Itoa(fixed)))
|
|
568
|
+
} else {
|
|
569
|
+
checks = append(checks, fmt.Sprintf("%d <= %s && %d >= %s", required, length, fixed, length))
|
|
570
|
+
}
|
|
571
|
+
} else {
|
|
572
|
+
checks = append(checks, fmt.Sprintf("%s >= %d", length, fixed))
|
|
573
|
+
}
|
|
574
|
+
for i := 0; i < fixed; i++ {
|
|
575
|
+
checks = append(checks, g.matchSlot(tuple.Elements[i], g.index(v, strconv.Itoa(i))))
|
|
576
|
+
}
|
|
577
|
+
if rest != nil {
|
|
578
|
+
elem := g.local("elem")
|
|
579
|
+
checks = append(checks, fmt.Sprintf("%s.slice(%d).every((%s) => %s)", g.wrap(v), fixed, elem, g.match(rest, elem)))
|
|
580
|
+
}
|
|
581
|
+
return g.and(checks...)
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
// discriminant renders the routing predicate for one specialized union member,
|
|
585
|
+
// matching how `is` decides membership: presence (`v[key] !== undefined`) for a
|
|
586
|
+
// key unique to this member, or a value check (literal equality for constants,
|
|
587
|
+
// typeof for atomics/templates) for a shared key whose value distinguishes it.
|
|
588
|
+
// It returns ok=false for any discriminant value it cannot render as such a
|
|
589
|
+
// check, so the caller falls back rather than emit a weaker predicate.
|
|
590
|
+
func (g *compareEqualProgrammerGenerator) discriminant(spec nativehelpers.UnionPredicator_ISpecialized, v string) (string, bool) {
|
|
591
|
+
sole := spec.Property.Key.GetSoleLiteral()
|
|
592
|
+
if sole == nil {
|
|
593
|
+
return "", false
|
|
594
|
+
}
|
|
595
|
+
access := g.property(v, *sole)
|
|
596
|
+
if spec.Neighbor == false {
|
|
597
|
+
return fmt.Sprintf("%s !== undefined", g.wrap(access)), true
|
|
598
|
+
}
|
|
599
|
+
meta := schemametadata.MetadataSchema_unalias(spec.Property.Value)
|
|
600
|
+
if meta == nil || meta.Any {
|
|
601
|
+
return "", false
|
|
602
|
+
}
|
|
603
|
+
if len(meta.Objects) != 0 || len(meta.Arrays) != 0 || len(meta.Tuples) != 0 ||
|
|
604
|
+
len(meta.Natives) != 0 || len(meta.Sets) != 0 || len(meta.Maps) != 0 ||
|
|
605
|
+
len(meta.Aliases) != 0 || len(meta.Functions) != 0 || meta.Escaped != nil || meta.Rest != nil {
|
|
606
|
+
return "", false
|
|
607
|
+
}
|
|
608
|
+
checks := []string{}
|
|
609
|
+
if meta.Nullable {
|
|
610
|
+
// A nullable discriminant (e.g. `type: "a" | null`) routes a null value to
|
|
611
|
+
// this member exactly as `is` does, so `equals(null-arm, null-arm)` stays
|
|
612
|
+
// reflexive rather than falling through to no member.
|
|
613
|
+
checks = append(checks, g.same(access, "null"))
|
|
614
|
+
}
|
|
615
|
+
for _, constant := range meta.Constants {
|
|
616
|
+
for _, value := range constant.Values {
|
|
617
|
+
checks = append(checks, g.same(access, compareEqualProgrammer_literal(value.Value, constant.Type)))
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
for _, atomic := range meta.Atomics {
|
|
621
|
+
checks = append(checks, g.typeof(access, atomic.Type))
|
|
622
|
+
}
|
|
623
|
+
if len(meta.Templates) != 0 {
|
|
624
|
+
checks = append(checks, g.typeof(access, "string"))
|
|
625
|
+
}
|
|
626
|
+
if len(checks) == 0 {
|
|
627
|
+
return "", false
|
|
628
|
+
}
|
|
629
|
+
return g.or(checks...), true
|
|
630
|
+
}
|
|
631
|
+
|
|
259
632
|
func (g *compareEqualProgrammerGenerator) arrayCall(array *schemametadata.MetadataArrayType, x string, y string) string {
|
|
260
633
|
index := 0
|
|
261
634
|
if array.Index != nil {
|
|
@@ -409,6 +782,21 @@ func (g *compareEqualProgrammerGenerator) objectGuard(x string, y string) string
|
|
|
409
782
|
return g.and(g.isObject(x), g.isObject(y))
|
|
410
783
|
}
|
|
411
784
|
|
|
785
|
+
// notNatives builds "neither x nor y is one of the union's native instances",
|
|
786
|
+
// so the object branch never claims a value a native branch owns. Empty when
|
|
787
|
+
// the union declares no native, keeping the object-only output unchanged.
|
|
788
|
+
func (g *compareEqualProgrammerGenerator) notNatives(natives []*schemametadata.MetadataNative, x string, y string) string {
|
|
789
|
+
if len(natives) == 0 {
|
|
790
|
+
return ""
|
|
791
|
+
}
|
|
792
|
+
checks := []string{}
|
|
793
|
+
for _, native := range natives {
|
|
794
|
+
checks = append(checks, "!"+g.wrap(g.instanceof(x, native.Name)))
|
|
795
|
+
checks = append(checks, "!"+g.wrap(g.instanceof(y, native.Name)))
|
|
796
|
+
}
|
|
797
|
+
return g.and(checks...)
|
|
798
|
+
}
|
|
799
|
+
|
|
412
800
|
func (g *compareEqualProgrammerGenerator) isObject(input string) string {
|
|
413
801
|
return fmt.Sprintf("typeof %s === \"object\" && %s !== null && !Array.isArray(%s)", g.wrap(input), g.wrap(input), g.wrap(input))
|
|
414
802
|
}
|
|
@@ -219,9 +219,11 @@ func (g *compareLessProgrammerGenerator) core(metadata *schemametadata.MetadataS
|
|
|
219
219
|
}
|
|
220
220
|
|
|
221
221
|
// primitive renders the scalar three-way comparator (works for number, string,
|
|
222
|
-
// boolean and bigint via the relational operators).
|
|
222
|
+
// boolean and bigint via the relational operators). Self-inequality detects NaN
|
|
223
|
+
// without coercing other scalar types and places it after every ordinary number.
|
|
223
224
|
func (g *compareLessProgrammerGenerator) primitive(x string, y string) string {
|
|
224
|
-
return fmt.Sprintf("(%s < %s ? -1 : %s > %s ? 1 : 0)",
|
|
225
|
+
return fmt.Sprintf("(%s !== %s ? (%s !== %s ? 0 : 1) : %s !== %s ? -1 : %s < %s ? -1 : %s > %s ? 1 : 0)",
|
|
226
|
+
g.wrap(x), g.wrap(x), g.wrap(y), g.wrap(y), g.wrap(y), g.wrap(y), g.wrap(x), g.wrap(y), g.wrap(x), g.wrap(y))
|
|
225
227
|
}
|
|
226
228
|
|
|
227
229
|
func (g *compareLessProgrammerGenerator) native(name string, x string, y string) string {
|