@@ -33,13 +33,22 @@ template <typename... Tail> bool hasExpr(const std::unique_ptr<parser::Node> &he
3333 return hasExpr (head) && hasExpr (tail...);
3434}
3535
36+ // Helper to extract desugared expression or return EmptyTree if node is null.
37+ ExpressionPtr takeDesugaredExprOrEmptyTree (const std::unique_ptr<parser::Node> &node) {
38+ if (node == nullptr ) {
39+ return MK::EmptyTree ();
40+ }
41+ ENFORCE (node->hasDesugaredExpr (), " Node has no desugared expression" );
42+ return node->takeDesugaredExpr ();
43+ }
44+
3645// Helper template to convert nodes to any store type with takeDesugaredExpr or EmptyTree for nulls.
3746// This is used to convert a NodeVec to the store type argument for nodes including `Send`, `InsSeq`.
3847template <typename StoreType> StoreType nodeVecToStore (const sorbet::parser::NodeVec &nodes) {
3948 StoreType store;
4049 store.reserve (nodes.size ());
4150 for (const auto &node : nodes) {
42- store.emplace_back (node ? node-> takeDesugaredExpr () : sorbet::ast::MK::EmptyTree ( ));
51+ store.emplace_back (takeDesugaredExprOrEmptyTree (node ));
4352 }
4453 return store;
4554}
@@ -1110,7 +1119,7 @@ unique_ptr<parser::Node> Translator::translate(pm_node_t *node, bool preserveCon
11101119 ExpressionPtr breakArgs;
11111120 if (arguments.size () == 1 ) {
11121121 auto &first = arguments[0 ];
1113- breakArgs = first == nullptr ? MK::EmptyTree () : first-> takeDesugaredExpr ( );
1122+ breakArgs = takeDesugaredExprOrEmptyTree ( first);
11141123 } else {
11151124 auto args = nodeVecToStore<ast::Array::ENTRY_store>(arguments);
11161125 auto arrayLocation = parser.translateLocation (breakNode->arguments ->base .location );
@@ -1630,8 +1639,7 @@ unique_ptr<parser::Node> Translator::translate(pm_node_t *node, bool preserveCon
16301639 blockExpr = desugarSymbolProc (symbol);
16311640 } else {
16321641 auto blockLoc = translateLoc (prismBlock->location );
1633- auto blockBodyExpr =
1634- blockBody == nullptr ? MK::EmptyTree () : blockBody->takeDesugaredExpr ();
1642+ auto blockBodyExpr = takeDesugaredExprOrEmptyTree (blockBody);
16351643 blockExpr = MK::Block (blockLoc, move (blockBodyExpr), move (blockParamsStore));
16361644 }
16371645
@@ -1748,7 +1756,7 @@ unique_ptr<parser::Node> Translator::translate(pm_node_t *node, bool preserveCon
17481756 blockExpr = desugarSymbolProc (symbol);
17491757 } else {
17501758 auto blockLoc = translateLoc (prismBlock->location );
1751- auto blockBodyExpr = blockBody == nullptr ? MK::EmptyTree () : blockBody-> takeDesugaredExpr ( );
1759+ auto blockBodyExpr = takeDesugaredExprOrEmptyTree ( blockBody);
17521760 blockExpr = MK::Block (blockLoc, move (blockBodyExpr), move (blockParamsStore));
17531761 }
17541762
@@ -1829,7 +1837,7 @@ unique_ptr<parser::Node> Translator::translate(pm_node_t *node, bool preserveCon
18291837 }
18301838
18311839 // Start with the else clause as the final else
1832- ExpressionPtr resultExpr = elseClause == nullptr ? MK::EmptyTree () : elseClause-> takeDesugaredExpr ( );
1840+ ExpressionPtr resultExpr = takeDesugaredExprOrEmptyTree ( elseClause);
18331841
18341842 // Build the if ladder backwards from the last "in" to the first
18351843 for (auto it = inNodes.rbegin (); it != inNodes.rend (); ++it) {
@@ -1841,7 +1849,7 @@ unique_ptr<parser::Node> Translator::translate(pm_node_t *node, bool preserveCon
18411849 auto matchExpr = MK::RaiseUnimplemented (patternLoc);
18421850
18431851 // The body is the statements from the "in" clause
1844- auto thenExpr = inPattern->body != nullptr ? inPattern-> body -> takeDesugaredExpr () : MK::EmptyTree ( );
1852+ auto thenExpr = takeDesugaredExprOrEmptyTree ( inPattern->body );
18451853
18461854 // Collect pattern variable assignments from the pattern
18471855 ast::InsSeq::STATS_store vars;
@@ -1910,7 +1918,7 @@ unique_ptr<parser::Node> Translator::translate(pm_node_t *node, bool preserveCon
19101918
19111919 ast::Send::ARGS_store args;
19121920 args.reserve (2 + whenNodes.size () + totalPatterns); // +2 is for the predicate and the patterns count
1913- args.emplace_back (predicate == nullptr ? MK::EmptyTree () : predicate-> takeDesugaredExpr ( ));
1921+ args.emplace_back (takeDesugaredExprOrEmptyTree ( predicate));
19141922 args.emplace_back (MK::Int (locZeroLen, totalPatterns));
19151923
19161924 for (auto &whenNodePtr : whenNodes) {
@@ -1919,20 +1927,18 @@ unique_ptr<parser::Node> Translator::translate(pm_node_t *node, bool preserveCon
19191927 // Each pattern node already has a desugared expression (populated by translateMulti +
19201928 // NodeWithExpr). Consume them now; the wrapper's placeholder expression is intentionally ignored.
19211929 for (auto &patternNode : whenNodeWrapped->patterns ) {
1922- args.emplace_back (patternNode == nullptr ? MK::EmptyTree () : patternNode-> takeDesugaredExpr ( ));
1930+ args.emplace_back (takeDesugaredExprOrEmptyTree ( patternNode));
19231931 }
19241932 }
19251933
19261934 for (auto &whenNodePtr : whenNodes) {
19271935 auto whenNodeWrapped = parser::NodeWithExpr::cast_node<parser::When>(whenNodePtr.get ());
19281936 ENFORCE (whenNodeWrapped != nullptr , " case without a when?" );
19291937 // The body node also carries a real expression once translateStatements has run.
1930- auto bodyExpr =
1931- whenNodeWrapped->body == nullptr ? MK::EmptyTree () : whenNodeWrapped->body ->takeDesugaredExpr ();
1932- args.emplace_back (move (bodyExpr));
1938+ args.emplace_back (takeDesugaredExprOrEmptyTree (whenNodeWrapped->body ));
19331939 }
19341940
1935- args.emplace_back (elseClause == nullptr ? MK::EmptyTree () : elseClause-> takeDesugaredExpr ( ));
1941+ args.emplace_back (takeDesugaredExprOrEmptyTree ( elseClause));
19361942
19371943 // Desugar to `::Magic.caseWhen(predicate, num_patterns, patterns..., bodies..., else)`
19381944 auto expr = MK::Send (location, MK::Magic (locZeroLen), core::Names::caseWhen (), locZeroLen, args.size (),
@@ -1955,15 +1961,15 @@ unique_ptr<parser::Node> Translator::translate(pm_node_t *node, bool preserveCon
19551961
19561962 // The if/else ladder for the entire case statement, starting with the else clause as the final `else` when
19571963 // building backwards
1958- ExpressionPtr resultExpr = elseClause == nullptr ? MK::EmptyTree () : elseClause-> takeDesugaredExpr ( );
1964+ ExpressionPtr resultExpr = takeDesugaredExprOrEmptyTree ( elseClause);
19591965
19601966 for (auto it = whenNodes.rbegin (); it != whenNodes.rend (); ++it) {
19611967 auto whenNodeWrapped = parser::NodeWithExpr::cast_node<parser::When>(it->get ());
19621968 ENFORCE (whenNodeWrapped != nullptr , " case without a when?" );
19631969
19641970 ExpressionPtr patternsResult; // the if/else ladder for this when clause's patterns
19651971 for (auto &patternNode : whenNodeWrapped->patterns ) {
1966- auto patternExpr = patternNode == nullptr ? MK::EmptyTree () : patternNode-> takeDesugaredExpr ( );
1972+ auto patternExpr = takeDesugaredExprOrEmptyTree ( patternNode);
19671973 auto patternLoc = patternExpr.loc ();
19681974
19691975 ExpressionPtr testExpr;
@@ -1998,8 +2004,7 @@ unique_ptr<parser::Node> Translator::translate(pm_node_t *node, bool preserveCon
19982004 }
19992005 }
20002006
2001- auto thenExpr =
2002- whenNodeWrapped->body != nullptr ? whenNodeWrapped->body ->takeDesugaredExpr () : MK::EmptyTree ();
2007+ auto thenExpr = takeDesugaredExprOrEmptyTree (whenNodeWrapped->body );
20032008 resultExpr = MK::If (whenNodeWrapped->loc , move (patternsResult), move (thenExpr), move (resultExpr));
20042009 }
20052010
@@ -2232,7 +2237,7 @@ unique_ptr<parser::Node> Translator::translate(pm_node_t *node, bool preserveCon
22322237 }
22332238 }
22342239
2235- auto methodBody = body == nullptr ? MK::EmptyTree () : body-> takeDesugaredExpr ( );
2240+ auto methodBody = takeDesugaredExprOrEmptyTree ( body);
22362241
22372242 auto methodExpr = MK::Method (location, declLoc, name, move (paramsStore), move (methodBody));
22382243
@@ -2413,7 +2418,7 @@ unique_ptr<parser::Node> Translator::translate(pm_node_t *node, bool preserveCon
24132418 canProvideNiceDesugar = parser::NodeWithExpr::isa_node<parser::LVarLhs>(variable.get ());
24142419 }
24152420
2416- auto bodyExpr = body ? body-> takeDesugaredExpr () : MK::EmptyTree ( );
2421+ auto bodyExpr = takeDesugaredExprOrEmptyTree (body );
24172422 auto collectionExpr = collection->takeDesugaredExpr ();
24182423 auto locZeroLen = location.copyWithZeroLength ();
24192424 ast::MethodDef::PARAMS_store params;
@@ -2988,7 +2993,7 @@ unique_ptr<parser::Node> Translator::translate(pm_node_t *node, bool preserveCon
29882993 ExpressionPtr nextArgs;
29892994 if (arguments.size () == 1 ) {
29902995 auto &first = arguments[0 ];
2991- nextArgs = first == nullptr ? MK::EmptyTree () : first-> takeDesugaredExpr ( );
2996+ nextArgs = takeDesugaredExprOrEmptyTree ( first);
29922997 } else {
29932998 auto args = nodeVecToStore<ast::Array::ENTRY_store>(arguments);
29942999 auto arrayLocation = parser.translateLocation (nextNode->arguments ->base .location );
@@ -3148,8 +3153,8 @@ unique_ptr<parser::Node> Translator::translate(pm_node_t *node, bool preserveCon
31483153 auto recv = MK::Magic (location);
31493154 auto locZeroLen = core::LocOffsets{location.beginPos (), location.beginPos ()};
31503155
3151- auto fromExpr = left ? left-> takeDesugaredExpr () : MK::EmptyTree ( );
3152- auto toExpr = right ? right-> takeDesugaredExpr () : MK::EmptyTree ( );
3156+ auto fromExpr = takeDesugaredExprOrEmptyTree (left );
3157+ auto toExpr = takeDesugaredExprOrEmptyTree (right );
31533158
31543159 auto excludeEndExpr = isExclusive ? MK::True (location) : MK::False (location);
31553160
@@ -3280,7 +3285,7 @@ unique_ptr<parser::Node> Translator::translate(pm_node_t *node, bool preserveCon
32803285 ExpressionPtr returnArgs;
32813286 if (returnValues.size () == 1 ) {
32823287 auto &first = returnValues[0 ];
3283- returnArgs = first == nullptr ? MK::EmptyTree () : first-> takeDesugaredExpr ( );
3288+ returnArgs = takeDesugaredExprOrEmptyTree ( first);
32843289 } else {
32853290 auto args = nodeVecToStore<ast::Array::ENTRY_store>(std::move (returnValues));
32863291 auto arrayLocation = parser.translateLocation (returnNode->arguments ->base .location );
@@ -3487,7 +3492,7 @@ unique_ptr<parser::Node> Translator::translate(pm_node_t *node, bool preserveCon
34873492 }
34883493 } else {
34893494 auto cond = predicate->takeDesugaredExpr ();
3490- auto body = statements ? statements-> takeDesugaredExpr () : MK::EmptyTree ( );
3495+ auto body = takeDesugaredExprOrEmptyTree (statements );
34913496 if (beginModifier) {
34923497 auto breaker =
34933498 MK::If (location, std::move (cond), MK::Break (location, MK::EmptyTree ()), MK::EmptyTree ());
@@ -3529,7 +3534,7 @@ unique_ptr<parser::Node> Translator::translate(pm_node_t *node, bool preserveCon
35293534 }
35303535 } else {
35313536 auto cond = predicate->takeDesugaredExpr ();
3532- auto body = statements ? statements-> takeDesugaredExpr () : MK::EmptyTree ( );
3537+ auto body = takeDesugaredExprOrEmptyTree (statements );
35333538 if (beginModifier) {
35343539 // TODO using bang (aka !) is not semantically correct because it can be overridden by the user.
35353540 auto negatedCond =
@@ -4926,11 +4931,7 @@ unique_ptr<parser::Node> Translator::translateRescue(pm_begin_node *parentBeginN
49264931 // Regular local variable
49274932 varExpr = var->takeDesugaredExpr ();
49284933
4929- if (rescueBody != nullptr ) {
4930- rescueBodyExpr = rescueBody->takeDesugaredExpr ();
4931- } else {
4932- rescueBodyExpr = ast::MK::EmptyTree ();
4933- }
4934+ rescueBodyExpr = takeDesugaredExprOrEmptyTree (rescueBody);
49344935 } else if (isReference) {
49354936 // Non-local reference (lvalue exception variables like @ex, @@ex, $ex)
49364937 // Create a temp variable and wrap the body
@@ -4945,7 +4946,7 @@ unique_ptr<parser::Node> Translator::translateRescue(pm_begin_node *parentBeginN
49454946 ast::InsSeq::STATS_store stats;
49464947 stats.emplace_back (move (assignExpr));
49474948
4948- auto bodyExpr = rescueBody != nullptr ? rescueBody-> takeDesugaredExpr () : ast::MK::EmptyTree ( );
4949+ auto bodyExpr = takeDesugaredExprOrEmptyTree (rescueBody );
49494950 rescueBodyExpr = ast::MK::InsSeq (varLoc, move (stats), move (bodyExpr));
49504951 } else {
49514952 // For bare rescue clauses with no variable, create a <rescueTemp> variable
@@ -4957,7 +4958,7 @@ unique_ptr<parser::Node> Translator::translateRescue(pm_begin_node *parentBeginN
49574958 : rescueKeywordLoc;
49584959 varExpr = ast::MK::Local (syntheticVarLoc, rescueTemp);
49594960
4960- rescueBodyExpr = rescueBody != nullptr ? rescueBody-> takeDesugaredExpr () : ast::MK::EmptyTree ( );
4961+ rescueBodyExpr = takeDesugaredExprOrEmptyTree (rescueBody );
49614962 }
49624963
49634964 auto rescueCaseExpr = ast::make_expression<ast::RescueCase>(resbodyLoc, move (astExceptions), move (varExpr),
@@ -5028,12 +5029,7 @@ unique_ptr<parser::Node> Translator::translateRescue(pm_begin_node *parentBeginN
50285029 }
50295030
50305031 // Build the ast::Rescue expression
5031- ast::ExpressionPtr bodyExpr;
5032- if (bodyNode != nullptr ) {
5033- bodyExpr = bodyNode->takeDesugaredExpr ();
5034- } else {
5035- bodyExpr = ast::MK::EmptyTree ();
5036- }
5032+ auto bodyExpr = takeDesugaredExprOrEmptyTree (bodyNode);
50375033
50385034 // Extract RescueCase expressions from each Resbody node
50395035 ast::Rescue::RESCUE_CASE_store rescueCases;
@@ -5047,8 +5043,7 @@ unique_ptr<parser::Node> Translator::translateRescue(pm_begin_node *parentBeginN
50475043 }
50485044
50495045 // Extract the else expression
5050- ast::ExpressionPtr elseExpr;
5051- elseExpr = (elseNode != nullptr ) ? elseNode->takeDesugaredExpr () : ast::MK::EmptyTree ();
5046+ auto elseExpr = takeDesugaredExprOrEmptyTree (elseNode);
50525047
50535048 // Build the ast::Rescue expression (ensure is EmptyTree since this is translateRescue, not translateEnsure)
50545049 auto rescueExpr = ast::make_expression<ast::Rescue>(rescueLoc, move (bodyExpr), move (rescueCases), move (elseExpr),
@@ -5127,7 +5122,7 @@ NodeVec Translator::translateEnsure(pm_begin_node *beginNode) {
51275122 auto rescue = ast::cast_tree<ast::Rescue>(bodyExpr);
51285123 ENFORCE (rescue != nullptr , " translatedRescue should be a Rescue node" );
51295124
5130- rescue->ensure = ensureBody != nullptr ? ensureBody-> takeDesugaredExpr () : ast::MK::EmptyTree ( );
5125+ rescue->ensure = takeDesugaredExprOrEmptyTree (ensureBody );
51315126
51325127 translatedEnsure =
51335128 make_node_with_expr<parser::Ensure>(move (bodyExpr), loc, move (translatedRescue), move (ensureBody));
@@ -5158,11 +5153,8 @@ NodeVec Translator::translateEnsure(pm_begin_node *beginNode) {
51585153 } else {
51595154 // Build ast::Rescue expression with ensure field set
51605155 // When there's no rescue clause, create a new Rescue with empty rescue cases
5161- ast::ExpressionPtr bodyExpr;
5162- bodyExpr = (bodyNode != nullptr ) ? bodyNode->takeDesugaredExpr () : ast::MK::EmptyTree ();
5163-
5164- ast::ExpressionPtr ensureExpr =
5165- (ensureBody != nullptr ) ? ensureBody->takeDesugaredExpr () : ast::MK::EmptyTree ();
5156+ auto bodyExpr = takeDesugaredExprOrEmptyTree (bodyNode);
5157+ auto ensureExpr = takeDesugaredExprOrEmptyTree (ensureBody);
51665158
51675159 // Create ast::Rescue with empty rescue cases
51685160 ast::Rescue::RESCUE_CASE_store emptyCases;
@@ -5250,8 +5242,8 @@ unique_ptr<parser::Node> Translator::translateIfNode(core::LocOffsets location,
52505242 }
52515243
52525244 auto condExpr = predicate->takeDesugaredExpr ();
5253- auto thenExpr = ifTrue ? ifTrue-> takeDesugaredExpr () : MK::EmptyTree ( );
5254- auto elseExpr = ifFalse ? ifFalse-> takeDesugaredExpr () : MK::EmptyTree ( );
5245+ auto thenExpr = takeDesugaredExprOrEmptyTree (ifTrue );
5246+ auto elseExpr = takeDesugaredExprOrEmptyTree (ifFalse );
52555247 auto ifNode = MK::If (location, move (condExpr), move (thenExpr), move (elseExpr));
52565248 return make_node_with_expr<parser::If>(move (ifNode), location, move (predicate), move (ifTrue), move (ifFalse));
52575249}
0 commit comments