From 589d0e1147095b24358fb2cfdcdf17a73e5cf1e7 Mon Sep 17 00:00:00 2001 From: Emily Samp Date: Wed, 24 Jul 2024 15:28:23 -0500 Subject: [PATCH 1/3] Refactor statements node handling Relocate it to the `PM_STATEMENTS_NODE` case so it can be reused by multiple parent nodes. --- main/pipeline/pipeline.cc | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/main/pipeline/pipeline.cc b/main/pipeline/pipeline.cc index 711474e50b4..4554d2a0a9f 100644 --- a/main/pipeline/pipeline.cc +++ b/main/pipeline/pipeline.cc @@ -174,12 +174,25 @@ const unique_ptr convertPrismToSorbet(pm_node_t *node, pm_parser_t } case PM_PROGRAM_NODE: { pm_program_node *programNode = reinterpret_cast(node); - pm_statements_node *stmts = programNode->statements; - auto size = stmts->body.size; + return convertPrismToSorbet(reinterpret_cast(programNode->statements), parser, gs); + } + case PM_RATIONAL_NODE: { + auto *rationalNode = reinterpret_cast(node); + pm_location_t *loc = &rationalNode->base.location; + + const uint8_t *start = rationalNode->numeric->location.start; + const uint8_t *end = rationalNode->numeric->location.end; + + std::string value = std::string(reinterpret_cast(start), end - start); + + return make_unique(locOffset(loc, parser), value); + } + case PM_STATEMENTS_NODE: { + pm_statements_node *stmts = reinterpret_cast(node); // For a single statement, do not create a Begin node and just return the statement - if (size == 1) { + if (stmts->body.size == 1) { return convertPrismToSorbet((pm_node *)stmts->body.nodes[0], parser, gs); } @@ -192,26 +205,10 @@ const unique_ptr convertPrismToSorbet(pm_node_t *node, pm_parser_t sorbetStmts.emplace_back(std::move(convertedStmt)); } - auto *loc = &programNode->base.location; + auto *loc = &stmts->base.location; return make_unique(locOffset(loc, parser), std::move(sorbetStmts)); } - case PM_RATIONAL_NODE: { - auto *rationalNode = reinterpret_cast(node); - pm_location_t *loc = &rationalNode->base.location; - - const uint8_t *start = rationalNode->numeric->location.start; - const uint8_t *end = rationalNode->numeric->location.end; - - std::string value = std::string(reinterpret_cast(start), end - start); - - return make_unique(locOffset(loc, parser), value); - - break; - } - case PM_STATEMENTS_NODE: { - Exception::raise("Handling for statements node should be performed in program node"); - } case PM_STRING_NODE: { auto strNode = reinterpret_cast(node); pm_location_t *loc = &strNode->base.location; From c90d7f8a28837ec62711cfedc576c36ac514d24b Mon Sep 17 00:00:00 2001 From: Emily Samp Date: Wed, 24 Jul 2024 15:32:54 -0500 Subject: [PATCH 2/3] Handle Prism -> Sorbet conversion for true and false nodes --- main/pipeline/pipeline.cc | 15 +++++++++++++-- test/prism_regression/false.parse-tree.exp | 2 ++ test/prism_regression/false.rb | 3 +++ test/prism_regression/true.parse-tree.exp | 2 ++ test/prism_regression/true.rb | 3 +++ 5 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 test/prism_regression/false.parse-tree.exp create mode 100644 test/prism_regression/false.rb create mode 100644 test/prism_regression/true.parse-tree.exp create mode 100644 test/prism_regression/true.rb diff --git a/main/pipeline/pipeline.cc b/main/pipeline/pipeline.cc index 4554d2a0a9f..79b50d4262e 100644 --- a/main/pipeline/pipeline.cc +++ b/main/pipeline/pipeline.cc @@ -159,6 +159,12 @@ core::LocOffsets locOffset(pm_location_t *loc, pm_parser_t *parser) { const unique_ptr convertPrismToSorbet(pm_node_t *node, pm_parser_t *parser, core::GlobalState &gs) { switch (PM_NODE_TYPE(node)) { + case PM_FALSE_NODE: { + auto falseNode = reinterpret_cast(node); + pm_location_t *loc = &falseNode->base.location; + + return make_unique(locOffset(loc, parser)); + } case PM_FLOAT_NODE: { auto floatNode = reinterpret_cast(node); pm_location_t *loc = &floatNode->base.location; @@ -220,6 +226,13 @@ const unique_ptr convertPrismToSorbet(pm_node_t *node, pm_parser_t // TODO: handle different string encodings return make_unique(locOffset(loc, parser), gs.enterNameUTF8(source)); } + case PM_TRUE_NODE: { + auto trueNode = reinterpret_cast(node); + pm_location_t *loc = &trueNode->base.location; + + return make_unique(locOffset(loc, parser)); + } + case PM_ALIAS_GLOBAL_VARIABLE_NODE: case PM_ALIAS_METHOD_NODE: case PM_ALTERNATION_PATTERN_NODE: @@ -270,7 +283,6 @@ const unique_ptr convertPrismToSorbet(pm_node_t *node, pm_parser_t case PM_EMBEDDED_STATEMENTS_NODE: case PM_EMBEDDED_VARIABLE_NODE: case PM_ENSURE_NODE: - case PM_FALSE_NODE: case PM_FIND_PATTERN_NODE: case PM_FLIP_FLOP_NODE: case PM_FOR_NODE: @@ -356,7 +368,6 @@ const unique_ptr convertPrismToSorbet(pm_node_t *node, pm_parser_t case PM_SPLAT_NODE: case PM_SUPER_NODE: case PM_SYMBOL_NODE: - case PM_TRUE_NODE: case PM_UNDEF_NODE: case PM_UNLESS_NODE: case PM_UNTIL_NODE: diff --git a/test/prism_regression/false.parse-tree.exp b/test/prism_regression/false.parse-tree.exp new file mode 100644 index 00000000000..e400eb766ea --- /dev/null +++ b/test/prism_regression/false.parse-tree.exp @@ -0,0 +1,2 @@ +False { +} diff --git a/test/prism_regression/false.rb b/test/prism_regression/false.rb new file mode 100644 index 00000000000..a69403d3d92 --- /dev/null +++ b/test/prism_regression/false.rb @@ -0,0 +1,3 @@ +# typed: strict + +false diff --git a/test/prism_regression/true.parse-tree.exp b/test/prism_regression/true.parse-tree.exp new file mode 100644 index 00000000000..1f47b310f39 --- /dev/null +++ b/test/prism_regression/true.parse-tree.exp @@ -0,0 +1,2 @@ +True { +} diff --git a/test/prism_regression/true.rb b/test/prism_regression/true.rb new file mode 100644 index 00000000000..4e8531f2f33 --- /dev/null +++ b/test/prism_regression/true.rb @@ -0,0 +1,3 @@ +# typed: strict + +true From 529367c25da56db1ecd46e89db447f77d49a0b74 Mon Sep 17 00:00:00 2001 From: Emily Samp Date: Wed, 24 Jul 2024 15:53:56 -0500 Subject: [PATCH 3/3] Implement Prism -> Sorbet conversion for if node --- main/pipeline/pipeline.cc | 18 ++++++++++++++++-- test/prism_regression/if.parse-tree.exp | 6 ++++++ test/prism_regression/if.rb | 3 +++ .../if_with_stmt.parse-tree.exp | 8 ++++++++ test/prism_regression/if_with_stmt.rb | 5 +++++ .../if_with_stmts.parse-tree.exp | 17 +++++++++++++++++ test/prism_regression/if_with_stmts.rb | 7 +++++++ 7 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 test/prism_regression/if.parse-tree.exp create mode 100644 test/prism_regression/if.rb create mode 100644 test/prism_regression/if_with_stmt.parse-tree.exp create mode 100644 test/prism_regression/if_with_stmt.rb create mode 100644 test/prism_regression/if_with_stmts.parse-tree.exp create mode 100644 test/prism_regression/if_with_stmts.rb diff --git a/main/pipeline/pipeline.cc b/main/pipeline/pipeline.cc index 79b50d4262e..ec7793881ca 100644 --- a/main/pipeline/pipeline.cc +++ b/main/pipeline/pipeline.cc @@ -157,7 +157,7 @@ core::LocOffsets locOffset(pm_location_t *loc, pm_parser_t *parser) { return core::LocOffsets{locStart, locEnd}; } -const unique_ptr convertPrismToSorbet(pm_node_t *node, pm_parser_t *parser, core::GlobalState &gs) { +unique_ptr convertPrismToSorbet(pm_node_t *node, pm_parser_t *parser, core::GlobalState &gs) { switch (PM_NODE_TYPE(node)) { case PM_FALSE_NODE: { auto falseNode = reinterpret_cast(node); @@ -171,6 +171,21 @@ const unique_ptr convertPrismToSorbet(pm_node_t *node, pm_parser_t return make_unique(locOffset(loc, parser), std::to_string(floatNode->value)); } + case PM_IF_NODE: { + auto ifNode = reinterpret_cast(node); + auto *loc = &ifNode->base.location; + + auto predicate = convertPrismToSorbet(ifNode->predicate, parser, gs); + + std::unique_ptr ifTrue; + + if (ifNode->statements != nullptr) { + ifTrue = convertPrismToSorbet(reinterpret_cast(ifNode->statements), parser, gs); + } + + // TODO: handle elsif/else clause + return make_unique(locOffset(loc, parser), std::move(predicate), std::move(ifTrue), nullptr); + } case PM_INTEGER_NODE: { auto intNode = reinterpret_cast(node); pm_location_t *loc = &intNode->base.location; @@ -297,7 +312,6 @@ const unique_ptr convertPrismToSorbet(pm_node_t *node, pm_parser_t case PM_GLOBAL_VARIABLE_WRITE_NODE: case PM_HASH_NODE: case PM_HASH_PATTERN_NODE: - case PM_IF_NODE: case PM_IMAGINARY_NODE: case PM_IMPLICIT_NODE: case PM_IMPLICIT_REST_NODE: diff --git a/test/prism_regression/if.parse-tree.exp b/test/prism_regression/if.parse-tree.exp new file mode 100644 index 00000000000..87ce4001a3e --- /dev/null +++ b/test/prism_regression/if.parse-tree.exp @@ -0,0 +1,6 @@ +If { + condition = True { + } + then_ = NULL + else_ = NULL +} diff --git a/test/prism_regression/if.rb b/test/prism_regression/if.rb new file mode 100644 index 00000000000..b77da0b04a1 --- /dev/null +++ b/test/prism_regression/if.rb @@ -0,0 +1,3 @@ +# typed: strict + +if true; end diff --git a/test/prism_regression/if_with_stmt.parse-tree.exp b/test/prism_regression/if_with_stmt.parse-tree.exp new file mode 100644 index 00000000000..6ae127f91fd --- /dev/null +++ b/test/prism_regression/if_with_stmt.parse-tree.exp @@ -0,0 +1,8 @@ +If { + condition = False { + } + then_ = Integer { + val = "5" + } + else_ = NULL +} diff --git a/test/prism_regression/if_with_stmt.rb b/test/prism_regression/if_with_stmt.rb new file mode 100644 index 00000000000..e8a87d8f6ab --- /dev/null +++ b/test/prism_regression/if_with_stmt.rb @@ -0,0 +1,5 @@ +# typed: static + +if false + 5 +end diff --git a/test/prism_regression/if_with_stmts.parse-tree.exp b/test/prism_regression/if_with_stmts.parse-tree.exp new file mode 100644 index 00000000000..20a8aaa50ed --- /dev/null +++ b/test/prism_regression/if_with_stmts.parse-tree.exp @@ -0,0 +1,17 @@ +If { + condition = True { + } + then_ = Begin { + stmts = [ + True { + } + Integer { + val = "4" + } + String { + val = + } + ] + } + else_ = NULL +} diff --git a/test/prism_regression/if_with_stmts.rb b/test/prism_regression/if_with_stmts.rb new file mode 100644 index 00000000000..7285cd0a5b0 --- /dev/null +++ b/test/prism_regression/if_with_stmts.rb @@ -0,0 +1,7 @@ +# typed: strict + +if true + true + 4 + "string" +end