Skip to content

Commit babdbed

Browse files
fix: Fix bug where LocOffsets in AliasMap were incorrect. (#26)
* fix: Fix bug in NamedSymbolRef's kind() method. * cleanup: Add more useful error message for an enforce. * fix: Fix bug where LocOffsets in AliasMap were incorrect.
1 parent ff8725b commit babdbed

File tree

3 files changed

+44
-5
lines changed

3 files changed

+44
-5
lines changed

scip_indexer/SCIPIndexer.cc

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -230,9 +230,27 @@ class NamedSymbolRef final {
230230
if (this->selfOrOwner.isFieldOrStaticField()) {
231231
return Kind::StaticField;
232232
}
233+
if (this->selfOrOwner.isMethod()) {
234+
return Kind::Method;
235+
}
233236
return Kind::ClassOrModule;
234237
}
235238

239+
string showRaw(const core::GlobalState &gs) const {
240+
switch (this->kind()) {
241+
case Kind::UndeclaredField:
242+
return fmt::format("UndeclaredField(owner: {}, name: {})", this->selfOrOwner.showFullName(gs),
243+
this->name.toString(gs));
244+
case Kind::StaticField:
245+
return fmt::format("StaticField {}", this->selfOrOwner.showFullName(gs));
246+
case Kind::ClassOrModule:
247+
return fmt::format("ClassOrModule {}", this->selfOrOwner.showFullName(gs));
248+
case Kind::Method:
249+
return fmt::format("Method {}", this->selfOrOwner.showFullName(gs));
250+
}
251+
ENFORCE(false, "impossible");
252+
}
253+
236254
core::SymbolRef asSymbolRef() const {
237255
ENFORCE(this->kind() != Kind::UndeclaredField);
238256
return this->selfOrOwner;
@@ -578,6 +596,11 @@ class AliasMap final {
578596
auto &gs = ctx.state;
579597
auto method = ctx.owner;
580598
auto klass = method.owner(gs);
599+
// Make sure that the offsets we store here match the offsets we use
600+
// in saveDefinition/saveReference.
601+
auto trim = [&](core::LocOffsets loc) -> core::LocOffsets {
602+
return trimColonColonPrefix(gs, core::Loc(ctx.file, loc)).offsets();
603+
};
581604
for (auto &bb : cfg.basicBlocks) {
582605
for (auto &bind : bb->exprs) {
583606
auto *instr = cfg::cast_instruction<cfg::Alias>(bind.value);
@@ -592,12 +615,13 @@ class AliasMap final {
592615
}
593616
if (sym == core::Symbols::Magic_undeclaredFieldStub()) {
594617
ENFORCE(!bind.loc.empty());
595-
this->map.insert(
618+
this->map.insert( // no trim(...) because undeclared fields shouldn't have ::
596619
{bind.bind.variable, {NamedSymbolRef::undeclaredField(klass, instr->name), bind.loc, false}});
597620
continue;
598621
}
599622
if (sym.isStaticField(gs)) {
600-
this->map.insert({bind.bind.variable, {NamedSymbolRef::staticField(instr->what), bind.loc, false}});
623+
this->map.insert(
624+
{bind.bind.variable, {NamedSymbolRef::staticField(instr->what), trim(bind.loc), false}});
601625
continue;
602626
}
603627
// Outside of definition contexts for classes & modules,
@@ -614,7 +638,7 @@ class AliasMap final {
614638
if (!loc.exists() || loc.empty()) { // For special classes like Sorbet::Private::Static
615639
continue;
616640
}
617-
this->map.insert({bind.bind.variable, {NamedSymbolRef::classOrModule(sym), loc, false}});
641+
this->map.insert({bind.bind.variable, {NamedSymbolRef::classOrModule(sym), trim(loc), false}});
618642
}
619643
}
620644
}
@@ -954,9 +978,11 @@ class CFGTraversal final {
954978
}
955979
}
956980
// Sort for determinism
957-
fast_sort(todo, [](const SymbolWithLoc &p1, const SymbolWithLoc &p2) -> bool {
981+
fast_sort(todo, [&](const SymbolWithLoc &p1, const SymbolWithLoc &p2) -> bool {
958982
ENFORCE(p1.second.beginPos() != p2.second.beginPos(),
959-
"Different alias instructions should correspond to different start offsets");
983+
"found alias instructions with same start offset in {}, source:\n{}\nsym1 = {}, sym2 = {}\n",
984+
file.data(gs).path(), core::Loc(file, p1.second).toString(gs), p1.first.showRaw(gs),
985+
p2.first.showRaw(gs));
960986
return p1.second.beginPos() < p2.second.beginPos();
961987
});
962988
// NOTE:(varun) Not 100% sure if emitting a reference here. Here's why it's written this

test/scip/testdata/types.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# typed: true
2+
3+
def f()
4+
T.let(true, T::Boolean)
5+
end

test/scip/testdata/types.snapshot.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# typed: true
2+
3+
def f()
4+
#^^^^^^^ definition scip-ruby gem TODO TODO Object#f().
5+
T.let(true, T::Boolean)
6+
# ^ reference scip-ruby gem TODO TODO T#
7+
# ^^^^^^^ reference scip-ruby gem TODO TODO T#Boolean.
8+
end

0 commit comments

Comments
 (0)