├── .ameba.yml ├── .gitattributes ├── .github ├── dependabot.yml └── workflows │ ├── build.yml │ ├── cd.yml │ ├── ci-base.yml │ ├── ci-nightly.yml │ └── ci.yml ├── .gitignore ├── .tool-versions ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── benchmark └── benchmark_core_parsing.cr ├── core ├── mint.json ├── source │ ├── AnimationFrame.mint │ ├── Array.mint │ ├── ArrayBuffer.mint │ ├── Base64.mint │ ├── Bool.mint │ ├── CSV.mint │ ├── Clipboard.mint │ ├── Console.mint │ ├── Debug.mint │ ├── Dom.mint │ ├── Dom │ │ └── Dimensions.mint │ ├── File.mint │ ├── FileSize.mint │ ├── FormData.mint │ ├── Function.mint │ ├── Html.Portals.Body.mint │ ├── Html.Portals.Head.mint │ ├── Html.mint │ ├── Html │ │ ├── DataTransfer.mint │ │ └── Event.mint │ ├── Http.mint │ ├── IntersectionObserver.mint │ ├── Json.mint │ ├── Locale.mint │ ├── Map.mint │ ├── Math.mint │ ├── Maybe.mint │ ├── MutationObserver.mint │ ├── Number.mint │ ├── Object │ │ ├── Decode.mint │ │ ├── Encode.mint │ │ └── Error.mint │ ├── Promise.mint │ ├── Provider │ │ ├── AnimationFrame.mint │ │ ├── ElementSize.mint │ │ ├── Intersection.mint │ │ ├── Keyboard.mint │ │ ├── MediaQuery.mint │ │ ├── Mouse.mint │ │ ├── Mutation.mint │ │ ├── OutsideClick.mint │ │ ├── Pointer.mint │ │ ├── Resize.mint │ │ ├── Scroll.mint │ │ ├── Shortcuts.mint │ │ ├── TabFocus.mint │ │ ├── Tick.mint │ │ ├── Url.mint │ │ └── Websocket.mint │ ├── Regexp.mint │ ├── ResizeObserver.mint │ ├── Result.mint │ ├── SearchParams.mint │ ├── Set.mint │ ├── Storage │ │ ├── Common.mint │ │ ├── Local.mint │ │ └── Session.mint │ ├── String.mint │ ├── Test │ │ ├── Context.mint │ │ ├── Html.mint │ │ └── Window.mint │ ├── Time.mint │ ├── Time │ │ ├── Enums.mint │ │ ├── Format.mint │ │ ├── Language.mint │ │ └── Languages │ │ │ ├── English.mint │ │ │ └── Hungarian.mint │ ├── Timer.mint │ ├── Uid.mint │ ├── Url.mint │ ├── Validation.mint │ ├── WebSocket.mint │ └── Window.mint └── tests │ ├── .env │ ├── mint.json │ └── tests │ ├── Array.mint │ ├── ArrayBuffer.mint │ ├── Base64.mint │ ├── Bool.mint │ ├── CSV.mint │ ├── Case.mint │ ├── Connect.mint │ ├── Console.mint │ ├── Constant.mint │ ├── Css.mint │ ├── Decoding.mint │ ├── Defer.mint │ ├── Destructuring.mint │ ├── Directives.mint │ ├── Dom.mint │ ├── Dom │ └── Dimensions.mint │ ├── Encoding.mint │ ├── Env.mint │ ├── FieldAccess.mint │ ├── File.mint │ ├── FileSize.mint │ ├── FormData.mint │ ├── Function.mint │ ├── GlobalComponent.mint │ ├── HereDocuments.mint │ ├── Html.mint │ ├── Html │ ├── DataTransfer.mint │ ├── Event.mint │ └── Portals │ │ └── Body.mint │ ├── Http.mint │ ├── Json.mint │ ├── Locale.mint │ ├── Map.mint │ ├── Math.mint │ ├── Maybe.mint │ ├── Number.mint │ ├── Object │ ├── Decode.mint │ └── Encode.mint │ ├── Pipe.mint │ ├── Promise.mint │ ├── Provider │ ├── AnimationFrame.mint │ ├── Keyboard.mint │ ├── Mouse.mint │ ├── Scroll.mint │ └── Tick.mint │ ├── Regexp.mint │ ├── Result.mint │ ├── SearchParams.mint │ ├── Set.mint │ ├── Storage │ ├── Local.mint │ └── Session.mint │ ├── String.mint │ ├── Test.mint │ ├── Time.mint │ ├── Time │ └── Format.mint │ ├── Timer.mint │ ├── Uid.mint │ ├── Url.mint │ ├── Validation.mint │ └── Window.mint ├── docker-compose.yml ├── documentation ├── Brand │ ├── logo.svg │ ├── logomark-16.svg │ ├── logomark-animated.svg │ ├── logomark.svg │ └── logotype.svg ├── Core │ ├── Conventions │ │ ├── Module.md │ │ ├── Naming.md │ │ └── Testing.md │ └── Time.md └── Language │ └── Locale.md ├── runtime ├── Makefile ├── index.js ├── index_testing.js ├── package.json ├── src │ ├── debug.js │ ├── decoders.js │ ├── encoders.js │ ├── equality.js │ ├── normalize_event.js │ ├── pattern_matching.js │ ├── portals.js │ ├── program.js │ ├── provider.js │ ├── styles.js │ ├── symbols.js │ ├── testing.js │ ├── translate.js │ ├── utilities.js │ └── variant.js ├── tests │ ├── debug.test.js │ ├── decoders.test.js │ ├── encoders.test.js │ ├── equality.test.js │ ├── normalize_event.test.js │ ├── provider.test.js │ ├── styles.test.js │ ├── translate.test.js │ ├── utilities.test.js │ └── variant.test.js ├── vite.config.mjs ├── yarn-error.log └── yarn.lock ├── shard.lock ├── shard.yml ├── spec ├── ast │ └── node_spec.cr ├── compilers │ ├── access │ ├── access_deep │ ├── argument │ ├── argument_with_default │ ├── argument_with_default_inline_function │ ├── array_literal │ ├── await_inline_function │ ├── block │ ├── block_with_await │ ├── block_with_early_return │ ├── block_with_early_return_await │ ├── block_with_tuple_destructuring │ ├── bool_literal_false │ ├── bool_literal_true │ ├── bracket_access │ ├── builtin │ ├── bundling │ ├── call_captured │ ├── call_labelled │ ├── call_labelled_captured │ ├── case │ ├── case_await │ ├── case_empty │ ├── case_or │ ├── case_with_array_destructuring │ ├── case_with_nested_tuple_destructuring │ ├── case_with_tuple_destructuring │ ├── case_with_tuple_destructuring_bool │ ├── case_with_type_destructuring │ ├── component │ ├── component_async │ ├── component_async_2 │ ├── component_async_3 │ ├── component_async_4 │ ├── component_async_5 │ ├── component_children │ ├── component_global │ ├── component_instance_access │ ├── component_instance_access_2 │ ├── component_instance_access_ref │ ├── component_namespaced │ ├── component_namespaced_with_style │ ├── component_readonly │ ├── component_with_provider │ ├── component_with_provider_and_lifecycle_functions │ ├── component_with_provider_and_store │ ├── constant_component │ ├── constant_global_component │ ├── constant_module │ ├── constant_store │ ├── constant_store_exposed │ ├── css_definition │ ├── css_font_face │ ├── css_font_face_with_quotes │ ├── css_keyframes │ ├── css_media │ ├── css_media_with_if │ ├── css_selector │ ├── css_selector_multiple │ ├── css_string │ ├── css_supports │ ├── css_with_ands │ ├── css_with_arguments │ ├── css_with_case │ ├── css_with_else_if │ ├── css_with_if │ ├── css_with_if_and_case │ ├── css_with_if_same_condition │ ├── css_with_if_variables │ ├── css_with_if_with_interpolation │ ├── dbg │ ├── dbg_as_function │ ├── dbg_bang │ ├── dce_remove_component │ ├── dce_remove_component_async │ ├── dce_remove_component_computed_property │ ├── dce_remove_component_function │ ├── dce_remove_enum │ ├── dce_remove_module │ ├── dce_remove_module_function │ ├── dce_remove_provider │ ├── dce_remove_store │ ├── dce_style │ ├── decode │ ├── decode_function │ ├── decode_map │ ├── decode_tuple │ ├── decode_type │ ├── decoder │ ├── defer │ ├── defer_2 │ ├── destructuring │ ├── destructuring_record │ ├── directives │ │ ├── asset │ │ ├── asset-absolute │ │ ├── format │ │ ├── highlight │ │ ├── highlight-comments-multiple │ │ ├── highlight-file │ │ ├── highlight-file-absolute │ │ ├── inline │ │ ├── inline-absolute │ │ ├── svg │ │ └── svg-absolute │ ├── encode │ ├── encode_in_async │ ├── encode_nested │ ├── encode_no_record │ ├── encode_type │ ├── encode_with_mapping │ ├── encoder_and_decoder │ ├── env │ ├── field │ ├── field_access │ ├── for │ ├── for_with_destructuring │ ├── for_with_index │ ├── for_with_index_2 │ ├── function │ ├── function_call_simple │ ├── function_call_with_arguments │ ├── get │ ├── here_doc_markdown │ ├── here_doc_markdown_escape │ ├── here_doc_markdown_in_markdown │ ├── here_doc_markdown_with_code_block │ ├── here_doc_markdown_with_code_block_interpolation │ ├── here_doc_markdown_with_code_block_interpolation_highlight │ ├── here_doc_markdown_with_code_block_multiline │ ├── here_doc_markdown_with_html_interpolation │ ├── here_doc_markdown_with_inline_code │ ├── here_doc_markdown_with_interpolation │ ├── here_doc_new_line_char │ ├── here_doc_with_interpolation │ ├── here_doc_without_indentation │ ├── html_attribute_class │ ├── html_attribute_class_with_style │ ├── html_attribute_html_fragment │ ├── html_attribute_readonly │ ├── html_attribute_ref │ ├── html_attribute_simple │ ├── html_attribute_with_expression │ ├── html_component │ ├── html_fragment │ ├── html_fragment_empty │ ├── html_with_custom_style │ ├── html_with_multiple_styles │ ├── html_with_multiple_styles_and_parameters │ ├── html_with_multiple_styles_and_parameters_2 │ ├── html_with_pseudos │ ├── html_with_string_style │ ├── html_with_style │ ├── html_with_style_and_custom_style │ ├── if │ ├── if_let │ ├── if_let_await │ ├── if_without_else_array │ ├── if_without_else_promise │ ├── if_without_else_string │ ├── indirect_connect │ ├── inline_function │ ├── inline_function_recursive │ ├── inline_function_with_arguments │ ├── js │ ├── js_with_double_interpolation │ ├── js_with_interpolation │ ├── locale_key │ ├── map │ ├── module │ ├── module_access │ ├── module_access_get │ ├── module_access_subscriptions │ ├── module_call │ ├── module_call_piped │ ├── next_call │ ├── next_call_empty │ ├── number_literal_negative │ ├── number_literal_simple │ ├── number_literal_with_decimal │ ├── operation_chained │ ├── operation_or │ ├── operation_simple │ ├── parenthesized_expression │ ├── pipe │ ├── pipe_await │ ├── pipe_captured │ ├── property │ ├── property_without_default │ ├── provider_with_items │ ├── record │ ├── record_update │ ├── regexp_literal │ ├── serialization │ ├── signal │ ├── state │ ├── state_setter │ ├── statement │ ├── store │ ├── store_with_get │ ├── string_literal_broken │ ├── string_literal_escaped │ ├── string_literal_simple │ ├── string_literal_with_backtick │ ├── string_literal_with_escaped_interpolation │ ├── string_literal_with_interpolation │ ├── string_literal_with_interpolation_and_js_iterpolation │ ├── string_literal_with_interpolation_of_number │ ├── string_literal_with_js_iterpolation │ ├── style_with_argument │ ├── style_with_default_argument │ ├── test │ ├── test_with_global_component │ ├── test_with_reference │ ├── test_with_reference_component │ ├── tuple_literal │ ├── type │ ├── type_with_variants │ ├── unary_minus │ ├── variable_argument │ ├── variable_component_function │ ├── variable_component_get │ ├── variable_component_property │ ├── variable_module_function │ └── void ├── compilers_spec.cr ├── documentation_generator_spec.cr ├── documentation_generators │ ├── module │ ├── provider │ ├── store │ └── type ├── errors │ ├── access_expected_field │ ├── access_expected_field_2 │ ├── access_field_not_found │ ├── access_not_record │ ├── argument_expected_colon │ ├── argument_expected_default_value │ ├── argument_expected_type │ ├── array_destructuring_expected_closing_bracket │ ├── array_expected_closing_bracket │ ├── array_expected_type_or_variable │ ├── array_not_matches │ ├── array_not_matches_defined_type │ ├── asset_directive_expected_closing_parenthesis │ ├── asset_directive_expected_file │ ├── asset_directive_expected_opening_parenthesis │ ├── asset_directive_expected_path │ ├── block_no_expressions │ ├── bracket_access_expected_closing_bracket │ ├── bracket_access_expected_index │ ├── bracket_access_index_not_number │ ├── bracket_access_invalid_tuple │ ├── bracket_access_not_accessible │ ├── call_argument_size_mismatch │ ├── call_argument_type_mismatch │ ├── call_expected_closing_parenthesis │ ├── call_mismatch │ ├── call_not_a_function │ ├── call_not_found_argument │ ├── call_with_mixed_arguments │ ├── case_branch_expected_expression │ ├── case_branch_not_matches │ ├── case_expected_branches │ ├── case_expected_closing_bracket │ ├── case_expected_closing_parenthesis │ ├── case_expected_condition │ ├── case_expected_opening_bracket │ ├── case_not_exhaustive │ ├── case_unnecessary │ ├── component_expected_body │ ├── component_expected_closing_bracket │ ├── component_expected_name │ ├── component_expected_opening_bracket │ ├── component_exposed_name_conflict │ ├── component_lifecycle_function_mismatch │ ├── component_main_properties │ ├── component_multiple_exposed │ ├── component_multiple_providers │ ├── component_multiple_stores │ ├── component_no_render_function │ ├── component_reference_name_conflict │ ├── component_render_function_mismatch │ ├── component_style_name_conflict │ ├── connect_expected_closing_bracket │ ├── connect_expected_exposing │ ├── connect_expected_keys │ ├── connect_expected_opening_bracket │ ├── connect_expected_store │ ├── connect_not_found_member │ ├── connect_not_found_store │ ├── connect_variable_expected_as │ ├── constant_expected_equal_sign │ ├── constant_expected_expression │ ├── constant_expected_name │ ├── css_definition_expected_semicolon │ ├── css_definition_expected_semicolon_2 │ ├── css_definition_no_property │ ├── css_definition_type_mismatch │ ├── css_font_face_expected_closing_bracket │ ├── css_font_face_expected_definitions │ ├── css_font_face_expected_opening_bracket │ ├── css_font_face_interpolation │ ├── css_keyframes_expected_closing_bracket │ ├── css_keyframes_expected_name │ ├── css_keyframes_expected_opening_bracket │ ├── css_keyframes_expected_selectors │ ├── css_nested_at_expected_body │ ├── css_nested_at_expected_closing_bracket │ ├── css_nested_at_expected_condition │ ├── css_nested_at_expected_opening_bracket │ ├── css_selector_expected_body │ ├── css_selector_expected_closing_bracket │ ├── decode_complex_type │ ├── decode_expected_as │ ├── decode_expected_object │ ├── decode_expected_subject │ ├── decode_expected_type │ ├── destructuring_multiple_spreads │ ├── destructuring_tuple_mismatch │ ├── destructuring_type_field_missing │ ├── destructuring_type_mismatch │ ├── destructuring_type_missing │ ├── destructuring_type_variant_missing │ ├── emit_no_signal │ ├── emit_type_mismatch │ ├── encode_complex_type │ ├── encode_expected_expression │ ├── entity_name_conflict │ ├── env_expected_name │ ├── env_not_found_variable │ ├── field_access_expected_closing_parenthesis │ ├── field_access_expected_opening_parenthesis │ ├── field_access_expected_type │ ├── field_access_expected_variable │ ├── field_access_field_not_found │ ├── field_access_not_record │ ├── for_array_or_set_arguments_mismatch │ ├── for_condition_type_mismatch │ ├── for_expected_body │ ├── for_expected_closing_bracket │ ├── for_expected_closing_parenthesis │ ├── for_expected_of │ ├── for_expected_opening_bracket │ ├── for_expected_subject │ ├── for_index_mismatch │ ├── for_map_arguments_mismatch │ ├── for_type_mismatch │ ├── format_directive_expected_body │ ├── format_directive_expected_closing_bracket │ ├── format_directive_expected_opening_bracket │ ├── function_argument_conflict │ ├── function_argument_must_have_a_default_value │ ├── function_expected_closing_bracket │ ├── function_expected_closing_parenthesis │ ├── function_expected_expression │ ├── function_expected_name │ ├── function_expected_opening_bracket │ ├── function_expected_type_or_variable │ ├── function_type_mismatch │ ├── get_expected_closing_bracket │ ├── get_expected_expression │ ├── get_expected_name │ ├── get_expected_opening_bracket │ ├── get_expected_type │ ├── get_type_mismatch │ ├── global_name_conflict │ ├── here_doc_expected_end │ ├── here_doc_interpolation_type_mismatch │ ├── here_document_expected_start │ ├── highlight_directive_expected_body │ ├── highlight_directive_expected_closing_bracket │ ├── highlight_directive_expected_opening_bracket │ ├── html_attribute_component_key_type_mismatch │ ├── html_attribute_component_property_type_mismatch │ ├── html_attribute_element_attribute_type_mismatch │ ├── html_attribute_expected_closing_bracket │ ├── html_attribute_expected_equal_sign │ ├── html_attribute_expected_expression │ ├── html_attribute_expected_opening_bracket │ ├── html_attribute_not_found_component_property │ ├── html_component_attribute_required │ ├── html_component_expected_closing_bracket │ ├── html_component_expected_closing_tag │ ├── html_component_expected_reference │ ├── html_component_global_component │ ├── html_component_not_found_component │ ├── html_component_reference_outside_of_component │ ├── html_content_type_mismatch │ ├── html_element_expected_closing_bracket │ ├── html_element_expected_closing_tag │ ├── html_element_expected_reference │ ├── html_element_expected_style │ ├── html_element_ref_forbidden │ ├── html_element_reference_outside_of_component │ ├── html_element_style_outside_of_component │ ├── html_fragment_expected_closing_tag │ ├── html_style_argument_size_mismatch │ ├── html_style_argument_type_mismatch │ ├── html_style_expected_closing_parenthesis │ ├── html_style_not_found │ ├── if_condition_type_mismatch │ ├── if_else_type_mismatch │ ├── if_expected_condition │ ├── if_expected_else_closing_bracket │ ├── if_expected_else_expression │ ├── if_expected_else_opening_bracket │ ├── if_expected_truthy_closing_bracket │ ├── if_expected_truthy_expression │ ├── if_expected_truthy_opening_bracket │ ├── inline_directive_expected_closing_parenthesis │ ├── inline_directive_expected_file │ ├── inline_directive_expected_opening_parenthesis │ ├── inline_directive_expected_path │ ├── inline_function_expected_body │ ├── inline_function_expected_closing_bracket │ ├── inline_function_expected_closing_parenthesis │ ├── inline_function_expected_opening_bracket │ ├── inline_function_expected_type │ ├── inline_function_type_mismatch │ ├── interpolation_expected_closing_bracket │ ├── interpolation_expected_expression │ ├── invalid_self_reference │ ├── locale_expected_closing_bracket │ ├── locale_expected_language │ ├── locale_expected_opening_bracket │ ├── module_expected_body │ ├── module_expected_closing_bracket │ ├── module_expected_name │ ├── module_expected_opening_bracket │ ├── negated_expression_expected_expression │ ├── negated_expression_not_bool │ ├── next_call_expected_fields │ ├── next_call_invalid_invocation │ ├── next_call_state_not_found │ ├── next_call_state_type_mismatch │ ├── number_literal_expected_decimal │ ├── operation_expected_expression │ ├── operation_numeric_type_mismatch │ ├── operation_or_not_maybe_or_result │ ├── operation_or_type_mismatch │ ├── operation_pipe_ambiguous │ ├── operation_plus_type_mismatch │ ├── property_children_default_requried │ ├── property_children_mismatch │ ├── property_expected_default_value │ ├── property_expected_name │ ├── property_expected_type │ ├── property_type_mismatch │ ├── property_type_or_default_needed │ ├── property_with_type_variables │ ├── provider_expeceted_colon │ ├── provider_expected_body │ ├── provider_expected_closing_bracket │ ├── provider_expected_name │ ├── provider_expected_opening_bracket │ ├── provider_expected_subscription │ ├── provider_not_found_subscription │ ├── record_not_found_matching_record_definition │ ├── record_update_expected_closing_bracket │ ├── record_update_expected_fields │ ├── record_update_not_found_key │ ├── record_update_not_updating_record │ ├── record_update_type_mismatch │ ├── record_with_holes │ ├── recursion │ ├── regexp_literal_expected_closing_slash │ ├── route_expected_body │ ├── route_expected_closing_bracket │ ├── route_expected_closing_parenthesis │ ├── route_expected_opening_bracket │ ├── route_param_invalid │ ├── routes_expected_body │ ├── routes_expected_closing_bracket │ ├── routes_expected_opening_bracket │ ├── signal_expected_block │ ├── signal_expected_colon │ ├── signal_expected_name │ ├── signal_expected_type │ ├── signal_type_mismatch │ ├── spread_expected_variable │ ├── state_expected_default_value │ ├── state_expected_equal_sign │ ├── state_expected_name │ ├── state_expected_type │ ├── state_type_mismatch │ ├── statement_last_target │ ├── statement_return_required │ ├── statement_return_type_mismatch │ ├── store_expected_body │ ├── store_expected_closing_bracket │ ├── store_expected_name │ ├── store_expected_opening_bracket │ ├── string_expected_closing_quote │ ├── string_expected_other_string │ ├── string_literal_interpolation_type_mismatch │ ├── style_expected_body │ ├── style_expected_closing_bracket │ ├── style_expected_closing_parenthesis │ ├── style_expected_name │ ├── style_expected_opening_bracket │ ├── suite_expected_body │ ├── suite_expected_closing_bracket │ ├── suite_expected_name │ ├── suite_expected_opening_bracket │ ├── svg_directive_expected_closing_parenthesis │ ├── svg_directive_expected_dimensions │ ├── svg_directive_expected_file │ ├── svg_directive_expected_opening_parenthesis │ ├── svg_directive_expected_path │ ├── svg_directive_expected_svg │ ├── svg_directive_expected_svg_tag │ ├── test_expected_body │ ├── test_expected_closing_bracket │ ├── test_expected_name │ ├── test_expected_opening_bracket │ ├── test_type_mismatch │ ├── translation_mismatch │ ├── translation_missing │ ├── translation_not_translated │ ├── tuple_literal_expected_closing_parenthesis │ ├── type_definition_expected_closing_bracket │ ├── type_definition_expected_closing_parenthesis │ ├── type_definition_expected_name │ ├── type_definition_field_expected_colon │ ├── type_definition_field_expected_mapping │ ├── type_definition_field_expected_type │ ├── type_definition_not_defined_parameter │ ├── type_definition_unused_parameter │ ├── type_destructuring_expected_closing_parenthesis │ ├── type_destructuring_expected_variant │ ├── type_expected_closing_parenthesis │ ├── type_expected_type_or_type_variable │ ├── type_variant_expected_closing_parenthesis │ ├── type_variant_missing │ ├── unary_minus_not_number │ ├── unkown_builtin │ ├── use_condition_mismatch │ ├── use_expected_condition │ ├── use_expected_condition_closing_bracket │ ├── use_expected_condition_opening_bracket │ ├── use_expected_provider │ ├── use_expected_record │ ├── use_not_found_provider │ ├── use_subscription_mismatch │ ├── variable_missing │ └── variable_reserved ├── errors_spec.cr ├── examples │ ├── access │ ├── access_call │ ├── argument │ ├── array_destructuring │ ├── array_literal │ ├── await │ ├── block │ ├── bool_literal │ ├── bracket_access │ ├── builtin │ ├── call │ ├── case │ ├── case_array │ ├── case_or │ ├── case_tuple │ ├── comment │ ├── component │ ├── connect │ ├── constant │ ├── css_definition │ ├── css_font_face │ ├── css_keyframes │ ├── css_nested_at │ ├── css_selector │ ├── decode │ ├── defer │ ├── destructuring │ ├── directives │ │ ├── asset │ │ ├── format │ │ ├── highlight │ │ ├── highlight_file │ │ ├── inline │ │ └── svg │ ├── discard │ ├── emit │ ├── encode │ ├── env │ ├── field_access │ ├── for_expression │ ├── function │ ├── get │ ├── here_document │ ├── html_attribute │ ├── html_component │ ├── html_element │ ├── html_fragment │ ├── html_style │ ├── if │ ├── inline_function │ ├── interpolation │ ├── js │ ├── locale │ ├── map │ ├── module │ ├── negated_expression │ ├── next_call │ ├── number_literal │ ├── operation │ ├── parenthesized_expression │ ├── pipe │ ├── property │ ├── provider │ ├── record │ ├── record_update │ ├── recursion │ ├── regexp_literal │ ├── route │ ├── routes │ ├── self_reference │ ├── signal │ ├── spread │ ├── state │ ├── state_setter │ ├── statement │ ├── store │ ├── string_literal │ ├── style │ ├── suite │ ├── test │ ├── tuple │ ├── type │ ├── type_definition │ ├── type_definition_field │ ├── type_destructuring │ ├── type_variable │ ├── type_variant │ ├── unary_minus │ ├── use │ ├── variable │ └── void ├── examples_spec.cr ├── fixtures │ ├── Test.mint │ ├── data.txt │ ├── icon-no-dimensions │ ├── icon-no-svg-tag │ ├── icon-not-svg │ └── icon.svg ├── formatters │ ├── access │ ├── argument │ ├── array_destructuring │ ├── array_empty │ ├── array_multiple │ ├── array_single │ ├── array_with_comments │ ├── array_with_multi_line_item │ ├── array_with_type │ ├── bool_literal_false │ ├── bool_literal_true │ ├── bracket_access │ ├── call_broken │ ├── case │ ├── case_branch │ ├── case_branch_css_with_brackets │ ├── case_or │ ├── comment │ ├── comment_multiline │ ├── comment_multiple │ ├── comment_multiple_2 │ ├── comment_multiple_3 │ ├── comment_with_code │ ├── component │ ├── component_with_comments │ ├── component_with_items │ ├── connect │ ├── connect_multiline │ ├── constant_component │ ├── constant_module │ ├── constant_provider │ ├── constant_store │ ├── css │ ├── css_keyframes │ ├── css_with_arguments │ ├── css_with_case │ ├── css_with_comments │ ├── css_with_if │ ├── css_with_if_and_else │ ├── css_with_interpolation │ ├── css_with_line_separation │ ├── css_with_multiline_value │ ├── css_with_selector │ ├── dbg │ ├── dbg_with_bang │ ├── decode │ ├── directives │ │ ├── asset │ │ ├── format │ │ ├── highlight-file │ │ ├── inline │ │ └── svg │ ├── env │ ├── field │ ├── field_access │ ├── field_multiline │ ├── field_with_comments │ ├── field_with_if │ ├── font_face │ ├── for │ ├── function │ ├── function_long │ ├── function_without_type │ ├── get │ ├── get_without_type │ ├── here_doc_with_interpolation │ ├── here_doc_without_indentation │ ├── html_attribute │ ├── html_attribute_array │ ├── html_attribute_html_fragment │ ├── html_attribute_multiline │ ├── html_component │ ├── html_content_multiline │ ├── html_element │ ├── html_element_single_line │ ├── html_element_with_comment │ ├── html_fragment │ ├── html_style │ ├── html_with_comments │ ├── if_with_comments │ ├── if_with_else_if │ ├── if_with_else_if_with_comment │ ├── if_with_multiple_conditions │ ├── inline_comment │ ├── inline_function │ ├── inline_function_multiline │ ├── inline_function_with_comments │ ├── js │ ├── js_multiline │ ├── js_multiline_with_backtick │ ├── js_with_backtick │ ├── js_with_duble_interpolation │ ├── js_with_type │ ├── locale │ ├── locale_key │ ├── map_multiline │ ├── map_with_type │ ├── module │ ├── module_access │ ├── module_call │ ├── module_call_multiline │ ├── module_call_piped │ ├── module_multiple │ ├── module_with_comments │ ├── negated_expression │ ├── next_call │ ├── next_call_multiline │ ├── number_literal_negative │ ├── number_literal_simple │ ├── number_literal_with_bigdecimals │ ├── number_literal_with_decimals │ ├── operation │ ├── operation_multi_line │ ├── operation_multi_line_with_pipe │ ├── operation_with_comment │ ├── parenthesized_expression │ ├── pipe_with_comment │ ├── property │ ├── property_new_line │ ├── property_without_type │ ├── provider │ ├── provider_with_comments │ ├── provider_with_items │ ├── record_destructuring │ ├── record_multiline │ ├── record_singleline │ ├── record_update_multiline │ ├── record_update_singleline │ ├── record_update_with_comments │ ├── record_with_comments │ ├── regexp_literal │ ├── routes │ ├── routes_await │ ├── routes_broken │ ├── routes_with_comments │ ├── state │ ├── state_without_type │ ├── statement │ ├── statement_with_await │ ├── store │ ├── store_with_comments │ ├── string_literal_escaped │ ├── string_literal_multiline │ ├── string_literal_simple │ ├── string_literal_split │ ├── string_literal_split_with_interpolation │ ├── string_literal_with_interpolation │ ├── style │ ├── suite │ ├── suite_with_comments │ ├── tuple_destructuring │ ├── tuple_multiple │ ├── tuple_with_comments │ ├── type │ ├── type_definition │ ├── type_definition_broken_variant │ ├── type_definition_with_comments │ ├── type_definition_with_new_lines │ ├── type_definition_with_using │ ├── type_record │ ├── type_record_multiline │ ├── type_with_parameters │ ├── unary_minus │ ├── use │ └── void ├── formatting_spec.cr ├── installer │ └── repository_spec.cr ├── language_server │ ├── code_actions │ │ ├── module │ │ └── provider │ ├── completion │ │ ├── function │ │ ├── html_component │ │ ├── html_component_with_snippet_support │ │ └── partial_function │ ├── definition │ │ ├── core_component │ │ ├── location │ │ │ ├── access_array │ │ │ ├── access_call │ │ │ ├── access_record_multiple │ │ │ ├── access_record_single │ │ │ ├── connect │ │ │ ├── connect_variable_constant │ │ │ ├── connect_variable_function │ │ │ ├── connect_variable_get │ │ │ ├── connect_variable_state │ │ │ ├── html_attribute │ │ │ ├── html_component │ │ │ ├── html_style │ │ │ ├── module_access_component_constant │ │ │ ├── module_access_component_function │ │ │ ├── module_access_component_gets │ │ │ ├── module_access_component_name │ │ │ ├── module_access_component_state │ │ │ ├── module_access_module_constant │ │ │ ├── module_access_module_function │ │ │ ├── module_access_module_multiple │ │ │ ├── module_access_module_name │ │ │ ├── module_access_module_name_shared │ │ │ ├── module_access_store_constant │ │ │ ├── module_access_store_function │ │ │ ├── module_access_store_gets │ │ │ ├── module_access_store_name │ │ │ ├── module_access_store_state │ │ │ ├── type_definition │ │ │ ├── type_destructuring_name │ │ │ ├── type_destructuring_option │ │ │ ├── type_record │ │ │ ├── type_type │ │ │ ├── type_variant │ │ │ ├── variable_block_statement_target │ │ │ ├── variable_casebranch_typedestructuring │ │ │ ├── variable_component_connect │ │ │ ├── variable_component_connect_as │ │ │ ├── variable_component_constant │ │ │ ├── variable_component_function │ │ │ ├── variable_component_get │ │ │ ├── variable_component_property │ │ │ ├── variable_component_state │ │ │ ├── variable_for │ │ │ ├── variable_for_argument_stop │ │ │ ├── variable_for_subject │ │ │ ├── variable_function_argument │ │ │ ├── variable_function_argument_stop │ │ │ ├── variable_module_constant │ │ │ ├── variable_nextcall_component │ │ │ ├── variable_nextcall_record │ │ │ ├── variable_nextcall_store │ │ │ ├── variable_nextcall_value │ │ │ ├── variable_provider_constant │ │ │ ├── variable_recordfield_key │ │ │ ├── variable_recordfield_value │ │ │ ├── variable_store_constant │ │ │ ├── variable_store_function │ │ │ ├── variable_store_get │ │ │ ├── variable_store_state │ │ │ └── variable_suite_constant │ │ ├── location_link │ │ │ ├── access_array │ │ │ ├── access_call │ │ │ ├── access_record_multiple │ │ │ ├── access_record_single │ │ │ ├── connect │ │ │ ├── connect_variable_constant │ │ │ ├── connect_variable_function │ │ │ ├── connect_variable_get │ │ │ ├── connect_variable_state │ │ │ ├── enum_id_name │ │ │ ├── enum_id_option │ │ │ ├── html_attribute │ │ │ ├── html_component │ │ │ ├── html_style │ │ │ ├── module_access_component_constant │ │ │ ├── module_access_component_function │ │ │ ├── module_access_component_gets │ │ │ ├── module_access_component_name │ │ │ ├── module_access_component_state │ │ │ ├── module_access_module_constant │ │ │ ├── module_access_module_function │ │ │ ├── module_access_module_multiple │ │ │ ├── module_access_module_name │ │ │ ├── module_access_module_name_shared │ │ │ ├── module_access_store_constant │ │ │ ├── module_access_store_function │ │ │ ├── module_access_store_gets │ │ │ ├── module_access_store_name │ │ │ ├── module_access_store_state │ │ │ ├── type_destructuring_name │ │ │ ├── type_destructuring_option │ │ │ ├── type_enum │ │ │ ├── type_record │ │ │ ├── variable_block_statement_target │ │ │ ├── variable_casebranch_typedestructuring │ │ │ ├── variable_component_connect │ │ │ ├── variable_component_connect_as │ │ │ ├── variable_component_constant │ │ │ ├── variable_component_function │ │ │ ├── variable_component_get │ │ │ ├── variable_component_property │ │ │ ├── variable_component_state │ │ │ ├── variable_for │ │ │ ├── variable_for_argument_stop │ │ │ ├── variable_for_subject │ │ │ ├── variable_function_argument │ │ │ ├── variable_function_argument_stop │ │ │ ├── variable_module_constant │ │ │ ├── variable_nextcall_component │ │ │ ├── variable_nextcall_record │ │ │ ├── variable_nextcall_store │ │ │ ├── variable_nextcall_value │ │ │ ├── variable_provider_constant │ │ │ ├── variable_recordfield_key │ │ │ ├── variable_recordfield_value │ │ │ ├── variable_store_constant │ │ │ ├── variable_store_function │ │ │ ├── variable_store_get │ │ │ ├── variable_store_state │ │ │ └── variable_suite_constant │ │ └── no_definition │ ├── did_change │ ├── did_open │ ├── folding_range │ │ ├── component │ │ ├── component_with_comments │ │ └── module │ ├── formatting │ ├── hover │ │ ├── argument │ │ ├── css_definition │ │ ├── function_component │ │ ├── function_module │ │ ├── function_provider │ │ ├── function_store │ │ ├── get │ │ ├── html_attribute │ │ ├── html_component │ │ ├── html_element │ │ ├── module_access │ │ ├── property │ │ ├── state │ │ ├── statement │ │ ├── string_literal │ │ ├── type_definition │ │ ├── type_destructuring │ │ ├── type_record │ │ ├── type_type │ │ ├── type_variant │ │ └── type_variant_2 │ ├── semantic_tokens │ │ ├── component │ │ └── record │ └── will_save_wait_until ├── language_server_spec.cr ├── lsp │ └── message_parser_spec.cr ├── mint.json ├── mint_json │ ├── application_css_prefix_invalid │ ├── application_display_invalid │ ├── application_display_mismatch │ ├── application_head_invalid │ ├── application_head_not_exists │ ├── application_icon_invalid │ ├── application_icon_not_exists │ ├── application_invalid │ ├── application_invalid_key │ ├── application_meta_invalid │ ├── application_meta_keyword_invalid │ ├── application_meta_keywords_invalid │ ├── application_meta_value_invalid │ ├── application_name │ ├── application_orientation_invalid │ ├── application_orientation_mismatch │ ├── application_theme_color_invalid │ ├── application_title_empty │ ├── application_title_invalid │ ├── dependencies_empty │ ├── dependencies_invalid │ ├── dependency_constraint_bad │ ├── dependency_constraint_invalid │ ├── dependency_invalid │ ├── dependency_invalid_key │ ├── dependency_missing_constraint │ ├── dependency_missing_repository │ ├── dependency_repository_invalid │ ├── formatter_indent_size_invalid │ ├── formatter_invalid │ ├── formatter_invalid_key │ ├── invalid_json │ ├── mint_version_bad │ ├── mint_version_invalid │ ├── mint_version_mismatch │ ├── name_empty │ ├── name_invalid │ ├── root_invalid │ ├── root_invalid_key │ ├── source_directories_empty │ ├── source_directories_invalid │ ├── source_directory_invalid │ ├── source_directory_not_exists │ ├── test_directories_empty │ ├── test_directories_invalid │ ├── test_directory_invalid │ └── test_directory_not_exists ├── mint_json_spec.cr ├── name_pool_spec.cr ├── spec_helper.cr ├── spec_helpers.cr ├── static_documentation_generator_spec.cr ├── static_documentation_generators │ └── module ├── style_builder_spec.cr ├── type_unification_spec.cr ├── utils │ └── markd_vdom_renderer_spec.cr ├── watcher_spec.cr └── workspace_spec.cr ├── spec_cli ├── build_spec.cr ├── docs_spec.cr ├── format_spec.cr ├── init_spec.cr ├── install_spec.cr ├── lint_spec.cr ├── spec_helper.cr ├── start_spec.cr ├── test_spec.cr ├── tool │ ├── clean_spec.cr │ ├── docs_json_spec.cr │ ├── docs_server_spec.cr │ ├── highlight_spec.cr │ └── loc_spec.cr └── version_spec.cr └── src ├── all.cr ├── assets.cr ├── assets ├── css_properties ├── docs │ ├── fonts │ │ ├── fira-code-v22-latin_latin-ext-regular.woff2 │ │ ├── forum-v18-latin_latin-ext-regular.woff2 │ │ ├── noto-sans-v36-latin_latin-ext-300.woff2 │ │ ├── noto-sans-v36-latin_latin-ext-500.woff2 │ │ └── noto-sans-v36-latin_latin-ext-regular.woff2 │ └── style.css ├── error_message │ └── style.css ├── html_tags ├── live-reload.js ├── runtime.js ├── runtime_test.js └── scaffold │ ├── .gitignore │ ├── assets │ ├── bottom-center.png │ ├── bottom-left.png │ ├── bottom-right.png │ ├── favicon.png │ ├── head.html │ ├── logo.svg │ ├── top-center.png │ ├── top-left.png │ └── top-right.png │ ├── source │ ├── Content.mint │ └── Main.mint │ └── tests │ └── Main.mint ├── ast.cr ├── ast ├── access.cr ├── argument.cr ├── array_destructuring.cr ├── array_literal.cr ├── await.cr ├── block.cr ├── bool_literal.cr ├── bracket_access.cr ├── builtin.cr ├── call.cr ├── case.cr ├── case_branch.cr ├── comment.cr ├── commented_expression.cr ├── component.cr ├── connect.cr ├── connect_variable.cr ├── constant.cr ├── css_definition.cr ├── css_font_face.cr ├── css_keyframes.cr ├── css_nested_at.cr ├── css_selector.cr ├── dbg.cr ├── decode.cr ├── defer.cr ├── directives │ ├── file_based.cr │ ├── format.cr │ └── highlight.cr ├── discard.cr ├── emit.cr ├── encode.cr ├── env.cr ├── field.cr ├── field_access.cr ├── for.cr ├── function.cr ├── get.cr ├── here_document.cr ├── html_attribute.cr ├── html_component.cr ├── html_element.cr ├── html_fragment.cr ├── html_style.cr ├── id.cr ├── if.cr ├── inline_function.cr ├── interpolation.cr ├── js.cr ├── locale.cr ├── locale_key.cr ├── map.cr ├── map_field.cr ├── module.cr ├── negated_expression.cr ├── next_call.cr ├── node.cr ├── number_literal.cr ├── operation.cr ├── parenthesized_expression.cr ├── pipe.cr ├── property.cr ├── provider.cr ├── record.cr ├── record_destructuring.cr ├── record_update.cr ├── regexp_literal.cr ├── return_call.cr ├── route.cr ├── routes.cr ├── signal.cr ├── spread.cr ├── state.cr ├── state_setter.cr ├── statement.cr ├── store.cr ├── string_literal.cr ├── style.cr ├── suite.cr ├── test.cr ├── tuple_destructuring.cr ├── tuple_literal.cr ├── type.cr ├── type_definition.cr ├── type_definition_field.cr ├── type_destructuring.cr ├── type_variable.cr ├── type_variant.cr ├── unary_minus.cr ├── use.cr └── variable.cr ├── bundler.cr ├── cli.cr ├── command.cr ├── commands ├── build.cr ├── docs.cr ├── format.cr ├── init.cr ├── install.cr ├── lint.cr ├── start.cr ├── test.cr ├── tool.cr ├── tool │ ├── clean.cr │ ├── docs_json.cr │ ├── docs_server.cr │ ├── highlight.cr │ ├── loc.cr │ ├── ls.cr │ └── ls_web_socket.cr └── version.cr ├── compiler.cr ├── compiler ├── decoder.cr ├── encoder.cr ├── js.cr ├── record.cr └── renderer.cr ├── compilers ├── access.cr ├── argument.cr ├── array_literal.cr ├── await.cr ├── block.cr ├── bool_literal.cr ├── bracket_access.cr ├── builtin.cr ├── call.cr ├── case.cr ├── case_branch.cr ├── commented_expression.cr ├── component.cr ├── constant.cr ├── dbg.cr ├── decode.cr ├── defer.cr ├── destructuring.cr ├── directives │ ├── asset.cr │ ├── format.cr │ ├── highlight.cr │ ├── highlight_file.cr │ ├── inline.cr │ └── svg.cr ├── emit.cr ├── encode.cr ├── env.cr ├── field.cr ├── field_access.cr ├── for_expression.cr ├── function.cr ├── get.cr ├── here_document.cr ├── html_attribute.cr ├── html_component.cr ├── html_element.cr ├── html_fragment.cr ├── if.cr ├── inline_function.cr ├── interpolation.cr ├── js.cr ├── locale_key.cr ├── map.cr ├── map_field.cr ├── module.cr ├── negated_expression.cr ├── next_call.cr ├── number_literal.cr ├── operation.cr ├── parenthesized_expression.cr ├── pipe.cr ├── provider.cr ├── record.cr ├── record_update.cr ├── regexp_literal.cr ├── return_call.cr ├── route.cr ├── signal.cr ├── state.cr ├── state_setter.cr ├── statement.cr ├── store.cr ├── string.cr ├── string_literal.cr ├── suite.cr ├── test.cr ├── tuple_literal.cr ├── type_definition.cr ├── unary_minus.cr └── variable.cr ├── constants.cr ├── core.cr ├── debugger.cr ├── documentation_generator.cr ├── env.cr ├── error_message.cr ├── errorable.cr ├── exhaustiveness_checker.cr ├── ext ├── array.cr ├── dir.cr ├── file.cr ├── libxml.cr └── string.cr ├── formatter.cr ├── formatter ├── processor.cr └── renderer.cr ├── formatters ├── access.cr ├── argument.cr ├── array_destructuring.cr ├── array_literal.cr ├── await.cr ├── block.cr ├── bool_literal.cr ├── bracket_access.cr ├── builtin.cr ├── call.cr ├── case.cr ├── case_branch.cr ├── comment.cr ├── commented_expression.cr ├── component.cr ├── connect.cr ├── connect_variable.cr ├── constant.cr ├── css_definition.cr ├── css_font_face.cr ├── css_keyframes.cr ├── css_nested_at.cr ├── css_selector.cr ├── dbg.cr ├── decode.cr ├── defer.cr ├── directives │ ├── asset.cr │ ├── format.cr │ ├── highlight.cr │ ├── highlight_file.cr │ ├── inline.cr │ └── svg.cr ├── discard.cr ├── emit.cr ├── encode.cr ├── env.cr ├── field.cr ├── field_access.cr ├── for.cr ├── function.cr ├── get.cr ├── here_document.cr ├── html.cr ├── html_attribute.cr ├── html_component.cr ├── html_element.cr ├── html_fragment.cr ├── html_style.cr ├── id.cr ├── if.cr ├── inline_function.cr ├── interpolation.cr ├── js.cr ├── list.cr ├── locale.cr ├── locale_key.cr ├── map.cr ├── map_field.cr ├── module.cr ├── negated_expression.cr ├── next_call.cr ├── number_literal.cr ├── operation.cr ├── parenthesized_expression.cr ├── pipe.cr ├── property.cr ├── provider.cr ├── record.cr ├── record_destructuring.cr ├── record_update.cr ├── regexp_literal.cr ├── return_call.cr ├── route.cr ├── routes.cr ├── signal.cr ├── spread.cr ├── state.cr ├── state_setter.cr ├── statement.cr ├── store.cr ├── string_literal.cr ├── style.cr ├── suite.cr ├── test.cr ├── top_level.cr ├── tuple_destructuring.cr ├── tuple_literal.cr ├── type.cr ├── type_definition.cr ├── type_definition_field.cr ├── type_destructuring.cr ├── type_variable.cr ├── type_variant.cr ├── unary_minus.cr ├── use.cr └── variable.cr ├── helpers.cr ├── installer.cr ├── installer ├── dependency.cr ├── fixed_constraint.cr ├── repository.cr ├── semver.cr └── simple_constraint.cr ├── logger.cr ├── ls ├── README.md ├── code_action.cr ├── code_actions │ ├── module_actions.cr │ └── provider_actions.cr ├── completion.cr ├── completion_item │ ├── argument.cr │ ├── component.cr │ ├── constant.cr │ ├── function.cr │ ├── get.cr │ ├── property.cr │ └── style.cr ├── completion_request.cr ├── completions │ ├── component.cr │ ├── functions.cr │ ├── module.cr │ ├── store.cr │ ├── style.cr │ └── type_definition.cr ├── definition.cr ├── definitions.cr ├── definitions │ ├── access.cr │ ├── connect.cr │ ├── connect_variable.cr │ ├── html_attribute.cr │ ├── html_component.cr │ ├── html_element.cr │ ├── html_style.cr │ ├── id.cr │ ├── type.cr │ ├── type_destructuring.cr │ └── variable.cr ├── did_change.cr ├── did_open.cr ├── exit.cr ├── folding_range.cr ├── formatting.cr ├── hover.cr ├── hover │ ├── access.cr │ ├── argument.cr │ ├── component.cr │ ├── css_definition.cr │ ├── function.cr │ ├── get.cr │ ├── html_attribute.cr │ ├── html_component.cr │ ├── html_element.cr │ ├── property.cr │ ├── state.cr │ ├── statement.cr │ ├── string_literal.cr │ ├── type.cr │ ├── type_definition.cr │ ├── type_destructuring.cr │ └── type_variant.cr ├── initialize.cr ├── sandbox.cr ├── sandbox_reset.cr ├── sandbox_update.cr ├── semantic_tokens.cr ├── server.cr ├── shutdown.cr ├── websocket_server.cr └── will_save_wait_until.cr ├── lsp ├── README.md ├── message_parser.cr ├── protocol │ ├── apply_workspace_edit_params.cr │ ├── client_capabilities.cr │ ├── code_action.cr │ ├── code_action_context.cr │ ├── code_action_options.cr │ ├── code_action_params.cr │ ├── code_action_trigger_kind.cr │ ├── code_description.cr │ ├── code_lens_provider.cr │ ├── color_provider_options.cr │ ├── command.cr │ ├── completion_client_capabilities.cr │ ├── completion_context.cr │ ├── completion_item.cr │ ├── completion_item_kind.cr │ ├── completion_options.cr │ ├── completion_params.cr │ ├── completion_trigger_kind.cr │ ├── create_file.cr │ ├── create_file_options.cr │ ├── definition_client_capabilities.cr │ ├── diagnostic.cr │ ├── diagnostic_related_information.cr │ ├── diagnostic_severity.cr │ ├── diagnostic_tag.cr │ ├── did_change_text_document_params.cr │ ├── did_open_text_document_params.cr │ ├── did_save_text_document_params.cr │ ├── document_formatting_params.cr │ ├── document_link_options.cr │ ├── document_on_type_formatting_options.cr │ ├── error_codes.cr │ ├── execute_command_options.cr │ ├── fold_range_kind.cr │ ├── fold_range_provider_options.cr │ ├── folding_range.cr │ ├── folding_range_params.cr │ ├── formatting_options.cr │ ├── initialize_params.cr │ ├── initialize_result.cr │ ├── location.cr │ ├── location_link.cr │ ├── notification_message.cr │ ├── optional_versioned_text_document_identifier.cr │ ├── position.cr │ ├── range.cr │ ├── rename_options.cr │ ├── request_message.cr │ ├── response_error.cr │ ├── response_message.cr │ ├── save_options.cr │ ├── semantic_tokens_client_capabilities.cr │ ├── semantic_tokens_legend.cr │ ├── semantic_tokens_options.cr │ ├── semantic_tokens_params.cr │ ├── server_capabilities.cr │ ├── signature_help_options.cr │ ├── text_document_client_capabilities.cr │ ├── text_document_content_change_event.cr │ ├── text_document_edit.cr │ ├── text_document_identifier.cr │ ├── text_document_item.cr │ ├── text_document_position_params.cr │ ├── text_document_sync_kind.cr │ ├── text_document_sync_options.cr │ ├── text_edit.cr │ ├── versioned_text_document_identifier.cr │ ├── will_save_text_document_params.cr │ ├── workspace.cr │ ├── workspace_edit.cr │ ├── workspace_folder.cr │ └── workspace_folders.cr └── server.cr ├── mint.cr ├── mint_json.cr ├── mint_json ├── application.cr ├── application │ ├── css_prefix.cr │ ├── display.cr │ ├── head.cr │ ├── icon.cr │ ├── meta.cr │ ├── name.cr │ ├── orientation.cr │ ├── theme_color.cr │ └── title.cr ├── dependencies.cr ├── formatter.cr ├── mint_version.cr ├── name.cr ├── parser.cr ├── root.cr ├── source_directories.cr └── test_directories.cr ├── parser.cr ├── parser ├── file.cr ├── location.cr └── top_level.cr ├── parsers ├── access.cr ├── argument.cr ├── array_destructuring.cr ├── array_literal.cr ├── await.cr ├── base_expression.cr ├── block.cr ├── bool_literal.cr ├── bracket_access.cr ├── builtin.cr ├── call.cr ├── case.cr ├── case_branch.cr ├── comment.cr ├── commented_expression.cr ├── component.cr ├── connect.cr ├── connect_variable.cr ├── constant.cr ├── css_definition.cr ├── css_font_face.cr ├── css_keyframes.cr ├── css_nested_at.cr ├── css_node.cr ├── css_selector.cr ├── css_selector_name.cr ├── dbg.cr ├── decode.cr ├── defer.cr ├── destructuring.cr ├── directives │ ├── asset.cr │ ├── format.cr │ ├── highlight.cr │ ├── highlight_file.cr │ ├── inline.cr │ └── svg.cr ├── discard.cr ├── emit.cr ├── encode.cr ├── env.cr ├── expression.cr ├── field.cr ├── field_access.cr ├── for.cr ├── function.cr ├── get.cr ├── here_document.cr ├── html_attribute.cr ├── html_body.cr ├── html_component.cr ├── html_element.cr ├── html_fragment.cr ├── html_style.cr ├── id.cr ├── if.cr ├── inline_function.cr ├── interpolation.cr ├── js.cr ├── locale.cr ├── locale_key.cr ├── map.cr ├── map_field.cr ├── module.cr ├── negated_expression.cr ├── next_call.cr ├── number_literal.cr ├── operation.cr ├── operator.cr ├── parenthesized_expression.cr ├── pipe.cr ├── property.cr ├── provider.cr ├── record.cr ├── record_destructuring.cr ├── record_update.cr ├── regexp_literal.cr ├── return.cr ├── route.cr ├── routes.cr ├── signal.cr ├── spread.cr ├── state.cr ├── state_setter.cr ├── statement.cr ├── store.cr ├── string_literal.cr ├── style.cr ├── suite.cr ├── test.cr ├── tuple_destructuring.cr ├── tuple_literal.cr ├── type.cr ├── type_definition.cr ├── type_definition_field.cr ├── type_destructuring.cr ├── type_variable.cr ├── type_variant.cr ├── unary_minus.cr ├── use.cr ├── value.cr └── variable.cr ├── reactor.cr ├── references_tracker.cr ├── render └── terminal.cr ├── scaffold.cr ├── scope.cr ├── semantic_tokenizer.cr ├── static_documentation_generator.cr ├── style_builder.cr ├── test_runner.cr ├── test_runner ├── browser.cr ├── documentation_reporter.cr ├── dot_reporter.cr ├── message.cr └── reporter.cr ├── type_checker.cr ├── type_checker ├── artifacts.cr ├── comparer.cr ├── record.cr ├── static_type_signature.cr ├── type.cr └── variable.cr ├── type_checkers ├── access.cr ├── argument.cr ├── arguments.cr ├── array_literal.cr ├── await.cr ├── block.cr ├── bool_literal.cr ├── bracket_access.cr ├── builtin.cr ├── call.cr ├── case.cr ├── case_branch.cr ├── comment.cr ├── commented_expression.cr ├── component.cr ├── connect.cr ├── constant.cr ├── css_definition.cr ├── css_font_face.cr ├── css_keyframes.cr ├── css_nested_at.cr ├── css_selector.cr ├── dbg.cr ├── decode.cr ├── defer.cr ├── destructuring.cr ├── directives │ ├── asset.cr │ ├── format.cr │ ├── highlight.cr │ ├── highlight_file.cr │ ├── inline.cr │ └── svg.cr ├── emit.cr ├── encode.cr ├── env.cr ├── field.cr ├── field_access.cr ├── for_expression.cr ├── function.cr ├── get.cr ├── here_document.cr ├── html_attribute.cr ├── html_component.cr ├── html_content.cr ├── html_element.cr ├── html_fragment.cr ├── html_style.cr ├── if.cr ├── inline_function.cr ├── interpolation.cr ├── js.cr ├── locale.cr ├── locale_key.cr ├── map.cr ├── module.cr ├── negated_expression.cr ├── next_call.cr ├── number_literal.cr ├── operation.cr ├── parenthesized_expression.cr ├── pipe.cr ├── property.cr ├── provider.cr ├── record.cr ├── record_update.cr ├── regexp_literal.cr ├── return_call.cr ├── route.cr ├── routes.cr ├── signal.cr ├── state.cr ├── state_setter.cr ├── statement.cr ├── store.cr ├── string_literal.cr ├── style.cr ├── suite.cr ├── test.cr ├── top_level.cr ├── tuple_literal.cr ├── type.cr ├── type_definition.cr ├── type_definition_field.cr ├── type_variable.cr ├── type_variant.cr ├── unary_minus.cr ├── use.cr └── variable.cr ├── utils ├── artifact_cleaner.cr ├── cors.cr ├── html_builder.cr ├── icon_generator.cr ├── markd_vdom_renderer.cr ├── name_pool.cr ├── server.cr ├── source_files.cr ├── source_map_generator.cr ├── terminal_snippet.cr ├── time_format.cr ├── vlq.cr └── watcher.cr ├── version.cr └── workspace.cr /.ameba.yml: -------------------------------------------------------------------------------- 1 | Documentation/DocumentationAdmonition: 2 | Enabled: false 3 | 4 | Metrics/CyclomaticComplexity: 5 | Enabled: false 6 | 7 | Lint/NotNil: 8 | Enabled: false 9 | 10 | Lint/Typos: 11 | Enabled: false 12 | 13 | Lint/UselessAssign: 14 | ExcludeTypeDeclarations: true 15 | 16 | Lint/SpecFilename: 17 | Excluded: 18 | - spec/spec_helpers.cr 19 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | src/assets/* linguist-vendored 2 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | # Maintain dependencies for GitHub Actions 4 | - package-ecosystem: github-actions 5 | directory: / 6 | schedule: 7 | interval: daily 8 | -------------------------------------------------------------------------------- /.github/workflows/ci-nightly.yml: -------------------------------------------------------------------------------- 1 | name: CI Nightly 2 | 3 | on: 4 | schedule: 5 | - cron: "0 6 * * 1" 6 | workflow_dispatch: 7 | 8 | jobs: 9 | test: 10 | uses: ./.github/workflows/ci-base.yml 11 | with: 12 | crystal-version: nightly 13 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | pull_request: 7 | types: [opened, synchronize, reopened] 8 | release: 9 | types: [published] 10 | workflow_dispatch: 11 | 12 | jobs: 13 | test: 14 | uses: ./.github/workflows/ci-base.yml 15 | with: 16 | crystal-version: latest 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /docs/ 2 | /lib/ 3 | /bin/ 4 | /.shards/ 5 | .vscode 6 | node_modules 7 | coverage 8 | .aider* 9 | .env 10 | -------------------------------------------------------------------------------- /.tool-versions: -------------------------------------------------------------------------------- 1 | crystal 1.15.0 2 | mint 0.20.0 3 | nodejs 20.10.0 4 | yarn 1.22.19 5 | -------------------------------------------------------------------------------- /benchmark/benchmark_core_parsing.cr: -------------------------------------------------------------------------------- 1 | require "benchmark" 2 | require "../src/all" 3 | 4 | module Mint 5 | Benchmark.ips(warmup: 4.seconds, calculation: 10.seconds) do |x| 6 | x.report("Core parsing") do 7 | Core.files.reduce(Ast.new) do |memo, file| 8 | Parser.parse(file.read, file.path).try do |ast| 9 | memo.merge(ast) 10 | end 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /core/mint.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "core", 3 | "source-directories": [ 4 | "source" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /core/source/Bool.mint: -------------------------------------------------------------------------------- 1 | /* This module provides functions for working with boolean values. */ 2 | module Bool { 3 | /* 4 | Converts a boolean to a string. 5 | 6 | Bool.toString(true) == "true" 7 | Bool.toString(false) == "false" 8 | */ 9 | fun toString (item : Bool) : String { 10 | `#{item}.toString()` 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /core/source/Object/Error.mint: -------------------------------------------------------------------------------- 1 | /* This module provides functions for working with `Object.Error` type. */ 2 | module Object.Error { 3 | /* Formats the error as string. */ 4 | fun toString (error : Object.Error) : String { 5 | `#{error}.toString()` 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /core/tests/.env: -------------------------------------------------------------------------------- 1 | TEST=TEST 2 | -------------------------------------------------------------------------------- /core/tests/mint.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "core-tests", 3 | "test-directories": [ 4 | "tests" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /core/tests/tests/ArrayBuffer.mint: -------------------------------------------------------------------------------- 1 | suite "ArrayBuffer conversion from/to String" { 2 | test "round trip converts" { 3 | ("Hello" 4 | |> ArrayBuffer.toArrayBuffer() 5 | |> ArrayBuffer.toString()) == "Hello" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /core/tests/tests/Base64.mint: -------------------------------------------------------------------------------- 1 | suite "Base64.decode" { 2 | test "it decodes" { 3 | Base64.decode("dGVzdA==") == Result.Ok("test") 4 | } 5 | 6 | test "it doesn't decode" { 7 | Result.isError(Base64.decode("dGVzdA=")) 8 | } 9 | } 10 | 11 | suite "Base64.encode" { 12 | test "it encodes" { 13 | Base64.encode("test") == "dGVzdA==" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /core/tests/tests/Bool.mint: -------------------------------------------------------------------------------- 1 | suite "Bool.toString" { 2 | test "returns 'true' for true" { 3 | (Bool.toString(true)) == "true" 4 | } 5 | 6 | test "returns 'false' for false" { 7 | (Bool.toString(false)) == "false" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /core/tests/tests/Defer.mint: -------------------------------------------------------------------------------- 1 | suite "Defer" { 2 | const DEFERRED = defer "Hello World!" 3 | 4 | test "it loads deferred content" { 5 | let greeting = 6 | await DEFERRED 7 | 8 | greeting == "Hello World!" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /core/tests/tests/Destructuring.mint: -------------------------------------------------------------------------------- 1 | suite "Array destructuring" { 2 | test "spread" { 3 | case ["a", "b"] { 4 | [..._] => true 5 | } 6 | } 7 | 8 | test "one item" { 9 | case ["a"] { 10 | [_] => true 11 | => false 12 | } 13 | } 14 | 15 | test "empty" { 16 | case [] { 17 | [] => true 18 | => false 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /core/tests/tests/Dom/Dimensions.mint: -------------------------------------------------------------------------------- 1 | suite "Dom.Dimensions.empty" { 2 | test "returns an empty dimensions object" { 3 | Dom.Dimensions.empty() == { 4 | bottom: 0, 5 | height: 0, 6 | width: 0, 7 | right: 0, 8 | left: 0, 9 | top: 0, 10 | x: 0, 11 | y: 0 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /core/tests/tests/Env.mint: -------------------------------------------------------------------------------- 1 | suite "Env" { 2 | test "loads from .env file" { 3 | @TEST == "TEST" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /core/tests/tests/FieldAccess.mint: -------------------------------------------------------------------------------- 1 | suite "Field Access" { 2 | test "it returns the value" { 3 | let options = 4 | { 5 | caseInsensitive: true, 6 | multiline: true, 7 | sticky: false, 8 | unicode: true, 9 | global: true 10 | } 11 | 12 | .sticky(Regexp.Options)(options) == false 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /core/tests/tests/FileSize.mint: -------------------------------------------------------------------------------- 1 | suite "FileSize.format" { 2 | test "for 0 return 0B" { 3 | FileSize.format(0) == "0 B" 4 | } 5 | 6 | test "for 1000 returns 1kB" { 7 | FileSize.format(1000) == "1 kB" 8 | } 9 | 10 | test "for 1000000 returns 1MB" { 11 | FileSize.format(1000000) == "1 MB" 12 | } 13 | 14 | test "for 1000000000 returns 1GB" { 15 | FileSize.format(1000000000) == "1 GB" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /core/tests/tests/Function.mint: -------------------------------------------------------------------------------- 1 | suite "captures" { 2 | fun add (a : Number, b : Number) : Number { 3 | a + b 4 | } 5 | 6 | test "normal" { 7 | add(1, _)(2) == 3 8 | } 9 | 10 | test "labelled" { 11 | add(b: 1, a: _)(2) == 3 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /core/tests/tests/GlobalComponent.mint: -------------------------------------------------------------------------------- 1 | global component GlobalTest { 2 | fun render : Html { 3 |
4 | } 5 | } 6 | 7 | suite "Global Component" { 8 | test "It renders on the page" { 9 | Dom.getElementBySelector(".global-component") != Maybe.Nothing 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /core/tests/tests/Uid.mint: -------------------------------------------------------------------------------- 1 | suite "Uid.generate" { 2 | test "it generates a unique id" { 3 | Uid.generate() != Uid.generate() 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | # This file is used to build the release version of Mint 2 | # locally and on linux CI. 3 | # 4 | # NOTE: Make sure that the crystal version is the same as 5 | # in the `.tool-versions` and `Dockerfile` files. 6 | version: "2" 7 | services: 8 | app: 9 | image: crystallang/crystal:1.14.0-alpine 10 | working_dir: /app 11 | volumes: 12 | - .:/app 13 | -------------------------------------------------------------------------------- /runtime/index_testing.js: -------------------------------------------------------------------------------- 1 | export { render as testRender } from "preact"; 2 | export * from "./src/testing"; 3 | export * from "./index"; 4 | -------------------------------------------------------------------------------- /runtime/src/symbols.js: -------------------------------------------------------------------------------- 1 | export const Equals = Symbol("Equals"); 2 | export const Name = Symbol("Name"); 3 | -------------------------------------------------------------------------------- /runtime/tests/translate.test.js: -------------------------------------------------------------------------------- 1 | import { expect, test, describe } from "vitest"; 2 | import { setLocale, translate, locale } from "../index"; 3 | 4 | describe("setLocale", () => { 5 | test("setting locale", () => { 6 | setLocale("en"); 7 | expect(locale.value).toEqual("en"); 8 | }); 9 | }); 10 | 11 | describe("translate", () => { 12 | test("translates a key", () => { 13 | expect(translate("test")).toEqual(""); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /runtime/vite.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vitest/config"; 2 | 3 | export default defineConfig({ 4 | test: { 5 | environment: "jsdom", 6 | coverage: { 7 | provider: "v8", 8 | }, 9 | }, 10 | }); 11 | -------------------------------------------------------------------------------- /spec/compilers/access: -------------------------------------------------------------------------------- 1 | type X { 2 | name : String 3 | } 4 | 5 | component Main { 6 | fun render : String { 7 | { name: "test" }.name 8 | } 9 | } 10 | -------------------------------------------------------------------------------- 11 | import { record as A } from "./runtime.js"; 12 | 13 | export const 14 | a = A(`X`), 15 | B = () => { 16 | return a({ 17 | name: `test` 18 | }).name 19 | }; 20 | -------------------------------------------------------------------------------- /spec/compilers/argument: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun test (a : String, b : Number) : Number { 3 | b 4 | } 5 | 6 | fun render : String { 7 | test("", 0) 8 | 9 | "" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- 13 | export const A = () => { 14 | const a = (b, c) => { 15 | return c 16 | }; 17 | a(``, 0); 18 | return `` 19 | }; 20 | -------------------------------------------------------------------------------- /spec/compilers/argument_with_default: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun test (a : String, b : Number = 0) : Number { 3 | b 4 | } 5 | 6 | fun render : String { 7 | test("") 8 | 9 | "" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- 13 | export const A = () => { 14 | const a = (b, c = 0) => { 15 | return c 16 | }; 17 | a(``); 18 | return `` 19 | }; 20 | -------------------------------------------------------------------------------- /spec/compilers/array_literal: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | [ 4 | "Hello", 5 | "Blah", 6 | "Joe" 7 | ] 8 | 9 | "" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- 13 | export const A = () => { 14 | [ 15 | `Hello`, 16 | `Blah`, 17 | `Joe` 18 | ]; 19 | return `` 20 | }; 21 | -------------------------------------------------------------------------------- /spec/compilers/await_inline_function: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | { 4 | await () { "" } 5 | } 6 | 7 | "Hello" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- 11 | export const A = () => { 12 | (async () => { 13 | return await (() => { 14 | return `` 15 | }) 16 | })(); 17 | return `Hello` 18 | }; 19 | -------------------------------------------------------------------------------- /spec/compilers/block: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | let a = "Some string..." 4 | 5 | a + ", other string..." 6 | } 7 | } 8 | -------------------------------------------------------------------------------- 9 | export const A = () => { 10 | const a = `Some string...`; 11 | return a + `, other string...` 12 | }; 13 | -------------------------------------------------------------------------------- /spec/compilers/block_with_tuple_destructuring: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | let {a, b} = {"Some string...", "B"} 4 | 5 | a + ", other string..." 6 | } 7 | } 8 | -------------------------------------------------------------------------------- 9 | export const A = () => { 10 | const [ 11 | a, 12 | b 13 | ] = [ 14 | `Some string...`, 15 | `B` 16 | ]; 17 | return a + `, other string...` 18 | }; 19 | -------------------------------------------------------------------------------- /spec/compilers/bool_literal_false: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | false 4 | 5 | "" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- 9 | export const A = () => { 10 | false; 11 | return `` 12 | }; 13 | -------------------------------------------------------------------------------- /spec/compilers/bool_literal_true: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | true 4 | 5 | "" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- 9 | export const A = () => { 10 | true; 11 | return `` 12 | }; 13 | -------------------------------------------------------------------------------- /spec/compilers/builtin: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : Html { 3 | `#{%decodeBoolean%}` 4 | 5 |
6 | } 7 | } 8 | -------------------------------------------------------------------------------- 9 | import { 10 | createElement as B, 11 | decodeBoolean as A 12 | } from "./runtime.js"; 13 | 14 | export const C = () => { 15 | (A); 16 | return B(`div`, {}) 17 | }; 18 | -------------------------------------------------------------------------------- /spec/compilers/call_labelled: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun test (argument1 : String, argument2: Number) : String { 3 | "" 4 | } 5 | 6 | fun render : String { 7 | test(argument2: 0, argument1: "") 8 | } 9 | } 10 | -------------------------------------------------------------------------------- 11 | export const A = () => { 12 | const a = (b, c) => { 13 | return `` 14 | }; 15 | return a(``, 0) 16 | }; 17 | -------------------------------------------------------------------------------- /spec/compilers/case_empty: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | case ("Hello") { 4 | => "false" 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- 9 | import { match as A } from "./runtime.js"; 10 | 11 | export const B = () => { 12 | return A(`Hello`, [[ 13 | null, 14 | () => { 15 | return `false` 16 | } 17 | ]]) 18 | }; 19 | -------------------------------------------------------------------------------- /spec/compilers/component: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | "" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | export const A = () => { 8 | return `` 9 | }; 10 | -------------------------------------------------------------------------------- /spec/compilers/constant_component: -------------------------------------------------------------------------------- 1 | component Main { 2 | const NAME = "ASD" 3 | 4 | fun render : String { 5 | NAME 6 | } 7 | } 8 | -------------------------------------------------------------------------------- 9 | import { useSignal as A } from "./runtime.js"; 10 | 11 | export const B = () => { 12 | const a = A(`ASD`); 13 | return a.value 14 | }; 15 | -------------------------------------------------------------------------------- /spec/compilers/constant_module: -------------------------------------------------------------------------------- 1 | module Test { 2 | const NAME = "ASD" 3 | } 4 | 5 | component Main { 6 | fun render : Html { 7 |
8 | Test.NAME 9 |
10 | } 11 | } 12 | -------------------------------------------------------------------------------- 13 | import { createElement as A } from "./runtime.js"; 14 | 15 | export const 16 | a = `ASD`, 17 | B = () => { 18 | return A(`div`, {}, [a]) 19 | }; 20 | -------------------------------------------------------------------------------- /spec/compilers/constant_store: -------------------------------------------------------------------------------- 1 | store Test { 2 | const NAME = "ASD" 3 | } 4 | 5 | component Main { 6 | fun render : Html { 7 |
8 | Test.NAME 9 |
10 | } 11 | } 12 | -------------------------------------------------------------------------------- 13 | import { createElement as A } from "./runtime.js"; 14 | 15 | export const 16 | a = `ASD`, 17 | B = () => { 18 | return A(`div`, {}, [a]) 19 | }; 20 | -------------------------------------------------------------------------------- /spec/compilers/dbg: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | dbg "Hello World!" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | import { inspect as A } from "./runtime.js"; 8 | 9 | export const B = () => { 10 | return (() => { 11 | const a = `Hello World!`; 12 | console.log(`compilers/dbg:3:4`); 13 | console.log(A(a)); 14 | return a 15 | })() 16 | }; 17 | -------------------------------------------------------------------------------- /spec/compilers/dbg_as_function: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | "Hello World!" |> dbg 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | import { inspect as A } from "./runtime.js"; 8 | 9 | export const B = () => { 10 | return (a) => { 11 | console.log(`compilers/dbg_as_function:3:22`); 12 | console.log(A(a)); 13 | return a 14 | }(`Hello World!`) 15 | }; 16 | -------------------------------------------------------------------------------- /spec/compilers/dbg_bang: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | dbg! "Hello World!" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | export const A = () => { 8 | return (() => { 9 | const a = `Hello World!`; 10 | console.log(`compilers/dbg_bang:3:4`); 11 | console.log(a); 12 | return a 13 | })() 14 | }; 15 | -------------------------------------------------------------------------------- /spec/compilers/dce_remove_component: -------------------------------------------------------------------------------- 1 | component Test { 2 | fun render : Html { 3 |
4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | -------------------------------------------------------------------------------- /spec/compilers/dce_remove_component_computed_property: -------------------------------------------------------------------------------- 1 | component Main { 2 | get test : String { 3 | "" 4 | } 5 | 6 | fun render : Html { 7 |
8 | } 9 | } 10 | -------------------------------------------------------------------------------- 11 | import { createElement as A } from "./runtime.js"; 12 | 13 | export const B = () => { 14 | return A(`div`, {}) 15 | }; 16 | -------------------------------------------------------------------------------- /spec/compilers/dce_remove_component_function: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun test : String { 3 | "" 4 | } 5 | 6 | fun render : Html { 7 |
8 | } 9 | } 10 | -------------------------------------------------------------------------------- 11 | import { createElement as A } from "./runtime.js"; 12 | 13 | export const B = () => { 14 | return A(`div`, {}) 15 | }; 16 | -------------------------------------------------------------------------------- /spec/compilers/dce_remove_enum: -------------------------------------------------------------------------------- 1 | type Test { 2 | X 3 | Y 4 | Z 5 | } 6 | -------------------------------------------------------------------------------- 7 | -------------------------------------------------------------------------------- /spec/compilers/dce_remove_module: -------------------------------------------------------------------------------- 1 | module Test { 2 | fun test : String { 3 | "" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | -------------------------------------------------------------------------------- /spec/compilers/dce_remove_module_function: -------------------------------------------------------------------------------- 1 | module Test { 2 | fun test : String { 3 | "" 4 | } 5 | 6 | fun x : String { 7 | "" 8 | } 9 | } 10 | 11 | component Main { 12 | fun render : String { 13 | Test.test() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- 17 | export const 18 | a = () => { 19 | return `` 20 | }, 21 | A = () => { 22 | return a() 23 | }; 24 | -------------------------------------------------------------------------------- /spec/compilers/dce_remove_provider: -------------------------------------------------------------------------------- 1 | type Subscription { 2 | name : String 3 | } 4 | 5 | provider MouseProvider : Subscription { 6 | fun attach : Void { 7 | void 8 | } 9 | } 10 | -------------------------------------------------------------------------------- 11 | -------------------------------------------------------------------------------- /spec/compilers/dce_remove_store: -------------------------------------------------------------------------------- 1 | store Test { 2 | fun test : String { 3 | "" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | -------------------------------------------------------------------------------- /spec/compilers/dce_style: -------------------------------------------------------------------------------- 1 | component Main { 2 | style test { 3 | color: red; 4 | } 5 | 6 | fun render : Html { 7 |
8 | } 9 | } 10 | -------------------------------------------------------------------------------- 11 | import { createElement as A } from "./runtime.js"; 12 | 13 | export const B = () => { 14 | return A(`div`, {}) 15 | }; 16 | -------------------------------------------------------------------------------- /spec/compilers/directives/inline: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | @inline(../../fixtures/data.txt) 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | export const A = () => { 8 | return `Hello World! 9 | ` 10 | }; 11 | -------------------------------------------------------------------------------- /spec/compilers/directives/inline-absolute: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | @inline(/fixtures/data.txt) 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | export const A = () => { 8 | return `Hello World! 9 | ` 10 | }; 11 | -------------------------------------------------------------------------------- /spec/compilers/env: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | @TEST 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | export const A = () => { 8 | return `TRUE` 9 | }; 10 | -------------------------------------------------------------------------------- /spec/compilers/function: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun test : Bool { 3 | true 4 | } 5 | 6 | fun render : String { 7 | test() 8 | 9 | "" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- 13 | export const A = () => { 14 | const a = () => { 15 | return true 16 | }; 17 | a(); 18 | return `` 19 | }; 20 | -------------------------------------------------------------------------------- /spec/compilers/get: -------------------------------------------------------------------------------- 1 | component Main { 2 | get test : String { 3 | "" 4 | } 5 | 6 | fun render : String { 7 | test 8 | } 9 | } 10 | -------------------------------------------------------------------------------- 11 | export const A = () => { 12 | const a = () => { 13 | return `` 14 | }; 15 | return a() 16 | }; 17 | -------------------------------------------------------------------------------- /spec/compilers/here_doc_new_line_char: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | <<~MINT 4 | \n 5 | MINT 6 | } 7 | } 8 | -------------------------------------------------------------------------------- 9 | export const A = () => { 10 | return `\\n` 11 | }; 12 | -------------------------------------------------------------------------------- /spec/compilers/html_attribute_class: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : Html { 3 |
4 |
5 | } 6 | } 7 | -------------------------------------------------------------------------------- 8 | import { createElement as A } from "./runtime.js"; 9 | 10 | export const B = () => { 11 | return A(`div`, { 12 | className: `something` 13 | }) 14 | }; 15 | -------------------------------------------------------------------------------- /spec/compilers/html_attribute_readonly: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : Html { 3 |
4 |
5 | } 6 | } 7 | -------------------------------------------------------------------------------- 8 | import { createElement as A } from "./runtime.js"; 9 | 10 | export const B = () => { 11 | return A(`div`, { 12 | readOnly: true 13 | }) 14 | }; 15 | -------------------------------------------------------------------------------- /spec/compilers/html_attribute_simple: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : Html { 3 |
4 |
5 | } 6 | } 7 | -------------------------------------------------------------------------------- 8 | import { createElement as A } from "./runtime.js"; 9 | 10 | export const B = () => { 11 | return A(`div`, { 12 | "title": `Hello` 13 | }) 14 | }; 15 | -------------------------------------------------------------------------------- /spec/compilers/html_attribute_with_expression: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : Html { 3 |
4 |
5 | } 6 | } 7 | -------------------------------------------------------------------------------- 8 | import { createElement as A } from "./runtime.js"; 9 | 10 | export const B = () => { 11 | return A(`div`, { 12 | "title": `Hello ` + `there!` 13 | }) 14 | }; 15 | -------------------------------------------------------------------------------- /spec/compilers/html_fragment_empty: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : Html { 3 |
4 | <> 5 | 6 |
7 | } 8 | } 9 | -------------------------------------------------------------------------------- 10 | import { createElement as A } from "./runtime.js"; 11 | 12 | export const B = () => { 13 | return A(`div`, {}, [null]) 14 | }; 15 | -------------------------------------------------------------------------------- /spec/compilers/html_with_string_style: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : Html { 3 |
4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | import { 8 | createElement as A, 9 | style as B 10 | } from "./runtime.js"; 11 | 12 | export const C = () => { 13 | return A(`div`, { 14 | style: B([`opacity:0;`]) 15 | }) 16 | }; 17 | -------------------------------------------------------------------------------- /spec/compilers/if: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | if ("asd" == "asd2") { 4 | true 5 | } else { 6 | false 7 | } 8 | 9 | "" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- 13 | import { compare as A } from "./runtime.js"; 14 | 15 | export const B = () => { 16 | (A(`asd`, `asd2`) ? true : false); 17 | return `` 18 | }; 19 | -------------------------------------------------------------------------------- /spec/compilers/if_without_else_array: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : Array(String) { 3 | if ("asd" == "asd2") { 4 | ["ARRAY"] 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- 9 | import { compare as A } from "./runtime.js"; 10 | 11 | export const B = () => { 12 | return (A(`asd`, `asd2`) ? [`ARRAY`] : []) 13 | }; 14 | -------------------------------------------------------------------------------- /spec/compilers/if_without_else_promise: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | if ("asd" == "asd2") { 4 | next {} 5 | } 6 | 7 | "" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- 11 | import { compare as A } from "./runtime.js"; 12 | 13 | export const B = () => { 14 | (A(`asd`, `asd2`) ? null : null); 15 | return `` 16 | }; 17 | -------------------------------------------------------------------------------- /spec/compilers/if_without_else_string: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | if ("asd" == "asd2") { 4 | "TRUE" 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- 9 | import { compare as A } from "./runtime.js"; 10 | 11 | export const B = () => { 12 | return (A(`asd`, `asd2`) ? `TRUE` : "") 13 | }; 14 | -------------------------------------------------------------------------------- /spec/compilers/inline_function: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | let a = 4 | () : String { "Hello" } 5 | 6 | a() 7 | } 8 | } 9 | -------------------------------------------------------------------------------- 10 | export const A = () => { 11 | const a = () => { 12 | return `Hello` 13 | }; 14 | return a() 15 | }; 16 | -------------------------------------------------------------------------------- /spec/compilers/js: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | ` "Hello" ` 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | export const A = () => { 8 | return ("Hello") 9 | }; 10 | -------------------------------------------------------------------------------- /spec/compilers/js_with_double_interpolation: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | ` "Hello" + #{`"World!"`} ` 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | export const A = () => { 8 | return ("Hello" + ("World!")) 9 | }; 10 | -------------------------------------------------------------------------------- /spec/compilers/js_with_interpolation: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | ` "Hello" + #{"World!"} ` 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | export const A = () => { 8 | return ("Hello" + `World!`) 9 | }; 10 | -------------------------------------------------------------------------------- /spec/compilers/next_call_empty: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | next {} 4 | "" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- 8 | export const A = () => { 9 | null; 10 | return `` 11 | }; 12 | -------------------------------------------------------------------------------- /spec/compilers/number_literal_negative: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | -42 4 | "" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- 8 | export const A = () => { 9 | -42; 10 | return `` 11 | }; 12 | -------------------------------------------------------------------------------- /spec/compilers/number_literal_simple: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | 10 4 | "" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- 8 | export const A = () => { 9 | 10; 10 | return `` 11 | }; 12 | -------------------------------------------------------------------------------- /spec/compilers/number_literal_with_decimal: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | 10.120 4 | "" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- 8 | export const A = () => { 9 | 10.120; 10 | return `` 11 | }; 12 | -------------------------------------------------------------------------------- /spec/compilers/operation_chained: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | "a" == "b" && true != false 4 | "" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- 8 | import { compare as A } from "./runtime.js"; 9 | 10 | export const B = () => { 11 | A(`a`, `b`) && !A(true, false); 12 | return `` 13 | }; 14 | -------------------------------------------------------------------------------- /spec/compilers/operation_simple: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | "a" == "b" 4 | "" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- 8 | import { compare as A } from "./runtime.js"; 9 | 10 | export const B = () => { 11 | A(`a`, `b`); 12 | return `` 13 | }; 14 | -------------------------------------------------------------------------------- /spec/compilers/parenthesized_expression: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | (true) 4 | "" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- 8 | export const A = () => { 9 | (true); 10 | return `` 11 | }; 12 | -------------------------------------------------------------------------------- /spec/compilers/regexp_literal: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | /.*/gm 4 | "" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- 8 | export const A = () => { 9 | /.*/gm; 10 | return `` 11 | }; 12 | -------------------------------------------------------------------------------- /spec/compilers/state_setter: -------------------------------------------------------------------------------- 1 | component Main { 2 | state value : String = "" 3 | 4 | fun render : String { 5 | ->value("Hello") 6 | value 7 | } 8 | } 9 | -------------------------------------------------------------------------------- 10 | import { useSignal as A } from "./runtime.js"; 11 | 12 | export const B = () => { 13 | const a = A(``); 14 | ((b) => { 15 | a.value = b 16 | })(`Hello`); 17 | return a.value 18 | }; 19 | -------------------------------------------------------------------------------- /spec/compilers/statement: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | let x = 4 | "hello" 5 | 6 | x 7 | } 8 | } 9 | -------------------------------------------------------------------------------- 10 | export const A = () => { 11 | const a = `hello`; 12 | return a 13 | }; 14 | -------------------------------------------------------------------------------- /spec/compilers/string_literal_broken: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | "First line" \ 4 | "Second line" \ 5 | "Third line" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- 9 | export const A = () => { 10 | return `First lineSecond lineThird line` 11 | }; 12 | -------------------------------------------------------------------------------- /spec/compilers/string_literal_escaped: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | "Hello There \"Joe\"" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | export const A = () => { 8 | return `Hello There "Joe"` 9 | }; 10 | -------------------------------------------------------------------------------- /spec/compilers/string_literal_simple: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | "Hello There" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | export const A = () => { 8 | return `Hello There` 9 | }; 10 | -------------------------------------------------------------------------------- /spec/compilers/string_literal_with_backtick: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | "Hello There `Joe`" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | export const A = () => { 8 | return `Hello There \`Joe\`` 9 | }; 10 | -------------------------------------------------------------------------------- /spec/compilers/string_literal_with_escaped_interpolation: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | "Hello There \#{name}" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | export const A = () => { 8 | return `Hello There #{name}` 9 | }; 10 | -------------------------------------------------------------------------------- /spec/compilers/string_literal_with_interpolation: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | "Hello There #{"Hello"}" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | export const A = () => { 8 | return `Hello There ${`Hello`}` 9 | }; 10 | -------------------------------------------------------------------------------- /spec/compilers/string_literal_with_interpolation_and_js_iterpolation: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | "Hello There #{"Hello"}" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | export const A = () => { 8 | return `Hello There ${`Hello`}` 9 | }; 10 | -------------------------------------------------------------------------------- /spec/compilers/string_literal_with_interpolation_of_number: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | "Hello There #{0}" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | export const A = () => { 8 | return `Hello There ${0}` 9 | }; 10 | -------------------------------------------------------------------------------- /spec/compilers/string_literal_with_js_iterpolation: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | "Hello There ${a}" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | export const A = () => { 8 | return `Hello There \${a}` 9 | }; 10 | -------------------------------------------------------------------------------- /spec/compilers/tuple_literal: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | { 4 | "Hello", 5 | "Blah", 6 | "Joe" 7 | } 8 | "" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- 12 | export const A = () => { 13 | [ 14 | `Hello`, 15 | `Blah`, 16 | `Joe` 17 | ]; 18 | return `` 19 | }; 20 | -------------------------------------------------------------------------------- /spec/compilers/unary_minus: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | -(42) 4 | 5 | "" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- 9 | export const A = () => { 10 | -((42)); 11 | return `` 12 | }; 13 | -------------------------------------------------------------------------------- /spec/compilers/variable_argument: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun test (a : String) : String { 3 | a 4 | } 5 | 6 | fun render : String { 7 | test("X") 8 | } 9 | } 10 | -------------------------------------------------------------------------------- 11 | export const A = () => { 12 | const a = (b) => { 13 | return b 14 | }; 15 | return a(`X`) 16 | }; 17 | -------------------------------------------------------------------------------- /spec/compilers/variable_component_function: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun test : String { 3 | "Hello" 4 | } 5 | 6 | fun render : String { 7 | test() 8 | } 9 | } 10 | -------------------------------------------------------------------------------- 11 | export const A = () => { 12 | const a = () => { 13 | return `Hello` 14 | }; 15 | return a() 16 | }; 17 | -------------------------------------------------------------------------------- /spec/compilers/variable_component_get: -------------------------------------------------------------------------------- 1 | component Main { 2 | get test : String { 3 | "Hello" 4 | } 5 | 6 | fun render : String { 7 | test 8 | } 9 | } 10 | -------------------------------------------------------------------------------- 11 | export const A = () => { 12 | const a = () => { 13 | return `Hello` 14 | }; 15 | return a() 16 | }; 17 | -------------------------------------------------------------------------------- /spec/compilers/void: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | void 4 | "" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- 8 | export const A = () => { 9 | null; 10 | return `` 11 | }; 12 | -------------------------------------------------------------------------------- /spec/errors/component_expected_body: -------------------------------------------------------------------------------- 1 | component Main { 2 | -------------------------------------------------------------------------------- 3 | ░ ERROR (COMPONENT_EXPECTED_BODY) ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 4 | 5 | I was expecting the body of a component but I found "a space" instead: 6 | 7 | ┌ errors/component_expected_body:1:16 8 | ├──────────────────────────────────── 9 | 1│ component Main { 10 | │ ⌃⌃⌃⌃ 11 | -------------------------------------------------------------------------------- /spec/errors/get_expected_name: -------------------------------------------------------------------------------- 1 | component Main { 2 | get 3 | -------------------------------------------------------------------------------- 4 | ░ ERROR (GET_EXPECTED_NAME) ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 5 | 6 | I was expecting the name of a get but I found "a space" instead: 7 | 8 | ┌ errors/get_expected_name:2:5 9 | ├───────────────────────────── 10 | 1│ component Main { 11 | 2│ get 12 | │ ⌃⌃⌃⌃ 13 | -------------------------------------------------------------------------------- /spec/errors/locale_expected_language: -------------------------------------------------------------------------------- 1 | locale 2 | -------------------------------------------------------------------------------- 3 | ░ ERROR (LOCALE_EXPECTED_LANGUAGE) ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 4 | 5 | I was expecting the language code of the locale but I found "a space" instead: 6 | 7 | ┌ errors/locale_expected_language:1:6 8 | ├──────────────────────────────────── 9 | 1│ locale 10 | │ ⌃⌃⌃⌃ 11 | -------------------------------------------------------------------------------- /spec/errors/module_expected_body: -------------------------------------------------------------------------------- 1 | module Test { 2 | -------------------------------------------------------------------------------- 3 | ░ ERROR (MODULE_EXPECTED_BODY) ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 4 | 5 | I was expecting the body of the module but I found "a space" instead: 6 | 7 | ┌ errors/module_expected_body:1:13 8 | ├───────────────────────────────── 9 | 1│ module Test { 10 | │ ⌃⌃⌃⌃ 11 | -------------------------------------------------------------------------------- /spec/errors/provider_expeceted_colon: -------------------------------------------------------------------------------- 1 | provider Test 2 | -------------------------------------------------------------------------------- 3 | ░ ERROR (PROVIDER_EXPECETED_COLON) ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 4 | 5 | I was expecting the colon of a provider but I found "a space" instead: 6 | 7 | ┌ errors/provider_expeceted_colon:1:13 8 | ├───────────────────────────────────── 9 | 1│ provider Test 10 | │ ⌃⌃⌃⌃ 11 | -------------------------------------------------------------------------------- /spec/errors/provider_expected_name: -------------------------------------------------------------------------------- 1 | provider 2 | -------------------------------------------------------------------------------- 3 | ░ ERROR (PROVIDER_EXPECTED_NAME) ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 4 | 5 | I was expecting the name of a provider but I found "a space" instead: 6 | 7 | ┌ errors/provider_expected_name:1:8 8 | ├────────────────────────────────── 9 | 1│ provider 10 | │ ⌃⌃⌃⌃ 11 | -------------------------------------------------------------------------------- /spec/errors/route_expected_body: -------------------------------------------------------------------------------- 1 | routes { 2 | * { 3 | -------------------------------------------------------------------------------- 4 | ░ ERROR (ROUTE_EXPECTED_BODY) ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 5 | 6 | I was expecting the body of a route but I found "a space" instead: 7 | 8 | ┌ errors/route_expected_body:2:5 9 | ├─────────────────────────────── 10 | 1│ routes { 11 | 2│ * { 12 | │ ⌃⌃⌃⌃ 13 | -------------------------------------------------------------------------------- /spec/errors/routes_expected_body: -------------------------------------------------------------------------------- 1 | routes { 2 | -------------------------------------------------------------------------------- 3 | ░ ERROR (ROUTES_EXPECTED_BODY) ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 4 | 5 | I was expecting the body of a routes block but I found "a space" instead: 6 | 7 | ┌ errors/routes_expected_body:1:8 8 | ├──────────────────────────────── 9 | 1│ routes { 10 | │ ⌃⌃⌃⌃ 11 | -------------------------------------------------------------------------------- /spec/errors/store_expected_body: -------------------------------------------------------------------------------- 1 | store X { 2 | -------------------------------------------------------------------------------- 3 | ░ ERROR (STORE_EXPECTED_BODY) ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 4 | 5 | I was expecting the body of a store but I found "a space" instead: 6 | 7 | ┌ errors/store_expected_body:1:9 8 | ├─────────────────────────────── 9 | 1│ store X { 10 | │ ⌃⌃⌃⌃ 11 | -------------------------------------------------------------------------------- /spec/errors/store_expected_name: -------------------------------------------------------------------------------- 1 | store 2 | -------------------------------------------------------------------------------- 3 | ░ ERROR (STORE_EXPECTED_NAME) ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 4 | 5 | I was expecting the name of a store but I found "a space" instead: 6 | 7 | ┌ errors/store_expected_name:1:5 8 | ├─────────────────────────────── 9 | 1│ store 10 | │ ⌃⌃⌃⌃ 11 | -------------------------------------------------------------------------------- /spec/errors/store_expected_opening_bracket: -------------------------------------------------------------------------------- 1 | store X 2 | -------------------------------------------------------------------------------- 3 | ░ ERROR (STORE_EXPECTED_OPENING_BRACKET) ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 4 | 5 | I was expecting the opening bracket of a store but I found "a space" instead: 6 | 7 | ┌ errors/store_expected_opening_bracket:1:7 8 | ├────────────────────────────────────────── 9 | 1│ store X 10 | │ ⌃⌃⌃⌃ 11 | -------------------------------------------------------------------------------- /spec/errors/suite_expected_body: -------------------------------------------------------------------------------- 1 | suite "X" { 2 | -------------------------------------------------------------------------------- 3 | ░ ERROR (SUITE_EXPECTED_BODY) ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 4 | 5 | I was expecting the body of a suite but I found "a space" instead: 6 | 7 | ┌ errors/suite_expected_body:1:11 8 | ├──────────────────────────────── 9 | 1│ suite "X" { 10 | │ ⌃⌃⌃⌃ 11 | -------------------------------------------------------------------------------- /spec/errors/suite_expected_name: -------------------------------------------------------------------------------- 1 | suite 2 | -------------------------------------------------------------------------------- 3 | ░ ERROR (SUITE_EXPECTED_NAME) ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 4 | 5 | I was expecting the name of a suite but I found "a space" instead: 6 | 7 | ┌ errors/suite_expected_name:1:5 8 | ├─────────────────────────────── 9 | 1│ suite 10 | │ ⌃⌃⌃⌃ 11 | -------------------------------------------------------------------------------- /spec/errors/test_expected_name: -------------------------------------------------------------------------------- 1 | suite "X" { 2 | test 3 | -------------------------------------------------------------------------------- 4 | ░ ERROR (TEST_EXPECTED_NAME) ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 5 | 6 | I was expecting the name of a test but I found "a space" instead: 7 | 8 | ┌ errors/test_expected_name:2:6 9 | ├────────────────────────────── 10 | 1│ suite "X" { 11 | 2│ test 12 | │ ⌃⌃⌃⌃ 13 | -------------------------------------------------------------------------------- /spec/errors/tuple_literal_expected_closing_parenthesis: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | {"", ""}[0] 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | -------------------------------------------------------------------------------- /spec/errors/type_definition_expected_closing_bracket: -------------------------------------------------------------------------------- 1 | type A 2 | -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- /spec/errors/type_definition_expected_name: -------------------------------------------------------------------------------- 1 | type 2 | -------------------------------------------------------------------------------- 3 | ░ ERROR (TYPE_DEFINITION_EXPECTED_NAME) ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 4 | 5 | I was expecting the name of a type but I found "a space" instead: 6 | 7 | ┌ errors/type_definition_expected_name:1:4 8 | ├───────────────────────────────────────── 9 | 1│ type 10 | │ ⌃⌃⌃⌃ 11 | -------------------------------------------------------------------------------- /spec/examples/array_destructuring: -------------------------------------------------------------------------------- 1 | -----------------------------------array_destructuring_expected_closing_bracket 2 | component Main { 3 | fun render : String { 4 | let [x 5 | -------------------------------------------------------------------------------- /spec/examples/await: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | { 4 | await "Hello" 5 | } 6 | 7 | "" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- 11 | component Main { 12 | fun render : String { 13 | { 14 | "asd" |> await defer (value : String) { value } 15 | } 16 | 17 | "" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /spec/examples/block: -------------------------------------------------------------------------------- 1 | --------------------------------------------------inline_function_expected_body 2 | component Main { 3 | state callback : Function(Bool, Number, void) = (a : Bool, b : Number) { } 4 | 5 | fun render : Html { 6 | "Hello" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /spec/examples/bool_literal: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | if (true) { 4 | "" 5 | } else { 6 | "" 7 | } 8 | } 9 | } 10 | ------------------------------------------------------------------------------- 11 | component Main { 12 | fun render : String { 13 | if (false) { 14 | "" 15 | } else { 16 | "" 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /spec/examples/builtin: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : Html { 3 | `#{%decodeBoolean%}` 4 | 5 |
6 | } 7 | } 8 | ------------------------------------------------------------------unkown_builtin 9 | component Main { 10 | fun render : Html { 11 | `#{%wtf%}` 12 | 13 |
14 | } 15 | } 16 | -------------------------------------------------------------------------------- /spec/examples/comment: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------- 2 | /* BLOCK COMMENT */ 3 | ------------------------------------------------------------------------------- 4 | // LINE COMMENT 5 | -------------------------------------------------------------------------------- /spec/examples/discard: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | case "A" { 4 | "A" => "A" 5 | _ => "X" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /spec/examples/emit: -------------------------------------------------------------------------------- 1 | -----------------------------------------------------------------emit_no_signal 2 | component Main { 3 | fun render : Html { 4 | emit 0 5 |
6 | } 7 | } 8 | -------------------------------------------------------------emit_type_mismatch 9 | store Test { 10 | signal b : String { emit 0 } 11 | } 12 | -------------------------------------------------------------------------------- /spec/examples/encode: -------------------------------------------------------------------------------- 1 | -----------------------------------------------------encode_expected_expression 2 | component Main { 3 | fun render : Html { 4 | encode 5 | ------------------------------------------------------------encode_complex_type 6 | type Maybe { 7 | Just(String) 8 | } 9 | 10 | component Main { 11 | fun render : Html { 12 | encode (`` as Blah) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /spec/examples/html_fragment: -------------------------------------------------------------------------------- 1 | ---------------------------------------------html_fragment_expected_closing_tag 2 | component Main { 3 | fun render : Html { 4 | <> 5 | -------------------------------------------------------------------------------- /spec/examples/number_literal: -------------------------------------------------------------------------------- 1 | ------------------------------------------------number_literal_expected_decimal 2 | component Main { 3 | fun render : String { 4 | 0. 5 | ------------------------------------------------------------------------------- 6 | component Main { 7 | fun test : Number { 8 | 0 9 | } 10 | 11 | fun render : String { 12 | "" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /spec/examples/parenthesized_expression: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------- 2 | component Main { 3 | fun render : String { 4 | ("") 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /spec/examples/regexp_literal: -------------------------------------------------------------------------------- 1 | ------------------------------------------regexp_literal_expected_closing_slash 2 | component Main { 3 | fun render : String { 4 | /asd 5 | -------------------------------------------------------------------------------- /spec/examples/spread: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------spread_expected_variable 2 | component Main { 3 | fun render : String { 4 | let [x, ... 5 | -------------------------------------------------------------------------------- /spec/examples/type_definition_field: -------------------------------------------------------------------------------- 1 | -----------------------------------------type_definition_field_expected_colon 2 | type A { 3 | x 4 | ------------------------------------------type_definition_field_expected_type 5 | type A { 6 | x: 7 | ---------------------------------------type_definition_field_expected_mapping 8 | type A { 9 | x: String using 10 | -------------------------------------------------------------------------------- /spec/examples/type_destructuring: -------------------------------------------------------------------------------- 1 | --------------------------------type_destructuring_expected_closing_parenthesis 2 | module Test { 3 | fun toString (status : Status) : String { 4 | case (status) { 5 | A.B( 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /spec/examples/type_variable: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------- 2 | component Main { 3 | fun render : a { 4 | "" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /spec/examples/type_variant: -------------------------------------------------------------------------------- 1 | --------------------------------------type_variant_expected_closing_parenthesis 2 | type Test { 3 | A( 4 | -------------------------------------------------------------------------------- /spec/examples/unary_minus: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------unary_minus_not_number 2 | component Main { 3 | fun render : String { 4 | -"ASD" 5 | 6 | "" 7 | } 8 | } 9 | ------------------------------------------------------------------------------- 10 | component Main { 11 | fun render : String { 12 | -(10) 13 | 14 | "" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /spec/examples/void: -------------------------------------------------------------------------------- 1 | component A { 2 | fun test : Void { 3 | void 4 | } 5 | 6 | fun render : String { 7 | "" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /spec/fixtures/Test.mint: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : Html { 3 |
4 | } 5 | } 6 | -------------------------------------------------------------------------------- /spec/fixtures/data.txt: -------------------------------------------------------------------------------- 1 | Hello World! 2 | -------------------------------------------------------------------------------- /spec/fixtures/icon-no-dimensions: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /spec/fixtures/icon-no-svg-tag: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /spec/fixtures/icon-not-svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /spec/fixtures/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /spec/formatters/argument: -------------------------------------------------------------------------------- 1 | module A { 2 | fun test(a:String, b : Float) : Float { 3 | b 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | module A { 8 | fun test (a : String, b : Float) : Float { 9 | b 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/formatters/array_destructuring: -------------------------------------------------------------------------------- 1 | module Test { 2 | fun test : String { 3 | case [] { 4 | [a, b, ...rest] => "" 5 | => "" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- 10 | module Test { 11 | fun test : String { 12 | case [] { 13 | [a, b, ...rest] => "" 14 | => "" 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /spec/formatters/array_empty: -------------------------------------------------------------------------------- 1 | module Test { 2 | fun test : Array(String) { 3 | [ 4 | ] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- 8 | module Test { 9 | fun test : Array(String) { 10 | [] 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /spec/formatters/array_multiple: -------------------------------------------------------------------------------- 1 | module Test { 2 | fun test : Array(String) { 3 | [ 4 | "Hello", "Blah", "Joe" 5 | ] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- 9 | module Test { 10 | fun test : Array(String) { 11 | ["Hello", "Blah", "Joe"] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /spec/formatters/array_single: -------------------------------------------------------------------------------- 1 | module Test { 2 | fun test : Array(String) { 3 | ["Hello"] 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | module Test { 8 | fun test : Array(String) { 9 | ["Hello"] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/formatters/array_with_multi_line_item: -------------------------------------------------------------------------------- 1 | module Test { 2 | fun test : Array(String) { 3 | [ 4 | "Hello 5 | World!", "Blah", "Joe" 6 | ] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- 10 | module Test { 11 | fun test : Array(String) { 12 | [ 13 | "Hello 14 | World!", 15 | "Blah", 16 | "Joe" 17 | ] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /spec/formatters/array_with_type: -------------------------------------------------------------------------------- 1 | module Test { 2 | fun test : Array(String) { 3 | [] of String 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | module Test { 8 | fun test : Array(String) { 9 | [] of String 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/formatters/bool_literal_false: -------------------------------------------------------------------------------- 1 | module A { 2 | fun test : Bool { 3 | false 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | module A { 8 | fun test : Bool { 9 | false 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/formatters/bool_literal_true: -------------------------------------------------------------------------------- 1 | module A { 2 | fun test : Bool { 3 | true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | module A { 8 | fun test : Bool { 9 | true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/formatters/bracket_access: -------------------------------------------------------------------------------- 1 | module Test { 2 | fun test : Maybe(String) { 3 | ["Hello"][ 0 ] 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | module Test { 8 | fun test : Maybe(String) { 9 | ["Hello"][0] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/formatters/case: -------------------------------------------------------------------------------- 1 | module Test { 2 | fun test : String { 3 | case("Hello"){"a"=>"a""b"=>"b"=> "others"} 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | module Test { 8 | fun test : String { 9 | case "Hello" { 10 | "a" => "a" 11 | "b" => "b" 12 | => "others" 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /spec/formatters/comment: -------------------------------------------------------------------------------- 1 | /*SomeCommentHere*/ 2 | -------------------------------------------------------------------------------- 3 | /* SomeCommentHere */ 4 | -------------------------------------------------------------------------------- /spec/formatters/comment_multiline: -------------------------------------------------------------------------------- 1 | /*SomeCommentHere 2 | and other line here*/ 3 | -------------------------------------------------------------------------------- 4 | /* 5 | SomeCommentHere 6 | and other line here 7 | */ 8 | -------------------------------------------------------------------------------- /spec/formatters/comment_multiple: -------------------------------------------------------------------------------- 1 | // Comment A 2 | // Comment B 3 | -------------------------------------------------------------------------------- 4 | // Comment A 5 | // Comment B 6 | -------------------------------------------------------------------------------- /spec/formatters/comment_multiple_2: -------------------------------------------------------------------------------- 1 | // Comment A 2 | 3 | // Comment B 4 | -------------------------------------------------------------------------------- 5 | // Comment A 6 | 7 | // Comment B 8 | -------------------------------------------------------------------------------- /spec/formatters/comment_multiple_3: -------------------------------------------------------------------------------- 1 | module Test { 2 | fun test : String { 3 | // Comment E 4 | // Comment F 5 | "" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- 9 | module Test { 10 | fun test : String { 11 | // Comment E 12 | // Comment F 13 | "" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /spec/formatters/component: -------------------------------------------------------------------------------- 1 | componentTest{fun render:Html{
}} 2 | -------------------------------------------------------------------------------- 3 | component Test { 4 | fun render : Html { 5 |
6 | } 7 | } 8 | -------------------------------------------------------------------------------- /spec/formatters/constant_component: -------------------------------------------------------------------------------- 1 | component Test { 2 | /* Comment */constNAME="hello" 3 | 4 | fun render : Html { 5 |
6 | } 7 | } 8 | -------------------------------------------------------------------------------- 9 | component Test { 10 | /* Comment */ 11 | const NAME = "hello" 12 | 13 | fun render : Html { 14 |
15 | } 16 | } 17 | -------------------------------------------------------------------------------- /spec/formatters/constant_module: -------------------------------------------------------------------------------- 1 | module Test { 2 | /* Comment */constNAME="hello" 3 | } 4 | -------------------------------------------------------------------------------- 5 | module Test { 6 | /* Comment */ 7 | const NAME = "hello" 8 | } 9 | -------------------------------------------------------------------------------- /spec/formatters/constant_store: -------------------------------------------------------------------------------- 1 | store Test { 2 | /* Comment */constNAME="hello" 3 | } 4 | -------------------------------------------------------------------------------- 5 | store Test { 6 | /* Comment */ 7 | const NAME = "hello" 8 | } 9 | -------------------------------------------------------------------------------- /spec/formatters/css: -------------------------------------------------------------------------------- 1 | component A { 2 | styletest{background: red;color: blue;} 3 | 4 | fun render : Html { 5 |
6 | } 7 | } 8 | -------------------------------------------------------------------------------- 9 | component A { 10 | style test { 11 | background: red; 12 | color: blue; 13 | } 14 | 15 | fun render : Html { 16 |
17 | } 18 | } 19 | -------------------------------------------------------------------------------- /spec/formatters/css_with_arguments: -------------------------------------------------------------------------------- 1 | component A { 2 | styletest(name:String){background: red;color: blue;} 3 | 4 | fun render : Html { 5 |
6 | } 7 | } 8 | -------------------------------------------------------------------------------- 9 | component A { 10 | style test (name : String) { 11 | background: red; 12 | color: blue; 13 | } 14 | 15 | fun render : Html { 16 |
17 | } 18 | } 19 | -------------------------------------------------------------------------------- /spec/formatters/css_with_interpolation: -------------------------------------------------------------------------------- 1 | component A { 2 | styletest{background: #{ "red" 3 | };color: blue;} 4 | 5 | fun render : Html { 6 |
7 | } 8 | } 9 | -------------------------------------------------------------------------------- 10 | component A { 11 | style test { 12 | background: #{"red"}; 13 | color: blue; 14 | } 15 | 16 | fun render : Html { 17 |
18 | } 19 | } 20 | -------------------------------------------------------------------------------- /spec/formatters/css_with_line_separation: -------------------------------------------------------------------------------- 1 | component A { 2 | styletest{background: red; 3 | 4 | color: blue;} 5 | 6 | fun render : Html { 7 |
8 | } 9 | } 10 | -------------------------------------------------------------------------------- 11 | component A { 12 | style test { 13 | background: red; 14 | 15 | color: blue; 16 | } 17 | 18 | fun render : Html { 19 |
20 | } 21 | } 22 | -------------------------------------------------------------------------------- /spec/formatters/dbg: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | dbg "Hello World!" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | component Main { 8 | fun render : String { 9 | dbg "Hello World!" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/formatters/dbg_with_bang: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | dbg! "Hello World!" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | component Main { 8 | fun render : String { 9 | dbg! "Hello World!" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/formatters/directives/asset: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | @asset(../../fixtures/data.txt) 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | component Main { 8 | fun render : String { 9 | @asset(../../fixtures/data.txt) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/formatters/directives/format: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | let{result, formatted}=@format{"Hello"} 4 | result + formatted 5 | } 6 | } 7 | -------------------------------------------------------------------------------- 8 | component Main { 9 | fun render : String { 10 | let {result, formatted} = 11 | @format { 12 | "Hello" 13 | } 14 | 15 | result + formatted 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /spec/formatters/directives/highlight-file: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : Html { 3 | @highlight-file(../../fixtures/Test.mint) 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | component Main { 8 | fun render : Html { 9 | @highlight-file(../../fixtures/Test.mint) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/formatters/directives/inline: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | @inline(../../fixtures/data.txt) 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | component Main { 8 | fun render : String { 9 | @inline(../../fixtures/data.txt) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/formatters/directives/svg: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : Html { 3 | @svg(../../fixtures/icon.svg) 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | component Main { 8 | fun render : Html { 9 | @svg(../../fixtures/icon.svg) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/formatters/env: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | @TEST 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | component Main { 8 | fun render : String { 9 | @TEST 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/formatters/field: -------------------------------------------------------------------------------- 1 | type Test { 2 | a : String 3 | } 4 | 5 | module Test { 6 | fun get : Test { 7 | {a:"Hello"} 8 | } 9 | } 10 | -------------------------------------------------------------------------------- 11 | type Test { 12 | a : String 13 | } 14 | 15 | module Test { 16 | fun get : Test { 17 | { a: "Hello" } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /spec/formatters/field_access: -------------------------------------------------------------------------------- 1 | type Test { 2 | test : String 3 | } 4 | 5 | component Main { 6 | fun render : String { 7 | .test(Test)({ test: "Hello" }) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- 11 | type Test { 12 | test : String 13 | } 14 | 15 | component Main { 16 | fun render : String { 17 | .test(Test)({ test: "Hello" }) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /spec/formatters/font_face: -------------------------------------------------------------------------------- 1 | component Main { 2 | style main { 3 | @font-face { 4 | color: red; 5 | } 6 | } 7 | 8 | fun render { 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- 13 | component Main { 14 | style main { 15 | @font-face { 16 | color: red; 17 | } 18 | } 19 | 20 | fun render { 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /spec/formatters/for: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : Array(String) { 3 | for (item of ["B"]){item}when{item == "A"} 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | component Main { 8 | fun render : Array(String) { 9 | for item of ["B"] { 10 | item 11 | } when { 12 | item == "A" 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /spec/formatters/function: -------------------------------------------------------------------------------- 1 | module A { 2 | /* Comment */funtest(a:String):Void{/*HEAD*/void/*TAIL*/} 3 | } 4 | -------------------------------------------------------------------------------- 5 | module A { 6 | /* Comment */ 7 | fun test (a : String) : Void { 8 | /* HEAD */ 9 | void 10 | 11 | /* TAIL */ 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /spec/formatters/function_without_type: -------------------------------------------------------------------------------- 1 | module A { 2 | /* Comment */fun test(a:String){/*HEAD*/void/*TAIL*/} 3 | } 4 | -------------------------------------------------------------------------------- 5 | module A { 6 | /* Comment */ 7 | fun test (a : String) { 8 | /* HEAD */ 9 | void 10 | 11 | /* TAIL */ 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /spec/formatters/get: -------------------------------------------------------------------------------- 1 | component Test { 2 | /*HEAD*/gettest:Number{/*A*/0/*B*/} 3 | 4 | fun render : Html { 5 |
6 | } 7 | } 8 | -------------------------------------------------------------------------------- 9 | component Test { 10 | /* HEAD */ 11 | get test : Number { 12 | /* A */ 13 | 0 14 | 15 | /* B */ 16 | } 17 | 18 | fun render : Html { 19 |
20 | } 21 | } 22 | -------------------------------------------------------------------------------- /spec/formatters/get_without_type: -------------------------------------------------------------------------------- 1 | component Test { 2 | /*HEAD*/get test{/*A*/0/*B*/} 3 | 4 | fun render : Html { 5 |
6 | } 7 | } 8 | -------------------------------------------------------------------------------- 9 | component Test { 10 | /* HEAD */ 11 | get test { 12 | /* A */ 13 | 0 14 | 15 | /* B */ 16 | } 17 | 18 | fun render : Html { 19 |
20 | } 21 | } 22 | -------------------------------------------------------------------------------- /spec/formatters/html_component: -------------------------------------------------------------------------------- 1 | component Test { 2 | fun render : Html { 3 |
4 | } 5 | } 6 | 7 | component X { 8 | fun render : Html { 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- 13 | component Test { 14 | fun render : Html { 15 |
16 | } 17 | } 18 | 19 | component X { 20 | fun render : Html { 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /spec/formatters/html_element: -------------------------------------------------------------------------------- 1 | component Test { 2 | style base { 3 | color: red; 4 | } 5 | 6 | fun render : Html { 7 | 8 |
9 | } 10 | } 11 | -------------------------------------------------------------------------------- 12 | component Test { 13 | style base { 14 | color: red; 15 | } 16 | 17 | fun render : Html { 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /spec/formatters/html_element_single_line: -------------------------------------------------------------------------------- 1 | component Test { 2 | style base { 3 | color: red; 4 | } 5 | 6 | fun render : Html { 7 | "Hello"
8 | } 9 | } 10 | -------------------------------------------------------------------------------- 11 | component Test { 12 | style base { 13 | color: red; 14 | } 15 | 16 | fun render : Html { 17 | "Hello"
18 | } 19 | } 20 | -------------------------------------------------------------------------------- /spec/formatters/html_fragment: -------------------------------------------------------------------------------- 1 | component Test { 2 | fun render : Html { 3 | <> 4 | "Hello There" 5 | 6 | <> 7 | <>"AA" 8 | 9 | } 10 | } 11 | -------------------------------------------------------------------------------- 12 | component Test { 13 | fun render : Html { 14 | <> 15 | "Hello There" 16 | 17 | <> 18 | <>"AA" 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /spec/formatters/if_with_else_if: -------------------------------------------------------------------------------- 1 | module Test { 2 | fun test : Bool { 3 | if(true){ true }elseif(false){false}else{true} 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | module Test { 8 | fun test : Bool { 9 | if true { 10 | true 11 | } else if false { 12 | false 13 | } else { 14 | true 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /spec/formatters/inline_comment: -------------------------------------------------------------------------------- 1 | //A single inline comment 2 | -------------------------------------------------------------------------------- 3 | // A single inline comment 4 | -------------------------------------------------------------------------------- /spec/formatters/inline_function: -------------------------------------------------------------------------------- 1 | module A { 2 | fun test : String { 3 | let a = ():String{"Hello"} 4 | a() 5 | } 6 | } 7 | -------------------------------------------------------------------------------- 8 | module A { 9 | fun test : String { 10 | let a = 11 | () : String { "Hello" } 12 | 13 | a() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /spec/formatters/js: -------------------------------------------------------------------------------- 1 | module Test { 2 | fun test : String { 3 | ` "Hello" ` 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | module Test { 8 | fun test : String { 9 | ` "Hello" ` 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/formatters/js_multiline: -------------------------------------------------------------------------------- 1 | module Test { 2 | fun test : String { 3 | ` 4 | "Hello" 5 | asd 6 | asd 7 | asd 8 | ` 9 | } 10 | } 11 | -------------------------------------------------------------------------------- 12 | module Test { 13 | fun test : String { 14 | ` 15 | "Hello" 16 | asd 17 | asd 18 | asd 19 | ` 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /spec/formatters/js_multiline_with_backtick: -------------------------------------------------------------------------------- 1 | module Test { 2 | fun test : String { 3 | ` 4 | "Hello"\` 5 | ` 6 | } 7 | } 8 | -------------------------------------------------------------------------------- 9 | module Test { 10 | fun test : String { 11 | ` 12 | "Hello"\` 13 | ` 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /spec/formatters/js_with_backtick: -------------------------------------------------------------------------------- 1 | module Test { 2 | fun test : String { 3 | `\`"Hello"` 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | module Test { 8 | fun test : String { 9 | `\`"Hello"` 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/formatters/js_with_type: -------------------------------------------------------------------------------- 1 | module Test { 2 | fun test : String { 3 | `"Hello"` as String 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | module Test { 8 | fun test : String { 9 | `"Hello"` as String 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/formatters/locale: -------------------------------------------------------------------------------- 1 | locale en { 2 | ui: { 3 | button: { 4 | ok: "OK" 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- 9 | locale en { 10 | ui: { button: { ok: "OK" } } 11 | } 12 | -------------------------------------------------------------------------------- /spec/formatters/locale_key: -------------------------------------------------------------------------------- 1 | locale en { 2 | ui: { 3 | button: { 4 | ok: "OK" 5 | } 6 | } 7 | } 8 | 9 | component Main { 10 | fun render : String { 11 | :ui.button.ok 12 | } 13 | } 14 | -------------------------------------------------------------------------------- 15 | locale en { 16 | ui: { button: { ok: "OK" } } 17 | } 18 | 19 | component Main { 20 | fun render : String { 21 | :ui.button.ok 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /spec/formatters/map_with_type: -------------------------------------------------------------------------------- 1 | module Test { 2 | fun test : Map(String, String) { 3 | {"a" => "Hello" } of String => String 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | module Test { 8 | fun test : Map(String, String) { 9 | { "a" => "Hello" } of String => String 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/formatters/module: -------------------------------------------------------------------------------- 1 | moduleA{fun a () : String { "" }} 2 | -------------------------------------------------------------------------------- 3 | module A { 4 | fun a : String { 5 | "" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /spec/formatters/module_access: -------------------------------------------------------------------------------- 1 | module Test { 2 | fun a : String { 3 | "Hello" 4 | } 5 | 6 | fun b : Function(String) { 7 | Test.a 8 | } 9 | } 10 | -------------------------------------------------------------------------------- 11 | module Test { 12 | fun a : String { 13 | "Hello" 14 | } 15 | 16 | fun b : Function(String) { 17 | Test.a 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /spec/formatters/module_call: -------------------------------------------------------------------------------- 1 | module Test { 2 | fun a : String { 3 | "Hello" 4 | } 5 | 6 | fun b : String { 7 | Test.a() 8 | } 9 | } 10 | -------------------------------------------------------------------------------- 11 | module Test { 12 | fun a : String { 13 | "Hello" 14 | } 15 | 16 | fun b : String { 17 | Test.a() 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /spec/formatters/module_call_piped: -------------------------------------------------------------------------------- 1 | module Test { 2 | fun a (value : String) : String { 3 | value 4 | } 5 | 6 | fun b : String { 7 | "Hello" |> Test.a() 8 | } 9 | } 10 | -------------------------------------------------------------------------------- 11 | module Test { 12 | fun a (value : String) : String { 13 | value 14 | } 15 | 16 | fun b : String { 17 | "Hello" 18 | |> Test.a() 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /spec/formatters/module_multiple: -------------------------------------------------------------------------------- 1 | module A { 2 | fun a : String { 3 | "" 4 | } 5 | } 6 | 7 | module A { 8 | fun b : String { 9 | "" 10 | } 11 | } 12 | 13 | -------------------------------------------------------------------------------- 14 | module A { 15 | fun a : String { 16 | "" 17 | } 18 | } 19 | 20 | module A { 21 | fun b : String { 22 | "" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /spec/formatters/module_with_comments: -------------------------------------------------------------------------------- 1 | /* Comment */moduleA{/*A*/fun a () : String { "" }/*B*//*C*/} 2 | -------------------------------------------------------------------------------- 3 | /* Comment */ 4 | module A { 5 | /* A */ 6 | fun a : String { 7 | "" 8 | } 9 | 10 | /* B */ 11 | 12 | /* C */ 13 | } 14 | -------------------------------------------------------------------------------- /spec/formatters/negated_expression: -------------------------------------------------------------------------------- 1 | module Test { 2 | fun test : Bool { 3 | !!!!!true && !!!!false && !false 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | module Test { 8 | fun test : Bool { 9 | !true && !!false && !false 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/formatters/number_literal_negative: -------------------------------------------------------------------------------- 1 | module A { 2 | fun test : Number { 3 | -(10 - 20) 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | module A { 8 | fun test : Number { 9 | -(10 - 20) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/formatters/number_literal_simple: -------------------------------------------------------------------------------- 1 | module A { 2 | fun test : Number { 3 | 10 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | module A { 8 | fun test : Number { 9 | 10 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/formatters/number_literal_with_decimals: -------------------------------------------------------------------------------- 1 | module A { 2 | fun test : Number { 3 | 0.100 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | module A { 8 | fun test : Number { 9 | 0.100 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/formatters/operation: -------------------------------------------------------------------------------- 1 | module Test { 2 | fun test : Bool { 3 | "Hello" == "True" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | module Test { 8 | fun test : Bool { 9 | "Hello" == "True" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/formatters/operation_multi_line: -------------------------------------------------------------------------------- 1 | module Test { 2 | fun test : Bool { 3 | "Hello" == "True" && 4 | "a" == "b" && 5 | "c" == "d" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- 9 | module Test { 10 | fun test : Bool { 11 | "Hello" == "True" && "a" == "b" && "c" == "d" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /spec/formatters/operation_with_comment: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun render : String { 3 | "Hello" // Some comment 4 | + "There" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- 8 | component Main { 9 | fun render : String { 10 | "Hello" // Some comment 11 | + "There" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /spec/formatters/parenthesized_expression: -------------------------------------------------------------------------------- 1 | module Test { 2 | fun test : Bool { 3 | ( true 4 | ) 5 | } 6 | } 7 | -------------------------------------------------------------------------------- 8 | module Test { 9 | fun test : Bool { 10 | (true) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /spec/formatters/property: -------------------------------------------------------------------------------- 1 | component Test { 2 | /* Comment */propertyname:String="hello" 3 | 4 | fun render : Html { 5 |
6 | } 7 | } 8 | -------------------------------------------------------------------------------- 9 | component Test { 10 | /* Comment */ 11 | property name : String = "hello" 12 | 13 | fun render : Html { 14 |
15 | } 16 | } 17 | -------------------------------------------------------------------------------- /spec/formatters/property_without_type: -------------------------------------------------------------------------------- 1 | component Test { 2 | /* Comment */property name="hello" 3 | 4 | fun render : Html { 5 |
6 | } 7 | } 8 | -------------------------------------------------------------------------------- 9 | component Test { 10 | /* Comment */ 11 | property name = "hello" 12 | 13 | fun render : Html { 14 |
15 | } 16 | } 17 | -------------------------------------------------------------------------------- /spec/formatters/provider: -------------------------------------------------------------------------------- 1 | type Subscription { 2 | a : Bool 3 | } 4 | 5 | providerProvider:Subscription { 6 | fun test : Void { 7 | void 8 | } 9 | } 10 | -------------------------------------------------------------------------------- 11 | type Subscription { 12 | a : Bool 13 | } 14 | 15 | provider Provider : Subscription { 16 | fun test : Void { 17 | void 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /spec/formatters/record_singleline: -------------------------------------------------------------------------------- 1 | type A { 2 | a : String 3 | } 4 | 5 | module Test { 6 | fun test : A { 7 | { 8 | a:"Hello" 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- 13 | type A { 14 | a : String 15 | } 16 | 17 | module Test { 18 | fun test : A { 19 | { a: "Hello" } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /spec/formatters/regexp_literal: -------------------------------------------------------------------------------- 1 | component Main { 2 | fun regexp : Regexp { 3 | /.*/gm 4 | } 5 | 6 | fun render : String { 7 | regexp() 8 | 9 | "" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- 13 | component Main { 14 | fun regexp : Regexp { 15 | /.*/gm 16 | } 17 | 18 | fun render : String { 19 | regexp() 20 | 21 | "" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /spec/formatters/routes: -------------------------------------------------------------------------------- 1 | routes { 2 | /test{void} 3 | /test2(a:String){void} 4 | } 5 | -------------------------------------------------------------------------------- 6 | routes { 7 | /test { 8 | void 9 | } 10 | 11 | /test2 (a : String) { 12 | void 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /spec/formatters/routes_await: -------------------------------------------------------------------------------- 1 | routes { 2 | /test await {void} 3 | } 4 | -------------------------------------------------------------------------------- 5 | routes { 6 | /test await { 7 | void 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /spec/formatters/routes_with_comments: -------------------------------------------------------------------------------- 1 | routes { 2 | /*A*/ 3 | /test{/*C*/void/*D*/} 4 | /*B*/ 5 | /test2(a:String){void} 6 | } 7 | -------------------------------------------------------------------------------- 8 | routes { 9 | /* A */ 10 | /test { 11 | /* C */ 12 | void 13 | 14 | /* D */ 15 | } 16 | 17 | /* B */ 18 | /test2 (a : String) { 19 | void 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /spec/formatters/state: -------------------------------------------------------------------------------- 1 | component Test { 2 | statea:Number=0 3 | stateb:String="hello" 4 | fun render : Html { 5 |
6 | } 7 | } 8 | -------------------------------------------------------------------------------- 9 | component Test { 10 | state a : Number = 0 11 | state b : String = "hello" 12 | 13 | fun render : Html { 14 |
15 | } 16 | } 17 | -------------------------------------------------------------------------------- /spec/formatters/state_without_type: -------------------------------------------------------------------------------- 1 | component Test { 2 | state a=0 3 | state b="hello" 4 | fun render : Html { 5 |
6 | } 7 | } 8 | -------------------------------------------------------------------------------- 9 | component Test { 10 | state a = 0 11 | state b = "hello" 12 | 13 | fun render : Html { 14 |
15 | } 16 | } 17 | -------------------------------------------------------------------------------- /spec/formatters/statement: -------------------------------------------------------------------------------- 1 | module A { 2 | fun test : Bool { 3 | letx="hello"lety=0letz=1 4 | true 5 | } 6 | } 7 | -------------------------------------------------------------------------------- 8 | module A { 9 | fun test : Bool { 10 | let x = 11 | "hello" 12 | 13 | let y = 14 | 0 15 | 16 | let z = 17 | 1 18 | 19 | true 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /spec/formatters/statement_with_await: -------------------------------------------------------------------------------- 1 | module A { 2 | fun test : Promise(String) { 3 | letx=await"hello" 4 | "" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- 8 | module A { 9 | fun test : Promise(String) { 10 | let x = 11 | await "hello" 12 | 13 | "" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /spec/formatters/store: -------------------------------------------------------------------------------- 1 | storeTest{state a : Number = 0} 2 | -------------------------------------------------------------------------------- 3 | store Test { 4 | state a : Number = 0 5 | } 6 | -------------------------------------------------------------------------------- /spec/formatters/store_with_comments: -------------------------------------------------------------------------------- 1 | /*A*/storeTest{/*B*/state a : Number = 0/*C*/} 2 | -------------------------------------------------------------------------------- 3 | /* A */ 4 | store Test { 5 | /* B */ 6 | state a : Number = 0 7 | 8 | /* C */ 9 | } 10 | -------------------------------------------------------------------------------- /spec/formatters/string_literal_escaped: -------------------------------------------------------------------------------- 1 | module A { 2 | fun test : String { 3 | "Hello there \"Joe\"" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | module A { 8 | fun test : String { 9 | "Hello there \"Joe\"" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/formatters/string_literal_multiline: -------------------------------------------------------------------------------- 1 | module A { 2 | fun test : String { 3 | " 4 | Hello there 5 | Hello there 6 | Hello there 7 | " 8 | } 9 | } 10 | -------------------------------------------------------------------------------- 11 | module A { 12 | fun test : String { 13 | " 14 | Hello there 15 | Hello there 16 | Hello there 17 | " 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /spec/formatters/string_literal_simple: -------------------------------------------------------------------------------- 1 | module A { 2 | fun test : String { 3 | "Hello there" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | module A { 8 | fun test : String { 9 | "Hello there" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/formatters/string_literal_with_interpolation: -------------------------------------------------------------------------------- 1 | module A { 2 | fun test : String { 3 | "Hello there #{"Joe"}" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | module A { 8 | fun test : String { 9 | "Hello there #{"Joe"}" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/formatters/suite: -------------------------------------------------------------------------------- 1 | suite"X"{test"X"{true}} 2 | -------------------------------------------------------------------------------- 3 | suite "X" { 4 | test "X" { 5 | true 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /spec/formatters/suite_with_comments: -------------------------------------------------------------------------------- 1 | suite"X"{/*A*/test"X"{/*B*/true/*C*/}} 2 | -------------------------------------------------------------------------------- 3 | suite "X" { 4 | /* A */ 5 | test "X" { 6 | /* B */ 7 | true 8 | 9 | /* C */ 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/formatters/tuple_destructuring: -------------------------------------------------------------------------------- 1 | module Test { 2 | fun test : String { 3 | let {a, b} = 4 | {"A", "B"} 5 | 6 | a 7 | } 8 | } 9 | -------------------------------------------------------------------------------- 10 | module Test { 11 | fun test : String { 12 | let {a, b} = 13 | {"A", "B"} 14 | 15 | a 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /spec/formatters/type: -------------------------------------------------------------------------------- 1 | type Test { 2 | number : Result(Number,Array(String)), 3 | param : Error(Bool), 4 | string : String 5 | } 6 | -------------------------------------------------------------------------------- 7 | type Test { 8 | number : Result(Number, Array(String)), 9 | param : Error(Bool), 10 | string : String 11 | } 12 | -------------------------------------------------------------------------------- /spec/formatters/type_definition: -------------------------------------------------------------------------------- 1 | typeTest{a:String,b:Blah} 2 | -------------------------------------------------------------------------------- 3 | type Test { 4 | a : String, 5 | b : Blah 6 | } 7 | -------------------------------------------------------------------------------- /spec/formatters/type_definition_broken_variant: -------------------------------------------------------------------------------- 1 | type A { 2 | B(name2 : String, name1 : String, name : String, color2 : String, color1 : String, color : String) 3 | C 4 | } 5 | -------------------------------------------------------------------------------- 6 | type A { 7 | B( 8 | name2 : String, 9 | name1 : String, 10 | name : String, 11 | color2 : String, 12 | color1 : String, 13 | color : String) 14 | 15 | C 16 | } 17 | -------------------------------------------------------------------------------- /spec/formatters/type_definition_with_comments: -------------------------------------------------------------------------------- 1 | /*A*/typeTest{ 2 | /*B*/a:String,/*C*/b:Blah// End comment 3 | } 4 | -------------------------------------------------------------------------------- 5 | /* A */ 6 | type Test { 7 | /* B */ 8 | a : String, 9 | 10 | /* C */ 11 | b : Blah 12 | 13 | // End comment 14 | } 15 | -------------------------------------------------------------------------------- /spec/formatters/type_definition_with_new_lines: -------------------------------------------------------------------------------- 1 | type Test { 2 | a:String, 3 | 4 | b:Blah 5 | } 6 | -------------------------------------------------------------------------------- 7 | type Test { 8 | a : String, 9 | 10 | b : Blah 11 | } 12 | -------------------------------------------------------------------------------- /spec/formatters/type_definition_with_using: -------------------------------------------------------------------------------- 1 | typeTest{a:String using "blah",b:Blah using "what"} 2 | -------------------------------------------------------------------------------- 3 | type Test { 4 | a : String using "blah", 5 | b : Blah using "what" 6 | } 7 | -------------------------------------------------------------------------------- /spec/formatters/type_with_parameters: -------------------------------------------------------------------------------- 1 | module Test { 2 | fun a : Array(Result(String,String)) { [] } 3 | } 4 | -------------------------------------------------------------------------------- 5 | module Test { 6 | fun a : Array(Result(String, String)) { 7 | [] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /spec/formatters/unary_minus: -------------------------------------------------------------------------------- 1 | module A { 2 | fun test : Number { 3 | -(10 + 20) 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | module A { 8 | fun test : Number { 9 | -(10 + 20) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/formatters/void: -------------------------------------------------------------------------------- 1 | module A { 2 | fun test : Void { 3 | void 4 | } 5 | } 6 | -------------------------------------------------------------------------------- 7 | module A { 8 | fun test : Void { 9 | void 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /spec/mint.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ROOT FOR TESTS" 3 | } 4 | -------------------------------------------------------------------------------- /spec/mint_json/invalid_json: -------------------------------------------------------------------------------- 1 | { 2 | , 3 | } 4 | -------------------------------------------------------------------------------- 5 | ░ ERROR (INVALID_JSON) ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 6 | 7 | I could not parse the following mint.json file: 8 | 9 | ┌ spec/fixtures/mint.json:2:3 10 | ├──────────────────────────── 11 | 1│ { 12 | 2│ , 13 | │ ⌃ 14 | 3│ } 15 | -------------------------------------------------------------------------------- /spec/mint_json/name_empty: -------------------------------------------------------------------------------- 1 | { 2 | "name": "" 3 | } 4 | -------------------------------------------------------------------------------- 5 | ░ ERROR (NAME_EMPTY) ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 6 | 7 | The name field should not be empty: 8 | 9 | ┌ spec/fixtures/mint.json:2:11 10 | ├───────────────────────────── 11 | 1│ { 12 | 2│ "name": "" 13 | │ ⌃ 14 | 3│ } 15 | -------------------------------------------------------------------------------- /spec/mint_json/name_invalid: -------------------------------------------------------------------------------- 1 | { 2 | "name": 0 3 | } 4 | -------------------------------------------------------------------------------- 5 | ░ ERROR (NAME_INVALID) ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 6 | 7 | The name field should be a string, but it's not: 8 | 9 | ┌ spec/fixtures/mint.json:2:11 10 | ├───────────────────────────── 11 | 1│ { 12 | 2│ "name": 0 13 | │ ⌃ 14 | 3│ } 15 | -------------------------------------------------------------------------------- /spec/mint_json/root_invalid: -------------------------------------------------------------------------------- 1 | "" 2 | -------------------------------------------------------------------------------- 3 | ░ ERROR (ROOT_INVALID) ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 4 | 5 | The root item should be an object, but it's not: 6 | 7 | ┌ spec/fixtures/mint.json:1:2 8 | ├──────────────────────────── 9 | 1│ "" 10 | -------------------------------------------------------------------------------- /spec/mint_json/root_invalid_key: -------------------------------------------------------------------------------- 1 | { 2 | "x": "y" 3 | } 4 | -------------------------------------------------------------------------------- 5 | ░ ERROR (ROOT_INVALID_KEY) ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 6 | 7 | The root object has an invalid key: 8 | 9 | x 10 | 11 | It is here: 12 | 13 | ┌ spec/fixtures/mint.json:2:8 14 | ├──────────────────────────── 15 | 1│ { 16 | 2│ "x": "y" 17 | │ ⌃ 18 | 3│ } 19 | -------------------------------------------------------------------------------- /spec/name_pool_spec.cr: -------------------------------------------------------------------------------- 1 | require "./spec_helper" 2 | 3 | describe Mint::NamePool do 4 | it "returns next name" do 5 | pool = Mint::NamePool(String, Mint::StyleBuilder::Selector).new 6 | object = Mint::StyleBuilder::Selector.new 7 | 8 | pool.of("a", object).should eq("a") 9 | pool.of("a", object).should eq("a") 10 | pool.of("b", object).should eq("b") 11 | pool.of("c", object).should eq("c") 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/assets.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Assets 3 | extend BakedFileSystem 4 | 5 | bake_folder "./assets" 6 | 7 | def self.read?(path) 8 | get?(path).try(&.gets_to_end) 9 | end 10 | 11 | def self.read(path) 12 | get(path).gets_to_end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /src/assets/docs/fonts/fira-code-v22-latin_latin-ext-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mint-lang/mint/80785f6098217b9297a00c5e38b7e80e0ea81931/src/assets/docs/fonts/fira-code-v22-latin_latin-ext-regular.woff2 -------------------------------------------------------------------------------- /src/assets/docs/fonts/forum-v18-latin_latin-ext-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mint-lang/mint/80785f6098217b9297a00c5e38b7e80e0ea81931/src/assets/docs/fonts/forum-v18-latin_latin-ext-regular.woff2 -------------------------------------------------------------------------------- /src/assets/docs/fonts/noto-sans-v36-latin_latin-ext-300.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mint-lang/mint/80785f6098217b9297a00c5e38b7e80e0ea81931/src/assets/docs/fonts/noto-sans-v36-latin_latin-ext-300.woff2 -------------------------------------------------------------------------------- /src/assets/docs/fonts/noto-sans-v36-latin_latin-ext-500.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mint-lang/mint/80785f6098217b9297a00c5e38b7e80e0ea81931/src/assets/docs/fonts/noto-sans-v36-latin_latin-ext-500.woff2 -------------------------------------------------------------------------------- /src/assets/docs/fonts/noto-sans-v36-latin_latin-ext-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mint-lang/mint/80785f6098217b9297a00c5e38b7e80e0ea81931/src/assets/docs/fonts/noto-sans-v36-latin_latin-ext-regular.woff2 -------------------------------------------------------------------------------- /src/assets/scaffold/.gitignore: -------------------------------------------------------------------------------- 1 | .mint 2 | dist 3 | -------------------------------------------------------------------------------- /src/assets/scaffold/assets/bottom-center.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mint-lang/mint/80785f6098217b9297a00c5e38b7e80e0ea81931/src/assets/scaffold/assets/bottom-center.png -------------------------------------------------------------------------------- /src/assets/scaffold/assets/bottom-left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mint-lang/mint/80785f6098217b9297a00c5e38b7e80e0ea81931/src/assets/scaffold/assets/bottom-left.png -------------------------------------------------------------------------------- /src/assets/scaffold/assets/bottom-right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mint-lang/mint/80785f6098217b9297a00c5e38b7e80e0ea81931/src/assets/scaffold/assets/bottom-right.png -------------------------------------------------------------------------------- /src/assets/scaffold/assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mint-lang/mint/80785f6098217b9297a00c5e38b7e80e0ea81931/src/assets/scaffold/assets/favicon.png -------------------------------------------------------------------------------- /src/assets/scaffold/assets/top-center.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mint-lang/mint/80785f6098217b9297a00c5e38b7e80e0ea81931/src/assets/scaffold/assets/top-center.png -------------------------------------------------------------------------------- /src/assets/scaffold/assets/top-left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mint-lang/mint/80785f6098217b9297a00c5e38b7e80e0ea81931/src/assets/scaffold/assets/top-left.png -------------------------------------------------------------------------------- /src/assets/scaffold/assets/top-right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mint-lang/mint/80785f6098217b9297a00c5e38b7e80e0ea81931/src/assets/scaffold/assets/top-right.png -------------------------------------------------------------------------------- /src/assets/scaffold/tests/Main.mint: -------------------------------------------------------------------------------- 1 | suite "Main" { 2 | test "h3 has the correct content" { 3 |
4 | |> Test.Html.start() 5 | |> Test.Html.assertTextOf("h3", "Hello there 👋") 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/ast/argument.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class Argument < Node 4 | getter type, name, default 5 | 6 | def initialize(@from : Parser::Location, 7 | @to : Parser::Location, 8 | @file : Parser::File, 9 | @default : Node?, 10 | @name : Variable, 11 | @type : Node) 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /src/ast/array_destructuring.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class ArrayDestructuring < Node 4 | getter items 5 | 6 | def initialize(@from : Parser::Location, 7 | @to : Parser::Location, 8 | @file : Parser::File, 9 | @items : Array(Node)) 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/ast/await.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class Await < Node 4 | getter body 5 | 6 | def initialize(@from : Parser::Location, 7 | @to : Parser::Location, 8 | @file : Parser::File, 9 | @body : Node) 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/ast/block.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class Block < Node 4 | getter expressions 5 | 6 | def initialize(@expressions : Array(Node), 7 | @from : Parser::Location, 8 | @to : Parser::Location, 9 | @file : Parser::File) 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/ast/bool_literal.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class BoolLiteral < Node 4 | getter value 5 | 6 | def initialize(@from : Parser::Location, 7 | @to : Parser::Location, 8 | @file : Parser::File, 9 | @value : Bool) 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/ast/bracket_access.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class BracketAccess < Node 4 | getter index, expression 5 | 6 | def initialize(@from : Parser::Location, 7 | @to : Parser::Location, 8 | @file : Parser::File, 9 | @expression : Node, 10 | @index : Node) 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/ast/builtin.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class Builtin < Node 4 | getter value 5 | 6 | def initialize(@from : Parser::Location, 7 | @to : Parser::Location, 8 | @file : Parser::File, 9 | @value : String) 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/ast/call.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class Call < Node 4 | getter arguments, expression, await 5 | 6 | def initialize(@arguments : Array(Field), 7 | @from : Parser::Location, 8 | @to : Parser::Location, 9 | @file : Parser::File, 10 | @expression : Node, 11 | @await : Bool) 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /src/ast/case_branch.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class CaseBranch < Node 4 | getter patterns, expression 5 | 6 | def initialize(@expression : Node | Array(CssDefinition), 7 | @from : Parser::Location, 8 | @patterns : Array(Node)?, 9 | @to : Parser::Location, 10 | @file : Parser::File) 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/ast/commented_expression.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class CommentedExpression < Node 4 | getter expression, comment 5 | 6 | def initialize(@from : Parser::Location, 7 | @to : Parser::Location, 8 | @file : Parser::File, 9 | @comment : Comment?, 10 | @expression : Node) 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/ast/connect.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class Connect < Node 4 | getter keys, store 5 | 6 | def initialize(@keys : Array(ConnectVariable), 7 | @from : Parser::Location, 8 | @to : Parser::Location, 9 | @file : Parser::File, 10 | @store : Id) 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/ast/connect_variable.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class ConnectVariable < Node 4 | getter target, name 5 | 6 | def initialize(@from : Parser::Location, 7 | @to : Parser::Location, 8 | @file : Parser::File, 9 | @target : Variable?, 10 | @name : Variable) 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/ast/css_definition.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class CssDefinition < Node 4 | getter name, value 5 | 6 | def initialize(@value : Array(String | Node), 7 | @from : Parser::Location, 8 | @to : Parser::Location, 9 | @file : Parser::File, 10 | @name : String) 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/ast/css_font_face.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class CssFontFace < Node 4 | getter definitions 5 | 6 | def initialize(@definitions : Array(Node), 7 | @from : Parser::Location, 8 | @to : Parser::Location, 9 | @file : Parser::File) 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/ast/css_keyframes.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class CssKeyframes < Node 4 | getter selectors, name 5 | 6 | def initialize(@selectors : Array(Node), 7 | @from : Parser::Location, 8 | @to : Parser::Location, 9 | @file : Parser::File, 10 | @name : String) 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/ast/css_selector.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class CssSelector < Node 4 | getter selectors, body 5 | 6 | def initialize(@selectors : Array(String), 7 | @from : Parser::Location, 8 | @to : Parser::Location, 9 | @file : Parser::File, 10 | @body : Array(Node)) 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/ast/dbg.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class Dbg < Node 4 | getter expression 5 | getter? bang 6 | 7 | def initialize(@from : Parser::Location, 8 | @to : Parser::Location, 9 | @file : Parser::File, 10 | @expression : Node?, 11 | @bang : Bool) 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /src/ast/decode.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class Decode < Node 4 | getter expression, type 5 | 6 | def initialize(@from : Parser::Location, 7 | @to : Parser::Location, 8 | @file : Parser::File, 9 | @expression : Node?, 10 | @type : Type) 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/ast/defer.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class Defer < Node 4 | getter body 5 | 6 | def initialize(@from : Parser::Location, 7 | @to : Parser::Location, 8 | @file : Parser::File, 9 | @body : Node) 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/ast/directives/format.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | module Directives 4 | class Format < Node 5 | getter content 6 | 7 | def initialize(@from : Parser::Location, 8 | @to : Parser::Location, 9 | @file : Parser::File, 10 | @content : Block) 11 | end 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /src/ast/directives/highlight.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | module Directives 4 | class Highlight < Node 5 | getter content 6 | 7 | def initialize(@from : Parser::Location, 8 | @to : Parser::Location, 9 | @file : Parser::File, 10 | @content : Block) 11 | end 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /src/ast/discard.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class Discard < Node 4 | def initialize(@from : Parser::Location, 5 | @to : Parser::Location, 6 | @file : Parser::File) 7 | end 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /src/ast/emit.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class Emit < Node 4 | property signal : Signal? = nil 5 | getter expression 6 | 7 | def initialize(@from : Parser::Location, 8 | @to : Parser::Location, 9 | @file : Parser::File, 10 | @expression : Node) 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/ast/encode.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class Encode < Node 4 | getter expression 5 | 6 | def initialize(@from : Parser::Location, 7 | @to : Parser::Location, 8 | @file : Parser::File, 9 | @expression : Node) 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/ast/env.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class Env < Node 4 | getter name 5 | 6 | def initialize(@from : Parser::Location, 7 | @to : Parser::Location, 8 | @file : Parser::File, 9 | @name : String) 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/ast/field_access.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class FieldAccess < Node 4 | getter name, type 5 | 6 | def initialize(@from : Parser::Location, 7 | @to : Parser::Location, 8 | @file : Parser::File, 9 | @name : Variable, 10 | @type : Type) 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/ast/html_attribute.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class HtmlAttribute < Node 4 | getter value, name 5 | 6 | def initialize(@from : Parser::Location, 7 | @to : Parser::Location, 8 | @file : Parser::File, 9 | @name : Variable, 10 | @value : Node) 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/ast/html_fragment.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class HtmlFragment < Node 4 | getter comments, children, tag 5 | 6 | def initialize(@comments : Array(Comment), 7 | @from : Parser::Location, 8 | @children : Array(Node), 9 | @to : Parser::Location, 10 | @file : Parser::File) 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/ast/id.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class Id < Node 4 | getter value 5 | 6 | def initialize(@from : Parser::Location, 7 | @to : Parser::Location, 8 | @file : Parser::File, 9 | @value : String) 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/ast/interpolation.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class Interpolation < Node 4 | getter expression 5 | 6 | def initialize(@from : Parser::Location, 7 | @to : Parser::Location, 8 | @file : Parser::File, 9 | @expression : Node) 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/ast/js.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class Js < Node 4 | getter value, type 5 | 6 | def initialize(@value : Array(String | Interpolation), 7 | @from : Parser::Location, 8 | @to : Parser::Location, 9 | @file : Parser::File, 10 | @type : Node?) 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/ast/locale_key.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class LocaleKey < Node 4 | getter value 5 | 6 | def initialize(@from : Parser::Location, 7 | @to : Parser::Location, 8 | @file : Parser::File, 9 | @value : String) 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/ast/map.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class Map < Node 4 | getter fields, types 5 | 6 | def initialize(@types : Tuple(Ast::Node, Ast::Node)?, 7 | @fields : Array(MapField), 8 | @from : Parser::Location, 9 | @to : Parser::Location, 10 | @file : Parser::File) 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/ast/map_field.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class MapField < Node 4 | getter key, value, comment 5 | 6 | def initialize(@from : Parser::Location, 7 | @to : Parser::Location, 8 | @file : Parser::File, 9 | @comment : Comment?, 10 | @value : Node, 11 | @key : Node) 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /src/ast/negated_expression.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class NegatedExpression < Node 4 | getter expression, negations 5 | 6 | def initialize(@from : Parser::Location, 7 | @to : Parser::Location, 8 | @file : Parser::File, 9 | @negations : String, 10 | @expression : Node) 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/ast/next_call.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class NextCall < Node 4 | getter data 5 | 6 | property entity : Ast::Node? = nil 7 | 8 | def initialize(@from : Parser::Location, 9 | @to : Parser::Location, 10 | @file : Parser::File, 11 | @data : Record) 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /src/ast/number_literal.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class NumberLiteral < Node 4 | getter? float 5 | getter value 6 | 7 | def initialize(@from : Parser::Location, 8 | @to : Parser::Location, 9 | @file : Parser::File, 10 | @value : String, 11 | @float : Bool) 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /src/ast/parenthesized_expression.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class ParenthesizedExpression < Node 4 | getter expression 5 | 6 | def initialize(@from : Parser::Location, 7 | @to : Parser::Location, 8 | @file : Parser::File, 9 | @expression : Node) 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/ast/record.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class Record < Node 4 | getter fields, comment 5 | 6 | def initialize(@from : Parser::Location, 7 | @to : Parser::Location, 8 | @fields : Array(Field), 9 | @file : Parser::File, 10 | @comment : Comment?) 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/ast/record_destructuring.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class RecordDestructuring < Node 4 | getter fields 5 | 6 | def initialize(@from : Parser::Location, 7 | @to : Parser::Location, 8 | @fields : Array(Field), 9 | @file : Parser::File) 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/ast/regexp_literal.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class RegexpLiteral < Node 4 | getter value, flags 5 | 6 | def initialize(@from : Parser::Location, 7 | @to : Parser::Location, 8 | @file : Parser::File, 9 | @value : String, 10 | @flags : String) 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/ast/return_call.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class ReturnCall < Node 4 | property statement : Ast::Statement? = nil 5 | 6 | getter expression 7 | 8 | def initialize(@from : Parser::Location, 9 | @to : Parser::Location, 10 | @file : Parser::File, 11 | @expression : Node) 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /src/ast/routes.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class Routes < Node 4 | getter comments, routes 5 | 6 | def initialize(@comments : Array(Comment), 7 | @from : Parser::Location, 8 | @to : Parser::Location, 9 | @routes : Array(Route), 10 | @file : Parser::File) 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/ast/spread.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class Spread < Node 4 | getter variable 5 | 6 | def initialize(@from : Parser::Location, 7 | @to : Parser::Location, 8 | @file : Parser::File, 9 | @variable : Node) 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/ast/state_setter.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class StateSetter < Node 4 | getter entity, state 5 | 6 | def initialize(@from : Parser::Location, 7 | @to : Parser::Location, 8 | @file : Parser::File, 9 | @state : Variable, 10 | @entity : Id?) 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/ast/string_literal.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class StringLiteral < Node 4 | getter? broken 5 | getter value 6 | 7 | def initialize(@value : Array(String | Interpolation), 8 | @from : Parser::Location, 9 | @to : Parser::Location, 10 | @file : Parser::File, 11 | @broken : Bool) 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /src/ast/tuple_destructuring.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class TupleDestructuring < Node 4 | getter items 5 | 6 | def initialize(@from : Parser::Location, 7 | @to : Parser::Location, 8 | @file : Parser::File, 9 | @items : Array(Node)) 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/ast/tuple_literal.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class TupleLiteral < Node 4 | getter comment, items 5 | 6 | def initialize(@items : Array(CommentedExpression), 7 | @from : Parser::Location, 8 | @to : Parser::Location, 9 | @file : Parser::File, 10 | @comment : Comment?) 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/ast/type.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class Type < Node 4 | getter parameters, name 5 | 6 | def initialize(@parameters : Array(Node), 7 | @from : Parser::Location, 8 | @to : Parser::Location, 9 | @file : Parser::File, 10 | @name : Id) 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/ast/type_variable.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class TypeVariable < Node 4 | getter value 5 | 6 | def initialize(@from : Parser::Location, 7 | @to : Parser::Location, 8 | @file : Parser::File, 9 | @value : String) 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/ast/unary_minus.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class UnaryMinus < Node 4 | getter expression, negations 5 | 6 | def initialize(@from : Parser::Location, 7 | @to : Parser::Location, 8 | @file : Parser::File, 9 | @expression : Node) 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/ast/use.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class Use < Node 4 | getter provider, condition, data 5 | 6 | def initialize(@from : Parser::Location, 7 | @to : Parser::Location, 8 | @file : Parser::File, 9 | @condition : Node?, 10 | @provider : Id, 11 | @data : Record) 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /src/ast/variable.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Ast 3 | class Variable < Node 4 | getter value 5 | 6 | def initialize(@from : Parser::Location, 7 | @to : Parser::Location, 8 | @file : Parser::File, 9 | @value : String) 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/commands/install.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Cli < Admiral::Command 3 | class Install < Admiral::Command 4 | include Command 5 | 6 | define_help description: "Installs dependencies." 7 | 8 | def run 9 | execute "Installing dependencies" do 10 | Installer.new 11 | end 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /src/commands/tool/ls.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Cli < Admiral::Command 3 | class Ls < Admiral::Command 4 | define_help description: "Starts the language server process." 5 | 6 | def run 7 | Colorize.enabled = 8 | false 9 | 10 | server = 11 | LS::Server.new(STDIN, STDOUT) 12 | 13 | loop do 14 | server.read 15 | end 16 | end 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /src/commands/version.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Cli < Admiral::Command 3 | class Version < Admiral::Command 4 | include Command 5 | 6 | define_help description: "Shows version." 7 | 8 | def run 9 | terminal.puts "Mint #{Mint.version}" 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/compiler/record.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Compiler 3 | def record(name : String) : Compiled 4 | @records[name] ||= begin 5 | node = 6 | ast.type_definitions.find!(&.name.value.==(name)) 7 | 8 | [ 9 | Record.new.tap do |id| 10 | add node, id, js.call(Builtin::Record, [js.string(name)]) 11 | end, 12 | ] of Item 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /src/compilers/argument.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Compiler 3 | def compile(node : Ast::Argument) : Compiled 4 | compile node do 5 | if default = node.default 6 | js.assign(node, compile(default)) 7 | else 8 | [node] of Item 9 | end 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/compilers/array_literal.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Compiler 3 | def compile(node : Ast::ArrayLiteral) : Compiled 4 | compile node do 5 | js.array(compile(node.items)) 6 | end 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/compilers/await.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Compiler 3 | def compile(node : Ast::Await) : Compiled 4 | compile node do 5 | [Await.new, " "] + defer(node.body, compile(node.body)) 6 | end 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/compilers/bool_literal.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Compiler 3 | def compile(node : Ast::BoolLiteral) : Compiled 4 | compile node do 5 | [node.value.to_s] of Item 6 | end 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/compilers/commented_expression.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Compiler 3 | def compile(node : Ast::CommentedExpression) : Compiled 4 | compile node do 5 | compile(node.expression) 6 | end 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/compilers/defer.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Compiler 3 | def compile(node : Ast::Defer) : Compiled 4 | compile node do 5 | add(node, node, compile(node.body)) 6 | 7 | [Deferred.new(node)] of Item 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /src/compilers/directives/asset.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Compiler 3 | def compile(node : Ast::Directives::Asset) : Compiled 4 | compile node do 5 | [Asset.new(node)] of Item 6 | end 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/compilers/directives/highlight_file.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Compiler 3 | def compile(node : Ast::Directives::HighlightFile) : Compiled 4 | compile node do 5 | tokenize(Parser.parse_any(node.real_path.to_s)) 6 | end 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/compilers/directives/inline.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Compiler 3 | def compile(node : Ast::Directives::Inline) : Compiled 4 | inlined = 5 | Raw.new(node.file_contents.gsub("\\", "\\\\").gsub("`", "\\`")) 6 | 7 | # TODO: Maybe use `js.string`? 8 | ["`", inlined, "`"] of Item 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /src/compilers/emit.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Compiler 3 | def compile(node : Ast::Emit) : Compiled 4 | compile node do 5 | js.assign(Signal.new(node.signal.not_nil!), compile(node.expression)) 6 | end 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/compilers/encode.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Compiler 3 | def compile(node : Ast::Encode) : Compiled 4 | compile node do 5 | code = 6 | encoder cache[node.expression] 7 | 8 | js.call(code, [compile(node.expression)]) 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/compilers/env.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Compiler 3 | def compile(node : Ast::Env) : Compiled 4 | compile node do 5 | value = 6 | MINT_ENV[node.name]?.to_s 7 | 8 | js.string(value) 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/compilers/field_access.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Compiler 3 | def compile(node : Ast::FieldAccess) : Compiled 4 | compile node do 5 | js.call(Builtin::Access, [js.string(node.name.value)]) 6 | end 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/compilers/get.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Compiler 3 | def resolve(node : Ast::Get) 4 | resolve node do 5 | body = 6 | compile node.body, for_function: true 7 | 8 | body = 9 | js.arrow_function([] of Compiled) { body } 10 | 11 | {node, node, body} 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /src/compilers/interpolation.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Compiler 3 | def compile(node : Ast::Interpolation) : Compiled 4 | compile node do 5 | compile node.expression 6 | end 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/compilers/locale_key.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Compiler 3 | def compile(node : Ast::LocaleKey) : Compiled 4 | compile node do 5 | js.call(Builtin::Translate, [js.string(node.value)]) 6 | end 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/compilers/map.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Compiler 3 | def compile(node : Ast::Map) : Compiled 4 | compile node do 5 | fields = 6 | compile node.fields 7 | 8 | js.array(fields) 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/compilers/map_field.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Compiler 3 | def compile(node : Ast::MapField) 4 | compile node do 5 | js.array([ 6 | compile(node.key), 7 | compile(node.value), 8 | ]) 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/compilers/module.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Compiler 3 | def resolve(node : Ast::Module) 4 | resolve node do 5 | functions = 6 | resolve node.functions 7 | 8 | constants = 9 | resolve node.constants 10 | 11 | add functions + constants 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /src/compilers/negated_expression.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Compiler 3 | def compile(node : Ast::NegatedExpression) : Compiled 4 | compile node do 5 | [node.negations] + compile(node.expression) 6 | end 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/compilers/number_literal.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Compiler 3 | def compile(node : Ast::NumberLiteral) : Compiled 4 | compile node do 5 | [static_value(node).to_s] of Item 6 | end 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/compilers/parenthesized_expression.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Compiler 3 | def compile(node : Ast::ParenthesizedExpression) : Compiled 4 | compile node do 5 | ["("] + compile(node.expression) + [")"] 6 | end 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/compilers/pipe.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Compiler 3 | def compile(node : Ast::Pipe) : Compiled 4 | compile node do 5 | compile node.call 6 | end 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/compilers/regexp_literal.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Compiler 3 | def compile(node : Ast::RegexpLiteral) : Compiled 4 | compile node do 5 | [static_value(node).to_s] of Item 6 | end 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/compilers/return_call.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Compiler 3 | def compile(node : Ast::ReturnCall) : Compiled 4 | compile node do 5 | js.return compile(node.expression) 6 | end 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/compilers/signal.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Compiler 3 | def resolve(node : Ast::Signal) 4 | resolve node do 5 | block = 6 | compile node.block 7 | 8 | {node, node, js.call(Builtin::Signal, [block])} 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/compilers/state_setter.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Compiler 3 | def compile(node : Ast::StateSetter) : Compiled 4 | compile node do 5 | variable = 6 | Variable.new 7 | 8 | ["("] + js.arrow_function([[variable] of Item]) do 9 | js.assign(Signal.new(lookups[node].first), [variable] of Item) 10 | end + [")"] 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/compilers/tuple_literal.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Compiler 3 | def compile(node : Ast::TupleLiteral) : Compiled 4 | compile node do 5 | js.array(compile(node.items)) 6 | end 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/compilers/unary_minus.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Compiler 3 | def compile(node : Ast::UnaryMinus) : Compiled 4 | compile node do 5 | ["-("] + compile(node.expression) + [")"] 6 | end 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/ext/array.cr: -------------------------------------------------------------------------------- 1 | class Array(T) 2 | def zip2(other : Array(T)) 3 | map_with_index do |item, index| 4 | [item, other[index]?].compact 5 | end.flatten 6 | end 7 | 8 | def intersperse(separator : T) 9 | flat_map { |item| [item, separator] }.tap(&.pop?) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /src/ext/dir.cr: -------------------------------------------------------------------------------- 1 | class Dir 2 | def self.safe_delete(directory, &) 3 | return unless Dir.exists?(directory) 4 | yield 5 | FileUtils.rm_rf(directory) 6 | end 7 | 8 | def self.tempdir(&) 9 | path = 10 | Path[tempdir, Random::Secure.hex] 11 | 12 | begin 13 | FileUtils.mkdir_p(path) 14 | FileUtils.cd(path) { yield } 15 | ensure 16 | FileUtils.rm_rf(path) 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /src/ext/libxml.cr: -------------------------------------------------------------------------------- 1 | # These add support for writing raw text when builing XML. 2 | lib LibXML 3 | fun xmlTextWriterWriteRaw(TextWriter, content : UInt8*) : Int 4 | end 5 | 6 | class XML::Builder 7 | def raw(content : String) : Nil 8 | call WriteRaw, string_to_unsafe(content) 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /src/formatters/access.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::Access) : Nodes 4 | format(node.expression) + [".", node.field.value] 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/formatters/await.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::Await) : Nodes 4 | ["await "] + format(node.body) 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/formatters/bool_literal.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::BoolLiteral) : Nodes 4 | format(node.value.to_s) 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/formatters/bracket_access.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::BracketAccess) : Nodes 4 | expression = 5 | format node.expression 6 | 7 | index = 8 | format node.index 9 | 10 | expression + ["["] + index + ["]"] 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/formatters/builtin.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::Builtin) : Nodes 4 | format("%#{node.value}%") 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/formatters/call.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::Call) : Nodes 4 | format(node.expression) + format_arguments(node.arguments) 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/formatters/commented_expression.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::CommentedExpression) : Nodes 4 | comment = 5 | format_documentation_comment node.comment 6 | 7 | expression = 8 | format node.expression 9 | 10 | comment + expression 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/formatters/connect_variable.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::ConnectVariable) : Nodes 4 | name = 5 | format node.name 6 | 7 | if target = node.target 8 | name + [" as "] + format(target) 9 | else 10 | name 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/formatters/css_font_face.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::CssFontFace) : Nodes 4 | ["@font-face "] + group( 5 | items: [list(node.definitions)], 6 | behavior: Behavior::Block, 7 | ends: {"{", "}"}, 8 | separator: "", 9 | pad: false) 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/formatters/css_keyframes.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::CssKeyframes) : Nodes 4 | ["@keyframes #{node.name} "] + group( 5 | items: [list(node.selectors)], 6 | behavior: Behavior::Block, 7 | ends: {"{", "}"}, 8 | separator: "", 9 | pad: false) 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/formatters/css_nested_at.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::CssNestedAt) : Nodes 4 | ["@#{node.name} #{node.content.strip} "] + group( 5 | behavior: Behavior::Block, 6 | items: [list(node.body)], 7 | ends: {"{", "}"}, 8 | separator: "", 9 | pad: false) 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/formatters/dbg.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::Dbg) : Nodes 4 | expression = 5 | format(node.expression) do |item| 6 | [" "] + format(item) 7 | end 8 | 9 | bang = 10 | if node.bang? 11 | "!" 12 | else 13 | "" 14 | end 15 | 16 | ["dbg", bang] + expression 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /src/formatters/decode.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::Decode) : Nodes 4 | type = 5 | format node.type 6 | 7 | expression = 8 | format(node.expression) do |item| 9 | [" "] + format(item) 10 | end 11 | 12 | ["decode"] + expression + [" as "] + type 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /src/formatters/defer.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::Defer) : Nodes 4 | ["defer "] + format(node.body) 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/formatters/directives/asset.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::Directives::Asset) : Nodes 4 | format("@asset(#{node.path})") 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/formatters/directives/format.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::Directives::Format) : Nodes 4 | ["@format "] + format(node.content) 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/formatters/directives/highlight.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::Directives::Highlight) : Nodes 4 | ["@highlight "] + format(node.content) 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/formatters/directives/highlight_file.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::Directives::HighlightFile) : Nodes 4 | format("@highlight-file(#{node.path})") 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/formatters/directives/inline.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::Directives::Inline) : Nodes 4 | format("@inline(#{node.path})") 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/formatters/directives/svg.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::Directives::Svg) : Nodes 4 | format("@svg(#{node.path})") 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/formatters/discard.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::Discard) : Nodes 4 | format("_") 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/formatters/emit.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::Emit) : Nodes 4 | ["emit "] + format(node.expression) 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/formatters/encode.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::Encode) : Nodes 4 | ["encode "] + format(node.expression) 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/formatters/env.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::Env) : Nodes 4 | format("@#{node.name}") 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/formatters/field_access.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::FieldAccess) : Nodes 4 | [".#{node.name.value}("] + format(node.type) + [")"] 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/formatters/html_attribute.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::HtmlAttribute) : Nodes 4 | name = 5 | format node.name 6 | 7 | formatted = 8 | case value = node.value 9 | when Ast::Block 10 | format value, BlockFormat::Attribute 11 | else 12 | format value 13 | end 14 | 15 | name + ["="] + formatted 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /src/formatters/html_component.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::HtmlComponent) : Nodes 4 | component = 5 | format node.component.value 6 | 7 | ref = 8 | format(node.ref) do |item| 9 | [" as "] + format(item) 10 | end 11 | 12 | format(prefix: component + ref, tag: component, node: node) 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /src/formatters/html_fragment.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::HtmlFragment) : Nodes 4 | group( 5 | items: [list(node.children + node.comments)], 6 | behavior: Behavior::BreakAll, 7 | ends: {"<>", ""}, 8 | separator: "", 9 | pad: false) 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/formatters/html_style.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::HtmlStyle) : Nodes 4 | ["::#{node.name.value}"] + 5 | format_arguments( 6 | empty_parenthesis: false, 7 | nodes: node.arguments) 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /src/formatters/id.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::Id) : Nodes 4 | format(node.value) 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/formatters/interpolation.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::Interpolation) : Nodes 4 | ["\#{"] + format(node.expression) + ["}"] 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/formatters/list.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def list( 4 | nodes : Array(Ast::Node), 5 | separator : String? = nil, 6 | comment : Nodes? = nil, 7 | ) : Nodes 8 | [ 9 | List.new( 10 | items: nodes.map(&.as(Ast::Node)).zip(nodes.map(&->format(Ast::Node))), 11 | separator: separator, 12 | comment: comment), 13 | ] of Node 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /src/formatters/locale.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::Locale) : Nodes 4 | ["locale #{node.language} "] + 5 | group( 6 | items: [format node.fields], 7 | behavior: Behavior::Block, 8 | ends: {"{", "}"}, 9 | separator: "", 10 | pad: false) 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/formatters/locale_key.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::LocaleKey) : Nodes 4 | format(":#{node.value}") 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/formatters/map_field.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::MapField) : Nodes 4 | comment = 5 | format_documentation_comment node.comment 6 | 7 | value = 8 | format node.value 9 | 10 | key = 11 | format node.key 12 | 13 | comment + break_not_fits( 14 | items: {key, value}, 15 | separator: " =>") 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /src/formatters/negated_expression.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::NegatedExpression) : Nodes 4 | expression = 5 | format node.expression 6 | 7 | [node.negations] + expression 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /src/formatters/next_call.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::NextCall) : Nodes 4 | ["next "] + format(node.data) 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/formatters/number_literal.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::NumberLiteral) : Nodes 4 | format(node.value) 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/formatters/parenthesized_expression.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::ParenthesizedExpression) : Nodes 4 | ["("] + format(node.expression) + [")"] 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/formatters/pipe.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::Pipe) : Nodes 4 | comment = 5 | format_documentation_comment node.comment 6 | 7 | argument = 8 | format node.argument 9 | 10 | expression = 11 | format node.expression 12 | 13 | argument + ([Line.new(1)] of Node) + comment + (["|> "] of Node) + expression 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /src/formatters/regexp_literal.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::RegexpLiteral) : Nodes 4 | format("/#{node.value}/#{node.flags.split.uniq!.join}") 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/formatters/return_call.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::ReturnCall) : Nodes 4 | ["return "] + format(node.expression) 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/formatters/route.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::Route) : Nodes 4 | entity( 5 | tail: node.await ? (format("await") + [" "]) : format(""), 6 | arguments: node.arguments.map(&->format(Ast::Node)), 7 | head: format(node.url)) + format(node.expression) 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /src/formatters/routes.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::Routes) : Nodes 4 | ["routes "] + group( 5 | items: [list(node.routes + node.comments)], 6 | behavior: Behavior::Block, 7 | ends: {"{", "}"}, 8 | separator: "", 9 | pad: false) 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/formatters/signal.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::Signal) : Nodes 4 | comment = 5 | format_documentation_comment node.comment 6 | 7 | block = 8 | format node.block 9 | 10 | name = 11 | format node.name 12 | 13 | type = 14 | format node.type 15 | 16 | comment + ["signal "] + name + [" : "] + type + [" "] + block 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /src/formatters/spread.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::Spread) : Nodes 4 | ["..."] + format(node.variable) 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/formatters/state_setter.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::StateSetter) : Nodes 4 | entity = 5 | format(node.entity) do |item| 6 | format(item) + ["."] 7 | end 8 | 9 | ["-> "] + entity + [node.state.value] 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/formatters/test.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::Test) : Nodes 4 | expression = 5 | format node.expression 6 | 7 | name = 8 | format node.name 9 | 10 | ["test "] + name + [" "] + expression 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/formatters/tuple_destructuring.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::TupleDestructuring) : Nodes 4 | group( 5 | items: node.items.map(&->format(Ast::Node)), 6 | behavior: Behavior::BreakAll, 7 | ends: {"{", "}"}, 8 | separator: ",", 9 | pad: false) 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/formatters/tuple_literal.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::TupleLiteral) : Nodes 4 | group( 5 | items: node.items.map(&->format(Ast::Node)), 6 | comment: format(node.comment), 7 | behavior: Behavior::BreakAll, 8 | ends: {"{", "}"}, 9 | separator: ",", 10 | pad: false) 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/formatters/type.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::Type) : Nodes 4 | parameters = 5 | format_arguments node.parameters, empty_parenthesis: false 6 | 7 | name = 8 | format node.name 9 | 10 | name + parameters 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/formatters/type_destructuring.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::TypeDestructuring) : Nodes 4 | items = 5 | format_arguments node.items, empty_parenthesis: false 6 | 7 | name = 8 | if node.name 9 | format(node.name) + ["."] 10 | else 11 | [] of Node 12 | end 13 | 14 | name + format(node.variant) + items 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /src/formatters/type_variable.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::TypeVariable) : Nodes 4 | format(node.value) 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/formatters/type_variant.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::TypeVariant) : Nodes 4 | comment = 5 | format_documentation_comment(node.comment) 6 | 7 | parameters = 8 | format_arguments(node.parameters, empty_parenthesis: false) 9 | 10 | comment + format(node.value) + parameters 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/formatters/unary_minus.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::UnaryMinus) : Nodes 4 | ["-"] + format(node.expression) 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/formatters/variable.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Formatter 3 | def format(node : Ast::Variable) : Nodes 4 | format(node.value) 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/installer/dependency.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Installer 3 | class Dependency 4 | getter repository, constraint, name 5 | 6 | def initialize(@name : String, @repository : String, @constraint : Constraint) 7 | end 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /src/installer/simple_constraint.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Installer 3 | class SimpleConstraint 4 | getter upper, lower 5 | 6 | def initialize(@lower : Semver, @upper : Semver) 7 | end 8 | 9 | def to_s(io : IO) 10 | io << lower << " <= v < " << upper 11 | end 12 | 13 | def ==(other) 14 | to_s == other.to_s 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /src/ls/completions/functions.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | module LS 3 | class Completion 4 | def completions(node : Ast::Function) : Array(LSP::CompletionItem) 5 | node.arguments.map { |item| completion_item(item) } 6 | end 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/ls/completions/module.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | module LS 3 | class Completion 4 | def completions(node : Ast::Module, global : Bool = false) : Array(LSP::CompletionItem) 5 | name = 6 | node.name if global 7 | 8 | node.functions.map { |item| completion_item(item, name) } + 9 | node.constants.map { |item| completion_item(item, name) } 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/ls/definitions/html_component.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | module LS 3 | class Definitions 4 | def definition(node : Ast::HtmlComponent) 5 | return unless cursor_intersects?(node.component) 6 | 7 | return unless component = 8 | find_component(node.component.value) 9 | 10 | location_link node.component, component.name, component 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/ls/definitions/html_element.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | module LS 3 | class Definitions 4 | def definition(node : Ast::HtmlElement) 5 | node.styles.each do |style| 6 | next unless cursor_intersects?(style) 7 | 8 | return definition(style) 9 | end 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/ls/did_change.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | module LS 3 | class DidChange < LSP::NotificationMessage 4 | property params : LSP::DidChangeTextDocumentParams 5 | 6 | def execute(server) : Nil 7 | path = 8 | params.text_document.path 9 | 10 | server 11 | .workspace(path) 12 | .update(params.content_changes.first.text, path) 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /src/ls/did_open.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | module LS 3 | class DidOpen < LSP::NotificationMessage 4 | property params : LSP::DidOpenTextDocumentParams 5 | 6 | def execute(server) : Nil 7 | path = 8 | params.text_document.path 9 | 10 | server 11 | .workspace(path) 12 | .update(params.text_document.text, path) 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /src/ls/exit.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | module LS 3 | class Exit < LSP::NotificationMessage 4 | def execute(server) 5 | exit(0) 6 | end 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/ls/hover/argument.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | module LS 3 | class Hover < LSP::RequestMessage 4 | def hover( 5 | node : Ast::Argument, 6 | workspace : Workspace, 7 | type_checker : TypeChecker, 8 | ) : Array(String) 9 | type = 10 | workspace.format(node.type) 11 | 12 | ["**#{node.name.value} : #{type}**"] 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /src/ls/hover/html_component.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | module LS 3 | class Hover < LSP::RequestMessage 4 | def hover( 5 | node : Ast::HtmlComponent, 6 | workspace : Workspace, 7 | type_checker : TypeChecker, 8 | ) : Array(String) 9 | component = 10 | type_checker.lookups[node]?.try(&.first?) 11 | 12 | hover(component, workspace, type_checker) 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /src/ls/hover/string_literal.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | module LS 3 | class Hover < LSP::RequestMessage 4 | def hover( 5 | node : Ast::StringLiteral, 6 | workspace : Workspace, 7 | type_checker : TypeChecker, 8 | ) : Array(String) 9 | ["String"] 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/ls/sandbox_reset.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | module LS 3 | class SandboxReset < LSP::RequestMessage 4 | property params : Array(Tuple(String, String)) 5 | 6 | def execute(server : Server) 7 | if sandbox = server.sandbox 8 | sandbox.reset(params) 9 | sandbox.directory 10 | end 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/ls/sandbox_update.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | module LS 3 | class SandboxUpdate < LSP::RequestMessage 4 | property params : Tuple(String, String) 5 | 6 | def execute(server : Server) 7 | server.sandbox.try(&.update(params)) 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /src/ls/shutdown.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | module LS 3 | class Shutdown < LSP::RequestMessage 4 | def execute(server) 5 | nil 6 | end 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/lsp/README.md: -------------------------------------------------------------------------------- 1 | # Language Server Protocol 2 | 3 | This folder contains the code for the language server protocol implementation in Crystal. 4 | 5 | _When matured and finalized this will be separated as a shard._ 6 | -------------------------------------------------------------------------------- /src/lsp/protocol/code_action_trigger_kind.cr: -------------------------------------------------------------------------------- 1 | module LSP 2 | enum CodeActionTriggerKind 3 | # Code actions were explicitly requested by the user or by an extension. 4 | Invoked = 1 5 | 6 | # Code actions were requested automatically. 7 | # 8 | # This typically happens when current selection in a file changes, but can 9 | # also be triggered when file content changes. 10 | Automatic = 2 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/lsp/protocol/code_description.cr: -------------------------------------------------------------------------------- 1 | module LSP 2 | struct CodeDescription 3 | include JSON::Serializable 4 | 5 | # An URI to open with more information about the diagnostic error. 6 | property uri : String 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /src/lsp/protocol/code_lens_provider.cr: -------------------------------------------------------------------------------- 1 | module LSP 2 | # Code Lens options. 3 | struct CodeLensOptions 4 | include JSON::Serializable 5 | 6 | # Code lens has a resolve provider as well. 7 | @[JSON::Field(key: "resolveProvider")] 8 | property? resolve_provider : Bool 9 | 10 | def initialize(@resolve_provider) 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/lsp/protocol/color_provider_options.cr: -------------------------------------------------------------------------------- 1 | module LSP 2 | struct ColorProviderOptions 3 | include JSON::Serializable 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /src/lsp/protocol/command.cr: -------------------------------------------------------------------------------- 1 | module LSP 2 | struct Command 3 | include JSON::Serializable 4 | 5 | # Title of the command, like `save`. 6 | property title : String 7 | 8 | # The identifier of the actual command handler. 9 | property command : String 10 | 11 | # Arguments that the command handler should be 12 | # invoked with. 13 | property arguments : Array(String)? 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /src/lsp/protocol/completion_params.cr: -------------------------------------------------------------------------------- 1 | require "./text_document_position_params" 2 | 3 | module LSP 4 | class CompletionParams < TextDocumentPositionParams 5 | include JSON::Serializable 6 | 7 | # The completion context. This is only available if the client specifies 8 | # to send this using `ClientCapabilities.textDocument.completion.contextSupport === true` 9 | property context : CompletionContext? 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /src/lsp/protocol/create_file_options.cr: -------------------------------------------------------------------------------- 1 | module LSP 2 | struct CreateFileOptions 3 | include JSON::Serializable 4 | 5 | # Overwrite existing file. Overwrite wins over `ignoreIfExists` 6 | property overwrite : Bool? 7 | 8 | # Ignore if exists. 9 | @[JSON::Field(key: "ignoreIfExists")] 10 | property ignore_if_exists : Bool? 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/lsp/protocol/diagnostic_related_information.cr: -------------------------------------------------------------------------------- 1 | module LSP 2 | struct DiagnosticRelatedInformation 3 | include JSON::Serializable 4 | 5 | # The location of this related diagnostic information. 6 | property location : Location 7 | 8 | # The message of this related diagnostic information. 9 | property message : String 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /src/lsp/protocol/diagnostic_severity.cr: -------------------------------------------------------------------------------- 1 | module LSP 2 | enum DiagnosticSeverity 3 | # Reports an error. 4 | Error = 1 5 | 6 | # Reports a warning. 7 | Warning = 2 8 | 9 | # Reports an information. 10 | Information = 3 11 | 12 | # Reports a hint. 13 | Hint = 4 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /src/lsp/protocol/diagnostic_tag.cr: -------------------------------------------------------------------------------- 1 | module LSP 2 | enum DiagnosticTag 3 | # Unused or unnecessary code. 4 | # 5 | # Clients are allowed to render diagnostics with this tag faded out 6 | # instead of having an error squiggle. 7 | Unnecessary = 1 8 | 9 | # Deprecated or obsolete code. 10 | # 11 | # Clients are allowed to rendered diagnostics with this tag strike through. 12 | Deprecated = 2 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/lsp/protocol/did_open_text_document_params.cr: -------------------------------------------------------------------------------- 1 | module LSP 2 | struct DidOpenTextDocumentParams 3 | include JSON::Serializable 4 | 5 | # The document that was opened. 6 | @[JSON::Field(key: "textDocument")] 7 | property text_document : TextDocumentItem 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/lsp/protocol/did_save_text_document_params.cr: -------------------------------------------------------------------------------- 1 | module LSP 2 | struct DidSaveTextDocumentParams 3 | include JSON::Serializable 4 | 5 | # The document to format. 6 | @[JSON::Field(key: "textDocument")] 7 | property text_document : TextDocumentIdentifier 8 | 9 | def initialize(@text_document) 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/lsp/protocol/document_formatting_params.cr: -------------------------------------------------------------------------------- 1 | module LSP 2 | struct DocumentFormattingParams 3 | include JSON::Serializable 4 | 5 | # The document to format. 6 | @[JSON::Field(key: "textDocument")] 7 | property text_document : TextDocumentIdentifier 8 | 9 | # The format options. 10 | property options : FormattingOptions 11 | 12 | def initialize(@text_document, @options) 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /src/lsp/protocol/document_link_options.cr: -------------------------------------------------------------------------------- 1 | module LSP 2 | struct DocumentLinkOptions 3 | include JSON::Serializable 4 | 5 | # Document links have a resolve provider as well. 6 | @[JSON::Field(key: "resolveProvider")] 7 | property? resolve_provider : Bool 8 | 9 | def initialize(@resolve_provider) 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/lsp/protocol/execute_command_options.cr: -------------------------------------------------------------------------------- 1 | module LSP 2 | struct ExecuteCommandOptions 3 | include JSON::Serializable 4 | 5 | # The commands to be executed on the server 6 | property commands : Array(String) 7 | 8 | def initialize(@commands) 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /src/lsp/protocol/fold_range_kind.cr: -------------------------------------------------------------------------------- 1 | module LSP 2 | # Enum of known range kinds 3 | enum FoldingRangeKind 4 | # Folding range for a comment 5 | Comment 6 | 7 | # Folding range for a imports or includes 8 | Imports 9 | 10 | # Folding range for a region (e.g. `#region`) 11 | Region 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/lsp/protocol/fold_range_provider_options.cr: -------------------------------------------------------------------------------- 1 | module LSP 2 | struct FoldingRangeProviderOptions 3 | include JSON::Serializable 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /src/lsp/protocol/folding_range_params.cr: -------------------------------------------------------------------------------- 1 | module LSP 2 | class FoldingRangeParams 3 | include JSON::Serializable 4 | 5 | # The document in which the command was invoked. 6 | @[JSON::Field(key: "textDocument")] 7 | property text_document : TextDocumentIdentifier 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/lsp/protocol/initialize_result.cr: -------------------------------------------------------------------------------- 1 | module LSP 2 | struct InitializeResult 3 | include JSON::Serializable 4 | 5 | # The capabilities the language server provides. 6 | property capabilities : ServerCapabilities 7 | 8 | def initialize(@capabilities) 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /src/lsp/protocol/location.cr: -------------------------------------------------------------------------------- 1 | module LSP 2 | struct Location 3 | include JSON::Serializable 4 | 5 | property range : Range 6 | property uri : String 7 | 8 | def initialize(@range, @uri) 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /src/lsp/protocol/notification_message.cr: -------------------------------------------------------------------------------- 1 | module LSP 2 | # A notification message. A processed notification message must not send a 3 | # response back. They work like events. 4 | abstract class NotificationMessage 5 | include JSON::Serializable 6 | 7 | # The method to be invoked. 8 | property method : String 9 | 10 | abstract def execute(server : Server) 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/lsp/protocol/range.cr: -------------------------------------------------------------------------------- 1 | module LSP 2 | struct Range 3 | include JSON::Serializable 4 | 5 | # The range's start position. 6 | property start : Position 7 | 8 | # The range's end position. 9 | property end : Position 10 | 11 | def initialize(@start, @end) 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/lsp/protocol/rename_options.cr: -------------------------------------------------------------------------------- 1 | module LSP 2 | struct RenameOptions 3 | include JSON::Serializable 4 | 5 | # Renames should be checked and tested before being executed. 6 | @[JSON::Field(key: "prepareProvider")] 7 | property? prepare_provider : Bool 8 | 9 | def initialize(@prepare_provider) 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/lsp/protocol/response_error.cr: -------------------------------------------------------------------------------- 1 | module LSP 2 | class ResponseError 3 | include JSON::Serializable 4 | 5 | # A number indicating the error type that occurred. 6 | property code : Int32 7 | 8 | # A string providing a short description of the error. 9 | property message : String 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /src/lsp/protocol/save_options.cr: -------------------------------------------------------------------------------- 1 | module LSP 2 | struct SaveOptions 3 | include JSON::Serializable 4 | 5 | # The client is supposed to include the content on save. 6 | @[JSON::Field(key: "includeText")] 7 | property? include_text : Bool 8 | 9 | def initialize(@include_text) 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/lsp/protocol/semantic_tokens_params.cr: -------------------------------------------------------------------------------- 1 | module LSP 2 | class SemanticTokensParams 3 | include JSON::Serializable 4 | 5 | # The document in which the command was invoked. 6 | @[JSON::Field(key: "textDocument")] 7 | property text_document : TextDocumentIdentifier 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/lsp/protocol/signature_help_options.cr: -------------------------------------------------------------------------------- 1 | module LSP 2 | struct SignatureHelpOptions 3 | include JSON::Serializable 4 | 5 | # The characters that trigger completion automatically. 6 | @[JSON::Field(key: "triggerCharacters")] 7 | property trigger_characters : Array(String) 8 | 9 | def initialize(@trigger_characters) 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/lsp/protocol/text_document_edit.cr: -------------------------------------------------------------------------------- 1 | module LSP 2 | struct TextDocumentEdit 3 | include JSON::Serializable 4 | 5 | # The text document to change. 6 | @[JSON::Field(key: "textDocument")] 7 | property text_document : OptionalVersionedTextDocumentIdentifier 8 | 9 | # The edits to be applied. 10 | property edits : Array(TextEdit) 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/lsp/protocol/text_document_identifier.cr: -------------------------------------------------------------------------------- 1 | module LSP 2 | class TextDocumentIdentifier 3 | include JSON::Serializable 4 | 5 | # The text document's URI. 6 | property uri : String 7 | 8 | # Returns the path of the URI 9 | def path 10 | URI.parse(uri).try(&.path).to_s 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/lsp/protocol/will_save_text_document_params.cr: -------------------------------------------------------------------------------- 1 | module LSP 2 | struct WillSaveTextDocumentParams 3 | include JSON::Serializable 4 | 5 | # The document to format. 6 | @[JSON::Field(key: "textDocument")] 7 | property text_document : TextDocumentIdentifier 8 | 9 | def initialize(@text_document) 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/lsp/protocol/workspace.cr: -------------------------------------------------------------------------------- 1 | module LSP 2 | struct Workspace 3 | include JSON::Serializable 4 | 5 | # The server supports workspace folder. 6 | @[JSON::Field(key: "workspaceFolders")] 7 | property workspace_folders : WorkspaceFolders 8 | 9 | def initialize(@workspace_folders) 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/lsp/protocol/workspace_folder.cr: -------------------------------------------------------------------------------- 1 | module LSP 2 | struct WorkspaceFolder 3 | include JSON::Serializable 4 | 5 | # The associated URI for this workspace folder. 6 | property uri : String 7 | 8 | # The name of the workspace folder. Used to refer to this 9 | # workspace folder in the user interface. 10 | property name : String 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/mint.cr: -------------------------------------------------------------------------------- 1 | require "./all" 2 | 3 | Mint::Cli.run 4 | -------------------------------------------------------------------------------- /src/parsers/await.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Parser 3 | def await : Ast::Await? 4 | parse do |start_position| 5 | next unless keyword! "await" 6 | 7 | whitespace 8 | next unless body = base_expression 9 | 10 | Ast::Await.new( 11 | from: start_position, 12 | to: position, 13 | file: file, 14 | body: body) 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /src/parsers/css_node.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Parser 3 | def css_node : Ast::Node? 4 | oneof do 5 | case_expression(for_css: true) || 6 | if_expression(for_css: true) || 7 | css_definition || 8 | css_nested_at || 9 | css_selector || 10 | comment 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/parsers/defer.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Parser 3 | def defer : Ast::Defer? 4 | parse do |start_position| 5 | next unless keyword! "defer" 6 | 7 | whitespace 8 | next unless body = expression 9 | 10 | Ast::Defer.new( 11 | from: start_position, 12 | to: position, 13 | file: file, 14 | body: body) 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /src/parsers/destructuring.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Parser 3 | def destructuring : Ast::Node? 4 | array_destructuring || 5 | record_destructuring || 6 | tuple_destructuring || 7 | type_destructuring || 8 | string_literal(with_interpolation: false) || 9 | number_literal || 10 | bool_literal || 11 | variable || 12 | discard 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /src/parsers/discard.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Parser 3 | def discard 4 | parse do |start_position| 5 | next unless word! "_" 6 | 7 | Ast::Discard.new( 8 | from: start_position, 9 | to: position, 10 | file: file) 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/parsers/expression.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Parser 3 | def expression : Ast::Node? 4 | return unless expression = base_expression 5 | 6 | if item = self.operator 7 | operator, comment = 8 | item 9 | 10 | pipe operation(expression, operator, comment) 11 | else 12 | expression 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /src/parsers/id.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Parser 3 | def id(*, track : Bool = true) : Ast::Id? 4 | parse(track: track) do |start_position| 5 | return unless value = identifier_type 6 | 7 | Ast::Id.new( 8 | from: start_position, 9 | value: value, 10 | to: position, 11 | file: file) 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /src/parsers/type_variable.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Parser 3 | def type_variable : Ast::TypeVariable? 4 | parse do |start_position| 5 | next unless value = identifier_variable 6 | 7 | Ast::TypeVariable.new( 8 | from: start_position, 9 | to: position, 10 | value: value, 11 | file: file) 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /src/parsers/unary_minus.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class Parser 3 | def unary_minus : Ast::UnaryMinus? 4 | parse do |start_position| 5 | next unless char! '-' 6 | next unless expression = self.expression 7 | 8 | Ast::UnaryMinus.new( 9 | expression: expression, 10 | from: start_position, 11 | to: position, 12 | file: file) 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /src/type_checkers/await.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class TypeChecker 3 | def check(node : Ast::Await) : Checkable 4 | type = 5 | resolve node.body 6 | 7 | if block = self.block 8 | async.add(block) 9 | end 10 | 11 | case type.name 12 | when "Promise", "Deferred" 13 | type.parameters.first 14 | else 15 | type 16 | end 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /src/type_checkers/bool_literal.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class TypeChecker 3 | def check(node : Ast::BoolLiteral) : Checkable 4 | BOOL 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/type_checkers/comment.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class TypeChecker 3 | def check(node : Ast::Comment) : Checkable 4 | VOID 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/type_checkers/commented_expression.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class TypeChecker 3 | def check(node : Ast::CommentedExpression) : Checkable 4 | resolve node.expression 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/type_checkers/constant.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class TypeChecker 3 | def check(node : Ast::Constant) : Checkable 4 | resolve node.expression 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/type_checkers/css_keyframes.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class TypeChecker 3 | def check(node : Ast::CssKeyframes) : Checkable 4 | resolve node.selectors 5 | 6 | VOID 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/type_checkers/css_nested_at.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class TypeChecker 3 | def check(node : Ast::CssNestedAt) : Checkable 4 | resolve node.body 5 | 6 | VOID 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/type_checkers/css_selector.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class TypeChecker 3 | def check(node : Ast::CssSelector) : Checkable 4 | resolve node.body 5 | 6 | VOID 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/type_checkers/dbg.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class TypeChecker 3 | def check(node : Ast::Dbg) : Checkable 4 | if expression = node.expression 5 | resolve(expression) 6 | else 7 | Type.new("Function", [ 8 | Variable.new("a"), 9 | Variable.new("a"), 10 | ] of Checkable) 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/type_checkers/defer.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class TypeChecker 3 | def check(node : Ast::Defer) : Checkable 4 | type = 5 | resolve node.body 6 | 7 | Type.new("Deferred", [type] of Checkable) 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /src/type_checkers/directives/format.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class TypeChecker 3 | def check(node : Ast::Directives::Format) : Checkable 4 | Type.new("Tuple", [resolve(node.content), STRING] of Checkable) 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/type_checkers/directives/highlight.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class TypeChecker 3 | def check(node : Ast::Directives::Highlight) : Checkable 4 | Type.new("Tuple", [resolve(node.content), HTML] of Checkable) 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/type_checkers/directives/inline.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class TypeChecker 3 | def check(node : Ast::Directives::Inline) : Checkable 4 | error! :inline_directive_expected_file do 5 | snippet "The path specified for an inline directive does not exist:", node.relative_path 6 | snippet "The inline directive in question is here:", node 7 | end unless node.exists? 8 | 9 | STRING 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/type_checkers/env.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class TypeChecker 3 | def check(node : Ast::Env) : Checkable 4 | return STRING unless @check_env 5 | 6 | error! :env_not_found_variable do 7 | snippet "I cannot find the environment variable with the name:", node.name 8 | snippet "Here is where it is referenced:", node 9 | end unless MINT_ENV[node.name]? 10 | 11 | STRING 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/type_checkers/field.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class TypeChecker 3 | def check(node : Ast::Field, should_create_record : Bool = false) : Checkable 4 | case expression = node.value 5 | when Ast::Record 6 | resolve expression, should_create_record 7 | else 8 | resolve expression 9 | end.dup.tap do |item| 10 | item.label = node.key.try(&.value) 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/type_checkers/html_fragment.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class TypeChecker 3 | def check(node : Ast::HtmlFragment) : Checkable 4 | check_html node.children 5 | 6 | HTML 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/type_checkers/inline_function.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class TypeChecker 3 | def check(node : Ast::InlineFunction) 4 | check_function(node) 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/type_checkers/interpolation.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class TypeChecker 3 | def check(node : Ast::Interpolation) : Checkable 4 | resolve node.expression 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/type_checkers/js.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class TypeChecker 3 | def check(node : Ast::Js) : Checkable 4 | node.value.each do |item| 5 | case item 6 | when Ast::Node 7 | resolve item 8 | end 9 | end 10 | 11 | node.type.try { |type| resolve type } || Variable.new("a") 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/type_checkers/number_literal.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class TypeChecker 3 | def check(node : Ast::NumberLiteral) : Checkable 4 | NUMBER 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/type_checkers/parenthesized_expression.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class TypeChecker 3 | def check(node : Ast::ParenthesizedExpression) : Checkable 4 | resolve node.expression 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/type_checkers/pipe.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class TypeChecker 3 | def check(node : Ast::Pipe) : Checkable 4 | resolve node.call 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/type_checkers/regexp_literal.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class TypeChecker 3 | def check(node : Ast::RegexpLiteral) : Checkable 4 | REGEXP 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/type_checkers/routes.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class TypeChecker 3 | def check(node : Ast::Routes) : Checkable 4 | resolve node.routes 5 | 6 | VOID 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/type_checkers/style.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class TypeChecker 3 | def check(node : Ast::Style) : Checkable 4 | check_arguments(node.arguments) 5 | 6 | resolve node.body 7 | 8 | arguments = resolve node.arguments 9 | arguments << VOID 10 | 11 | type = Type.new("Function", arguments) 12 | type.optional_count = node.arguments.count(&.default) 13 | type 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /src/type_checkers/suite.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class TypeChecker 3 | def check(node : Ast::Suite) 4 | resolve node.constants 5 | resolve node.tests 6 | resolve node.name 7 | 8 | VOID 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /src/type_checkers/tuple_literal.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class TypeChecker 3 | def check(node : Ast::TupleLiteral) : Checkable 4 | items = 5 | resolve node.items 6 | 7 | Type.new("Tuple", items) 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /src/type_checkers/type.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class TypeChecker 3 | def check(node : Ast::Type) : Checkable 4 | resolve_record_definition(node.name.value) || begin 5 | parameters = 6 | resolve node.parameters 7 | 8 | Comparer.normalize(Type.new(node.name.value, parameters)) 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/type_checkers/type_definition_field.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class TypeChecker 3 | def check(node : Ast::TypeDefinitionField) : Checkable 4 | resolve(node.type).tap do |type| 5 | if definition = ast.type_definitions.find(&.name.value.==(type.name)) 6 | resolve(definition) 7 | end 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /src/type_checkers/type_variable.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class TypeChecker 3 | def check(node : Ast::TypeVariable) : Checkable 4 | Variable.new(node.value) 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/type_checkers/type_variant.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | class TypeChecker 3 | def check(node : Ast::TypeVariant) : Checkable 4 | parameters = 5 | resolve node.parameters 6 | 7 | Type.new(node.value.value, parameters) 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /src/version.cr: -------------------------------------------------------------------------------- 1 | module Mint 2 | def self.version 3 | {{ `shards version "#{__DIR__}"`.chomp.stringify }} 4 | end 5 | end 6 | --------------------------------------------------------------------------------