Skip to content

Commit

Permalink
fix: Propagate locations correctly for enums (#213)
Browse files Browse the repository at this point in the history
The old code triggered an ENFORCE when encountering enums; this patch fixes that issue.
However, the handling is not quite right, as we're not emitting a definition correctly.
We do emit an extra class def/ref, however, the class is not referenced elsewhere,
the constant is. Follow-up issue for improving that:
  • Loading branch information
varungandhi-src authored Jul 9, 2024
1 parent 9058a6a commit 527916d
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 3 deletions.
2 changes: 1 addition & 1 deletion cfg/builder/builder_walk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ BasicBlock *CFGBuilder::walk(CFGContext cctx, ast::ExpressionPtr &what, BasicBlo
[&](ast::Assign &a) {
LocalRef lhs;
if (auto lhsIdent = ast::cast_tree<ast::ConstantLit>(a.lhs)) {
lhs = global2Local(cctx, lhsIdent->symbol, a.loc);
lhs = global2Local(cctx, lhsIdent->symbol, a.lhs.loc());
} else if (auto lhsLocal = ast::cast_tree<ast::Local>(a.lhs)) {
lhs = cctx.inWhat.enterLocal(lhsLocal->localVariable);
} else if (auto ident = ast::cast_tree<ast::UnresolvedIdent>(a.lhs)) {
Expand Down
7 changes: 5 additions & 2 deletions rewriter/TEnum.cc
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,10 @@ std::optional<ProcessStatResult> processStat(core::MutableContext ctx, ast::Clas

auto statLocZero = stat.loc().copyWithZeroLength();
auto name = ctx.state.enterNameConstant(ctx.state.freshNameUnique(core::UniqueNameKind::TEnum, lhs->cnst, 1));
auto classCnst = ast::MK::UnresolvedConstant(statLocZero, ast::MK::EmptyTree(), name);
// For some reason, Sorbet uses a zero-length range here,
// but it seems like we need this for scip-ruby?
// https://github.com/sorbet/sorbet/pull/7092
auto classCnst = ast::MK::UnresolvedConstant(lhs->loc, ast::MK::EmptyTree(), name);
ast::ClassDef::ANCESTORS_store parent;
parent.emplace_back(klass->name.deepCopy());
ast::ClassDef::RHS_store classRhs;
Expand Down Expand Up @@ -243,7 +246,7 @@ void TEnum::run(core::MutableContext ctx, ast::ClassDef *klass) {
auto serializeReturnTypeClass = core::cast_type_nonnull<core::ClassType>(serializeReturnType);
ast::ExpressionPtr return_type_ast = ast::MK::Constant(klass->declLoc, serializeReturnTypeClass.symbol);
auto sig = ast::MK::Sig0(klass->declLoc, std::move(return_type_ast));
auto method = ast::MK::SyntheticMethod0(klass->loc, klass->declLoc, klass->loc, core::Names::serialize(),
auto method = ast::MK::SyntheticMethod0(klass->loc, klass->declLoc, klass->name.loc(), core::Names::serialize(),
ast::MK::RaiseTypedUnimplemented(klass->declLoc));
ast::Send::ARGS_store nargs;
ast::Send::Flags flags;
Expand Down
10 changes: 10 additions & 0 deletions test/scip/testdata/enum.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# typed: struct

class X < T::Enum
enums do
A = new("A")
B = new
end

All = T.let([A, B], T::Array[X])
end
32 changes: 32 additions & 0 deletions test/scip/testdata/enum.snapshot.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# typed: struct

class X < T::Enum
# ^ reference [..] X#
# ^ definition [..] X#
# ^ definition [..] X#serialize().
# ^ reference [..] T#
# ^^^^ reference [..] Module#public().
# ^^^^ reference [..] String#
# ^^^^ reference [..] T#Enum#
enums do
A = new("A")
# ^ definition local 2~#119448696
# ^ definition [..] X#A#
# ^ reference [..] X#A#
# ^ reference [..] X#A.
# ^^^ reference [..] Class#new().
B = new
# ^ definition local 5~#119448696
# ^ definition [..] X#B#
# ^ reference [..] X#B#
# ^ reference [..] X#B.
# ^^^ reference [..] Class#new().
end

All = T.let([A, B], T::Array[X])
# ^^^ definition [..] X#All.
# ^ reference [..] X#A.
# ^ reference [..] X#B.
# ^^^^^^^^ definition local 8~#119448696
# ^ reference [..] X#
end

0 comments on commit 527916d

Please sign in to comment.