Skip to content

Commit

Permalink
Merge pull request #211 from Shopify/Alex/translate-module
Browse files Browse the repository at this point in the history
Implement Prism -> Sorbet translation for `module` declarations
  • Loading branch information
amomchilov authored Aug 22, 2024
2 parents ebea65c + 207c182 commit 1ddd437
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 11 deletions.
22 changes: 15 additions & 7 deletions parser/prism/Translator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -130,14 +130,12 @@ std::unique_ptr<parser::Node> Translator::translate(pm_node_t *node) {
pm_location_t *declLoc = &classNode->class_keyword_loc;

auto name = translate(reinterpret_cast<pm_node *>(classNode->constant_path));
std::unique_ptr<parser::Node> superclass;
auto superclass = translate(classNode->superclass);

if (classNode->superclass != nullptr) {
superclass = translate(reinterpret_cast<pm_node *>(classNode->superclass));
}
auto body = translate(classNode->body);

return make_unique<parser::Class>(parser.translateLocation(loc), parser.translateLocation(declLoc),
std::move(name), std::move(superclass), nullptr);
std::move(name), std::move(superclass), std::move(body));
}
case PM_CONSTANT_PATH_NODE: {
// Part of a constant path, like the `A` in `A::B`. `B` is a `PM_CONSTANT_READ_NODE`
Expand All @@ -150,7 +148,7 @@ std::unique_ptr<parser::Node> Translator::translate(pm_node_t *node) {
if (constantPathNode->parent) {
// This constant reference is chained onto another constant reference.
// E.g. if `node` is pointing to `B`, then then `A` is the `parent` in `A::B::C`.
parent = translate(reinterpret_cast<pm_node *>(constantPathNode->parent));
parent = translate(constantPathNode->parent);
} else { // This is a fully qualified constant reference, like `::A`.
pm_location_t *delimiterLoc = &constantPathNode->delimiter_loc; // The location of the `::`
parent = make_unique<parser::Cbase>(parser.translateLocation(delimiterLoc));
Expand Down Expand Up @@ -284,6 +282,17 @@ std::unique_ptr<parser::Node> Translator::translate(pm_node_t *node) {

return make_unique<parser::Kwrestarg>(parser.translateLocation(loc), gs.enterNameUTF8(name));
}
case PM_MODULE_NODE: { // Modules declarations, like `module A::B::C; ...; end`
auto moduleNode = reinterpret_cast<pm_module_node *>(node);
pm_location_t *loc = &moduleNode->base.location;
pm_location_t *declLoc = &moduleNode->module_keyword_loc;

auto name = translate(moduleNode->constant_path);
auto body = translate(moduleNode->body);

return make_unique<parser::Module>(parser.translateLocation(loc), parser.translateLocation(declLoc),
std::move(name), std::move(body));
}
case PM_NIL_NODE: {
auto nilNode = reinterpret_cast<pm_nil_node *>(node);
pm_location_t *loc = &nilNode->base.location;
Expand Down Expand Up @@ -619,7 +628,6 @@ std::unique_ptr<parser::Node> Translator::translate(pm_node_t *node) {
case PM_MATCH_REQUIRED_NODE:
case PM_MATCH_WRITE_NODE:
case PM_MISSING_NODE:
case PM_MODULE_NODE:
case PM_MULTI_TARGET_NODE:
case PM_MULTI_WRITE_NODE:
case PM_NEXT_NODE:
Expand Down
28 changes: 26 additions & 2 deletions test/prism_regression/class.parse-tree.exp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,19 @@ Begin {
name = <C <U Parent>>
}
superclass = NULL
body = NULL
body = Begin {
stmts = [
Integer {
val = "1"
}
Integer {
val = "2"
}
Integer {
val = "3"
}
]
}
}
Class {
name = Const {
Expand All @@ -22,7 +34,19 @@ Begin {
SClass {
expr = Self {
}
body = NULL
body = Begin {
stmts = [
Integer {
val = "4"
}
Integer {
val = "5"
}
Integer {
val = "6"
}
]
}
}
SClass {
expr = Const {
Expand Down
13 changes: 11 additions & 2 deletions test/prism_regression/class.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
# typed: strict

class Parent; end
class Parent
1
2
3
end

class Child < Parent; end

class << self; end
class << self
4
5
6
end

class << Parent; end
# ^^^^^^ error: `class << EXPRESSION` is only supported for `class << self`
19 changes: 19 additions & 0 deletions test/prism_regression/module.parse-tree.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Module {
name = Const {
scope = NULL
name = <C <U M>>
}
body = Begin {
stmts = [
Integer {
val = "1"
}
Integer {
val = "2"
}
Integer {
val = "3"
}
]
}
}
7 changes: 7 additions & 0 deletions test/prism_regression/module.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# typed: strict

module M
1
2
3
end

0 comments on commit 1ddd437

Please sign in to comment.