Skip to content

Commit d1b83d5

Browse files
fix: Emit qualified names for symbols
1 parent 939f17b commit d1b83d5

File tree

9 files changed

+83
-66
lines changed

9 files changed

+83
-66
lines changed

scip_indexer/SCIPIndexer.cc

Lines changed: 42 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -134,36 +134,49 @@ absl::Status symbolForExpr(const core::GlobalState &gs, core::SymbolRef symRef,
134134
package.set_version("TODO");
135135
*symbol.mutable_package() = move(package);
136136

137-
scip::Descriptor descriptor;
138-
*descriptor.mutable_name() = symRef.name(gs).show(gs);
139-
140-
// TODO: Are the scip descriptor kinds correct?
141-
switch (symRef.kind()) {
142-
case core::SymbolRef::Kind::Method:
143-
// NOTE: There is a separate isOverloaded field in the flags field,
144-
// despite SO/docs saying that Ruby doesn't support method overloading,
145-
// Technically, we should better understand how this works and set the
146-
// disambiguator based on that. However, right now, an extension's
147-
// type-checking function is not run if a method is overloaded,
148-
// (see pipeline.cc), so it's unclear if we need to care about that.
149-
descriptor.set_suffix(scip::Descriptor::Method);
150-
break;
151-
case core::SymbolRef::Kind::ClassOrModule:
152-
descriptor.set_suffix(scip::Descriptor::Type);
153-
break;
154-
case core::SymbolRef::Kind::TypeArgument:
155-
descriptor.set_suffix(scip::Descriptor::TypeParameter);
156-
break;
157-
case core::SymbolRef::Kind::FieldOrStaticField:
158-
descriptor.set_suffix(scip::Descriptor::Term);
159-
break;
160-
case core::SymbolRef::Kind::TypeMember: // TODO: What does TypeMember mean?
161-
descriptor.set_suffix(scip::Descriptor::Type);
162-
break;
163-
default:
164-
return absl::InvalidArgumentError("unexpected expr type for symbol computation");
137+
InlinedVector<scip::Descriptor, 4> descriptors;
138+
auto cur = symRef;
139+
while (cur != core::Symbols::root()) {
140+
// NOTE:(varun) The current scheme will cause multiple 'definitions' for the same
141+
// entity if it is present in different files, because the path is not encoded
142+
// in the descriptor whose parent is the root. This matches the semantics of
143+
// RubyMine, but we may want to revisit this if it is problematic for classes
144+
// that are extended in lots of places.
145+
scip::Descriptor descriptor;
146+
*descriptor.mutable_name() = cur.name(gs).show(gs);
147+
// TODO: Are the scip descriptor kinds correct?
148+
switch (cur.kind()) {
149+
case core::SymbolRef::Kind::Method:
150+
// NOTE: There is a separate isOverloaded field in the flags field,
151+
// despite SO/docs saying that Ruby doesn't support method overloading,
152+
// Technically, we should better understand how this works and set the
153+
// disambiguator based on that. However, right now, an extension's
154+
// type-checking function is not run if a method is overloaded,
155+
// (see pipeline.cc), so it's unclear if we need to care about that.
156+
descriptor.set_suffix(scip::Descriptor::Method);
157+
break;
158+
case core::SymbolRef::Kind::ClassOrModule:
159+
descriptor.set_suffix(scip::Descriptor::Type);
160+
break;
161+
case core::SymbolRef::Kind::TypeArgument:
162+
descriptor.set_suffix(scip::Descriptor::TypeParameter);
163+
break;
164+
case core::SymbolRef::Kind::FieldOrStaticField:
165+
descriptor.set_suffix(scip::Descriptor::Term);
166+
break;
167+
case core::SymbolRef::Kind::TypeMember: // TODO: What does TypeMember mean?
168+
descriptor.set_suffix(scip::Descriptor::Type);
169+
break;
170+
default:
171+
return absl::InvalidArgumentError("unexpected expr type for symbol computation");
172+
}
173+
descriptors.push_back(move(descriptor));
174+
cur = cur.owner(gs);
175+
}
176+
while (!descriptors.empty()) {
177+
*symbol.add_descriptors() = move(descriptors.back());
178+
descriptors.pop_back();
165179
}
166-
*symbol.add_descriptors() = move(descriptor);
167180
return absl::OkStatus();
168181
}
169182

scip_indexer/SCIPUtils.cc

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,16 @@ absl::Status emitSymbolString(const scip::Symbol &symbol, string &out) {
5454
} else {
5555
out.append(". . ");
5656
}
57-
if (symbol.descriptors_size() == 1) {
58-
return emitDescriptorString(symbol.descriptors()[0], out);
57+
if (symbol.descriptors_size() == 0) {
58+
return absl::InvalidArgumentError("expected symbol to have at least 1 descriptor");
5959
}
60-
// FIXME(varun): Are we going to emit multiple descriptors per symbol?
61-
return absl::InvalidArgumentError(
62-
absl::StrCat("expected symbol to have 1 descriptor but found %d", symbol.descriptors_size()));
60+
for (auto i = 0; i < symbol.descriptors_size(); ++i) {
61+
auto status = emitDescriptorString(symbol.descriptors()[i], out);
62+
if (!status.ok()) {
63+
return status;
64+
}
65+
}
66+
return absl::OkStatus();
6367
}
6468

6569
}; // end namespace scip::utils

test/scip/testdata/args.snapshot.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# typed: true
22

33
def args(x, y)
4-
#^^^^^^^^^^^^^^ definition scip-ruby gem TODO TODO args().
4+
#^^^^^^^^^^^^^^ definition scip-ruby gem TODO TODO Object#args().
55
# ^ definition local 1~#2634721084
66
# ^ definition local 2~#2634721084
77
z = x + y

test/scip/testdata/arrays.snapshot.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# typed: true
22

33
def arrays(a, i)
4-
#^^^^^^^^^^^^^^^^ definition scip-ruby gem TODO TODO arrays().
4+
#^^^^^^^^^^^^^^^^ definition scip-ruby gem TODO TODO Object#arrays().
55
# ^ definition local 1~#513334479
66
# ^ definition local 2~#513334479
77
a[0] = 0

test/scip/testdata/classes.snapshot.rb

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,39 +6,39 @@
66
class C1
77
# ^^ definition scip-ruby gem TODO TODO C1#
88
def f()
9-
# ^^^^^^^ definition scip-ruby gem TODO TODO f().
9+
# ^^^^^^^ definition scip-ruby gem TODO TODO C1#f().
1010
_a = C1.new
1111
# ^^ definition local 2~#3809224601
1212
# ^^ reference scip-ruby gem TODO TODO C1#
1313
_b = M2::C2.new
1414
# ^^ definition local 5~#3809224601
1515
# ^^ reference scip-ruby gem TODO TODO M2#
16-
# ^^ reference scip-ruby gem TODO TODO C2#
16+
# ^^ reference scip-ruby gem TODO TODO M2#C2#
1717
return
1818
end
1919
end
2020

2121
module M2
2222
# ^^ definition scip-ruby gem TODO TODO M2#
2323
class C2
24-
# ^^ definition scip-ruby gem TODO TODO C2#
24+
# ^^ definition scip-ruby gem TODO TODO M2#C2#
2525
end
2626
end
2727

2828
class M3::C3
2929
# ^^ definition scip-ruby gem TODO TODO M3#
30-
# ^^ definition scip-ruby gem TODO TODO C3#
30+
# ^^ definition scip-ruby gem TODO TODO M3#C3#
3131
end
3232

3333
def local_class()
34-
#^^^^^^^^^^^^^^^^^ definition scip-ruby gem TODO TODO local_class().
34+
#^^^^^^^^^^^^^^^^^ definition scip-ruby gem TODO TODO Object#local_class().
3535
localClass = Class.new
3636
# ^^^^^^^^^^ definition local 2~#552113551
3737
# ^^^^^ reference scip-ruby gem TODO TODO Class#
3838
# Technically, this is not supported by Sorbet (https://srb.help/3001),
3939
# but make sure we don't crash or do something weird.
4040
def localClass.myMethod()
41-
# ^^^^^^^^^^^^^^^^^^^^^^^^^ definition scip-ruby gem TODO TODO myMethod().
41+
# ^^^^^^^^^^^^^^^^^^^^^^^^^ definition scip-ruby gem TODO TODO Object#myMethod().
4242
":)"
4343
end
4444
_c = localClass.new
@@ -47,7 +47,7 @@ def localClass.myMethod()
4747
_m = localClass.myMethod
4848
# ^^ definition local 4~#552113551
4949
# ^^^^^^^^^^ reference local 2~#552113551
50-
# ^^^^^^^^ reference scip-ruby gem TODO TODO myMethod().
50+
# ^^^^^^^^ reference scip-ruby gem TODO TODO Object#myMethod().
5151
return
5252
end
5353

@@ -59,45 +59,45 @@ module M4
5959
end
6060

6161
def module_access()
62-
#^^^^^^^^^^^^^^^^^^^ definition scip-ruby gem TODO TODO module_access().
62+
#^^^^^^^^^^^^^^^^^^^ definition scip-ruby gem TODO TODO Object#module_access().
6363
_ = M4::K
6464
# ^ definition local 2~#3353511840
6565
# ^^ reference scip-ruby gem TODO TODO M4#
66-
# ^ reference scip-ruby gem TODO TODO K.
66+
# ^ reference scip-ruby gem TODO TODO M4#K.
6767
return
6868
end
6969

7070
module M5
7171
# ^^ definition scip-ruby gem TODO TODO M5#
7272
module M6
73-
# ^^ definition scip-ruby gem TODO TODO M6#
73+
# ^^ definition scip-ruby gem TODO TODO M5#M6#
7474
def self.g()
75-
# ^^^^^^^^^^^^ definition scip-ruby gem TODO TODO g().
75+
# ^^^^^^^^^^^^ definition scip-ruby gem TODO TODO M5#<Class:M6>#g().
7676
end
7777
end
7878

7979
def self.h()
80-
# ^^^^^^^^^^^^ definition scip-ruby gem TODO TODO h().
80+
# ^^^^^^^^^^^^ definition scip-ruby gem TODO TODO <Class:M5>#h().
8181
M6.g()
82-
# ^^ reference scip-ruby gem TODO TODO M6#
82+
# ^^ reference scip-ruby gem TODO TODO M5#M6#
8383
return
8484
end
8585
end
8686

8787
class C7
8888
# ^^ definition scip-ruby gem TODO TODO C7#
8989
module M8
90-
# ^^ definition scip-ruby gem TODO TODO M8#
90+
# ^^ definition scip-ruby gem TODO TODO C7#M8#
9191
def self.i()
92-
# ^^^^^^^^^^^^ definition scip-ruby gem TODO TODO i().
92+
# ^^^^^^^^^^^^ definition scip-ruby gem TODO TODO C7#<Class:M8>#i().
9393
end
9494
end
9595

9696
def j()
97-
# ^^^^^^^ definition scip-ruby gem TODO TODO j().
97+
# ^^^^^^^ definition scip-ruby gem TODO TODO C7#j().
9898
M8.j()
99-
# ^^ reference scip-ruby gem TODO TODO M8#
100-
# ^ reference scip-ruby gem TODO TODO j().
99+
# ^^ reference scip-ruby gem TODO TODO C7#M8#
100+
# ^ reference scip-ruby gem TODO TODO C7#j().
101101
return
102102
end
103103
end

test/scip/testdata/for.snapshot.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# typed: true
22

33
def for_loop()
4-
#^^^^^^^^^^^^^^ definition scip-ruby gem TODO TODO for_loop().
4+
#^^^^^^^^^^^^^^ definition scip-ruby gem TODO TODO Object#for_loop().
55
y = 0
66
# ^ definition local 1~#1120785331
77
for x in [1, 2, 3]
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
# typed: true
22

33
def globalFn1()
4-
#^^^^^^^^^^^^^^^ definition scip-ruby gem TODO TODO globalFn1().
4+
#^^^^^^^^^^^^^^^ definition scip-ruby gem TODO TODO Object#globalFn1().
55
x = 10
66
# ^ definition local 1~#3846536873
77
x
88
# ^ reference local 1~#3846536873
99
end
1010

1111
def globalFn2()
12-
#^^^^^^^^^^^^^^^ definition scip-ruby gem TODO TODO globalFn2().
12+
#^^^^^^^^^^^^^^^ definition scip-ruby gem TODO TODO Object#globalFn2().
1313
x = globalFn1()
1414
# ^ definition local 1~#3796204016
1515
# ^^^^^^^^^^^^^^^ reference local 1~#3796204016
16-
# ^^^^^^^^^ reference scip-ruby gem TODO TODO globalFn1().
16+
# ^^^^^^^^^ reference scip-ruby gem TODO TODO Object#globalFn1().
1717
end
1818

test/scip/testdata/hashes.snapshot.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# typed: true
22

33
def hashes(h, k)
4-
#^^^^^^^^^^^^^^^^ definition scip-ruby gem TODO TODO hashes().
4+
#^^^^^^^^^^^^^^^^ definition scip-ruby gem TODO TODO Object#hashes().
55
# ^ definition local 1~#1685166589
66
# ^ definition local 2~#1685166589
77
h["hello"] = "world"

test/scip/testdata/loops_and_conditionals.snapshot.rb

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# typed: true
22

33
def if_elsif_else()
4-
#^^^^^^^^^^^^^^^^^^^ definition scip-ruby gem TODO TODO if_elsif_else().
4+
#^^^^^^^^^^^^^^^^^^^ definition scip-ruby gem TODO TODO Object#if_elsif_else().
55
x = 0
66
# ^ definition local 1~#2393773952
77
y = 0
@@ -43,7 +43,7 @@ def if_elsif_else()
4343
end
4444

4545
def unless()
46-
#^^^^^^^^^^^^ definition scip-ruby gem TODO TODO unless().
46+
#^^^^^^^^^^^^ definition scip-ruby gem TODO TODO Object#unless().
4747
z = 0
4848
# ^ definition local 1~#2827997891
4949
x = 1
@@ -66,7 +66,7 @@ def unless()
6666
end
6767

6868
def case(x, y)
69-
#^^^^^^^^^^^^^^ definition scip-ruby gem TODO TODO case().
69+
#^^^^^^^^^^^^^^ definition scip-ruby gem TODO TODO Object#case().
7070
# ^ definition local 1~#2602907825
7171
# ^ definition local 2~#2602907825
7272
case x
@@ -91,7 +91,7 @@ def case(x, y)
9191
end
9292

9393
def for(xs)
94-
#^^^^^^^^^^^ definition scip-ruby gem TODO TODO for().
94+
#^^^^^^^^^^^ definition scip-ruby gem TODO TODO Object#for().
9595
# ^^ definition local 1~#2901640080
9696
for e in xs
9797
# ^ definition local 2~#2901640080
@@ -124,7 +124,7 @@ def for(xs)
124124
end
125125

126126
def while(xs)
127-
#^^^^^^^^^^^^^ definition scip-ruby gem TODO TODO while().
127+
#^^^^^^^^^^^^^ definition scip-ruby gem TODO TODO Object#while().
128128
# ^^ definition local 1~#231090382
129129
i = 0
130130
# ^ definition local 2~#231090382
@@ -161,7 +161,7 @@ def while(xs)
161161
end
162162

163163
def until(xs)
164-
#^^^^^^^^^^^^^ definition scip-ruby gem TODO TODO until().
164+
#^^^^^^^^^^^^^ definition scip-ruby gem TODO TODO Object#until().
165165
# ^^ definition local 1~#3132432719
166166
i = 0
167167
# ^ definition local 2~#3132432719
@@ -198,7 +198,7 @@ def until(xs)
198198
end
199199

200200
def flip_flop(xs)
201-
#^^^^^^^^^^^^^^^^^ definition scip-ruby gem TODO TODO flip_flop().
201+
#^^^^^^^^^^^^^^^^^ definition scip-ruby gem TODO TODO Object#flip_flop().
202202
# ^^ definition local 1~#2191960030
203203
# NOTE: flip-flops are unsupported (https://srb.help/3003)
204204
# Unlike redo, which somehow works, we fail to emit references

0 commit comments

Comments
 (0)