Skip to content

Commit da62c0c

Browse files
authored
Desugar forwarding super with block (sorbet#9904)
1 parent 4134404 commit da62c0c

File tree

1 file changed

+25
-11
lines changed

1 file changed

+25
-11
lines changed

parser/prism/Translator.cc

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2224,24 +2224,38 @@ ast::ExpressionPtr Translator::desugar(pm_node_t *node) {
22242224
unreachable("PM_FORWARDING_PARAMETER_NODE is handled separately in `desugarParametersNode()`.");
22252225
}
22262226
case PM_FORWARDING_SUPER_NODE: { // A `super` with no explicit arguments
2227-
// It might have a literal block argument, though.
2228-
2227+
// Surprisingly, a forwarding `super` call can still have a literal block argument, like `super { }`.
22292228
auto forwardingSuperNode = down_cast<pm_forwarding_super_node>(node);
22302229

2231-
// There's no `keyword_loc` field, so we make it ourselves from the start location.
2232-
// constexpr uint32_t length = "super"sv.size();
2233-
// auto keywordLoc = translateLoc(node->location.start, node->location.start + length);
2230+
if (auto *blockNode = forwardingSuperNode->block) { // always a PM_BLOCK_NODE
2231+
// Desugar `super { ... }` to `self.<super>(<ZSuperArgs>) { ... }`
2232+
2233+
// Compute keyword location from the start of the node (since there's no `keyword_loc` field)
2234+
constexpr uint32_t length = "super"sv.size();
2235+
auto superKeywordLoc = translateLoc(node->location.start, node->location.start + length);
2236+
2237+
auto receiver = MK::Self(superKeywordLoc.copyWithZeroLength());
22342238

2235-
auto expr = MK::ZSuper(location, maybeTypedSuper());
2239+
auto methodName = maybeTypedSuper();
22362240

2237-
auto blockArgumentNode = forwardingSuperNode->block;
2241+
auto posArgs = 1;
22382242

2239-
if (blockArgumentNode != nullptr) { // always a PM_BLOCK_NODE
2240-
categoryCounterInc("Prism fallback", "PM_FORWARDING_SUPER_NODE with block");
2241-
throw PrismFallback{}; // TODO: Not implemented yet
2243+
auto block = desugarLiteralBlock(blockNode->body, blockNode->parameters, blockNode->base.location,
2244+
blockNode->opening_loc);
2245+
2246+
ast::Send::ARGS_store args;
2247+
args.reserve(2);
2248+
args.emplace_back(ast::make_expression<ast::ZSuperArgs>(superKeywordLoc.copyEndWithZeroLength()));
2249+
args.emplace_back(move(block));
2250+
2251+
ast::Send::Flags flags;
2252+
flags.isPrivateOk = true;
2253+
flags.hasBlock = true;
2254+
2255+
return MK::Send(location, move(receiver), methodName, location, posArgs, move(args), flags);
22422256
}
22432257

2244-
return expr;
2258+
return MK::ZSuper(location, maybeTypedSuper());
22452259
}
22462260
case PM_GLOBAL_VARIABLE_AND_WRITE_NODE: { // And-assignment to a global variable, e.g. `$g &&= false`
22472261
return desugarVariableOpAssign<pm_global_variable_and_write_node, OpAssignKind::And,

0 commit comments

Comments
 (0)