Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions proto/SCIP.proto
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,14 @@ message Occurrence {
SyntaxKind syntax_kind = 5;
// (optional) Diagnostics that have been reported for this specific range.
repeated Diagnostic diagnostics = 6;
// (optional) Using the same encoding as the sibling `range` field, half-open
// source range of the nearest non-trivial enclosing AST node. This range must
// enclose the `range` field.
//
// For definition occurrences, the enclosing range should indicate the
// start/end bounds of the entire definition AST node, including
// documentation.
repeated int32 enclosing_range = 7;
}

// Represents a diagnostic, such as a compiler error or warning, which should be
Expand Down
25 changes: 18 additions & 7 deletions scip_indexer/SCIPIndexer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,8 @@ class SCIPState {

absl::Status saveDefinitionImpl(const core::GlobalState &gs, core::FileRef file, const string &symbolString,
core::Loc occLoc, const SmallVec<string> &docs,
const SmallVec<scip::Relationship> &rels) {
const SmallVec<scip::Relationship> &rels,
optional<core::Loc> enclosingLoc = nullopt) {
ENFORCE(!symbolString.empty());
occLoc = trimColonColonPrefix(gs, occLoc);
auto range = sorbet::scip_indexer::fromSorbetLoc(gs, occLoc);
Expand All @@ -305,6 +306,12 @@ class SCIPState {
for (auto val : range) {
occurrence.add_range(val);
}
if (enclosingLoc.has_value() && !enclosingLoc->empty()) {
auto encRange = sorbet::scip_indexer::fromSorbetLoc(gs, enclosingLoc.value());
for (auto val : encRange) {
occurrence.add_enclosing_range(val);
}
}
switch (emitted) {
case Emitted::Now:
break;
Expand Down Expand Up @@ -396,7 +403,8 @@ class SCIPState {
}

public:
absl::Status saveDefinition(const core::GlobalState &gs, core::FileRef file, OwnedLocal occ, core::TypePtr type) {
absl::Status saveDefinition(const core::GlobalState &gs, core::FileRef file, OwnedLocal occ, core::TypePtr type,
optional<core::Loc> enclosingLoc = nullopt) {
if (this->cacheOccurrence(gs, file, occ, scip::SymbolRole::Definition)) {
return absl::OkStatus();
}
Expand All @@ -407,7 +415,7 @@ class SCIPState {
ENFORCE(var.has_value(), "Failed to find source text for definition of local variable");
docStrings.push_back(fmt::format("```ruby\n{} ({})\n```", var.value(), type.show(gs)));
}
return this->saveDefinitionImpl(gs, file, occ.toSCIPString(gs, file), loc, docStrings, {});
return this->saveDefinitionImpl(gs, file, occ.toSCIPString(gs, file), loc, docStrings, {}, enclosingLoc);
}

void saveAliasRelationship(const core::GlobalState &gs, UntypedGenericSymbolRef aliasedSymbol,
Expand All @@ -423,7 +431,8 @@ class SCIPState {
// TODO(varun): Should we always pass in the location instead of sometimes only?
absl::Status saveDefinition(const core::GlobalState &gs, core::FileRef file, GenericSymbolRef symRef,
optional<UntypedGenericSymbolRef> aliasedSymbol,
optional<core::LocOffsets> loc = nullopt) {
optional<core::LocOffsets> loc = nullopt,
optional<core::Loc> enclosingLoc = nullopt) {
// In practice, there doesn't seem to be any situation which triggers
// a duplicate definition being emitted, so skip calling cacheOccurrence here.
auto occLoc = loc.has_value() ? core::Loc(file, loc.value()) : symRef.symbolLoc(gs);
Expand Down Expand Up @@ -452,7 +461,7 @@ class SCIPState {
this->saveAliasRelationship(gs, aliasedSymbol.value(), rels);
}

return this->saveDefinitionImpl(gs, file, symbolString, occLoc, docs, rels);
return this->saveDefinitionImpl(gs, file, symbolString, occLoc, docs, rels, enclosingLoc);
}

absl::Status saveReference(const core::GlobalState &gs, core::FileRef file, OwnedLocal occ,
Expand Down Expand Up @@ -1491,7 +1500,8 @@ class SCIPSemanticExtension : public SemanticExtension {

auto scipState = this->getSCIPState();
auto sym = scip_indexer::GenericSymbolRef::classOrModule(klass.symbol);
auto status = scipState->saveDefinition(gs, file, sym, /*aliasedSymbol*/ nullopt, nameLoc);
auto klassLoc = core::Loc(file, klass.loc);
auto status = scipState->saveDefinition(gs, file, sym, /*aliasedSymbol*/ nullopt, nameLoc, klassLoc);
ENFORCE(status.ok());
auto *expr = &klass.name;
if (auto *constantLit = ast::cast_tree<ast::ConstantLit>(*expr)) {
Expand All @@ -1513,9 +1523,10 @@ class SCIPSemanticExtension : public SemanticExtension {
return;
}
auto scipState = this->getSCIPState();
auto methodLoc = core::Loc(file, methodDef.loc);
if (methodDef.name != core::Names::staticInit()) {
auto sym = scip_indexer::GenericSymbolRef::method(methodDef.symbol);
auto status = scipState->saveDefinition(gs, file, sym, /*aliasedSymbol*/ nullopt);
auto status = scipState->saveDefinition(gs, file, sym, /*aliasedSymbol*/ nullopt, /*loc*/ nullopt, methodLoc);
ENFORCE(status.ok());
}

Expand Down
28 changes: 28 additions & 0 deletions test/scip/testdata/abstract_interface.snapshot.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

# Exercises abstract!, interface!, final!, sealed!, mixes_in_class_methods.

#⌄ enclosing_range_start [..] Drawable#
module Drawable
# ^^^^^^^^ definition [..] Drawable#
extend T::Sig
Expand All @@ -12,10 +13,14 @@ module Drawable

sig { abstract.returns(String) }
# ^^^^^^ reference [..] String#
# ⌄ enclosing_range_start [..] Drawable#draw().
def draw; end
# ^^^^ definition [..] Drawable#draw().
# ⌃ enclosing_range_end [..] Drawable#draw().
end
# ⌃ enclosing_range_end [..] Drawable#

#⌄ enclosing_range_start [..] Shape#
class Shape
# ^^^^^ definition [..] Shape#
extend T::Sig
Expand All @@ -26,10 +31,14 @@ class Shape

sig { abstract.returns(Integer) }
# ^^^^^^^ reference [..] Integer#
# ⌄ enclosing_range_start [..] Shape#area().
def area; end
# ^^^^ definition [..] Shape#area().
# ⌃ enclosing_range_end [..] Shape#area().
end
# ⌃ enclosing_range_end [..] Shape#

#⌄ enclosing_range_start [..] Square#
class Square < Shape
# ^^^^^^ definition [..] Square#
# ^^^^^ reference [..] Shape#
Expand All @@ -42,19 +51,25 @@ class Square < Shape

sig { override.returns(Integer) }
# ^^^^^^^ reference [..] Integer#
# ⌄ enclosing_range_start [..] Square#area().
def area
# ^^^^ definition [..] Square#area().
16
end
# ⌃ enclosing_range_end [..] Square#area().

sig { override.returns(String) }
# ^^^^^^ reference [..] String#
# ⌄ enclosing_range_start [..] Square#draw().
def draw
# ^^^^ definition [..] Square#draw().
"square"
end
# ⌃ enclosing_range_end [..] Square#draw().
end
# ⌃ enclosing_range_end [..] Square#

#⌄ enclosing_range_start [..] FinalLeaf#
class FinalLeaf
# ^^^^^^^^^ definition [..] FinalLeaf#
extend T::Sig
Expand All @@ -65,44 +80,57 @@ class FinalLeaf

sig(:final) { returns(Integer) }
# ^^^^^^^ reference [..] Integer#
# ⌄ enclosing_range_start [..] FinalLeaf#value().
def value
# ^^^^^ definition [..] FinalLeaf#value().
42
end
# ⌃ enclosing_range_end [..] FinalLeaf#value().
end
# ⌃ enclosing_range_end [..] FinalLeaf#

#⌄ enclosing_range_start [..] SealedHierarchy#
module SealedHierarchy
# ^^^^^^^^^^^^^^^ definition [..] SealedHierarchy#
extend T::Helpers
# ^^^^^^ reference [..] Kernel#extend().
sealed!
end
# ⌃ enclosing_range_end [..] SealedHierarchy#

#⌄ enclosing_range_start [..] ClassMethodsMixin#
module ClassMethodsMixin
# ^^^^^^^^^^^^^^^^^ definition [..] ClassMethodsMixin#
extend T::Sig
# ^^^^^^ reference [..] Kernel#extend().

sig { returns(String) }
# ^^^^^^ reference [..] String#
# ⌄ enclosing_range_start [..] ClassMethodsMixin#class_helper().
def class_helper
# ^^^^^^^^^^^^ definition [..] ClassMethodsMixin#class_helper().
"class!"
end
# ⌃ enclosing_range_end [..] ClassMethodsMixin#class_helper().
end
# ⌃ enclosing_range_end [..] ClassMethodsMixin#

#⌄ enclosing_range_start [..] InstanceMethodsMixin#
module InstanceMethodsMixin
# ^^^^^^^^^^^^^^^^^^^^ definition [..] InstanceMethodsMixin#
extend T::Helpers
# ^^^^^^ reference [..] Kernel#extend().
mixes_in_class_methods(ClassMethodsMixin)
# ^^^^^^^^^^^^^^^^^ reference [..] ClassMethodsMixin#
end
# ⌃ enclosing_range_end [..] InstanceMethodsMixin#

#⌄ enclosing_range_start [..] WithMixedIn#
class WithMixedIn
# ^^^^^^^^^^^ definition [..] WithMixedIn#
include InstanceMethodsMixin
# ^^^^^^^ reference [..] Module#include().
# ^^^^^^^^^^^^^^^^^^^^ reference [..] InstanceMethodsMixin#
# ^^^^^^^^^^^^^^^^^^^^ reference [..] InstanceMethodsMixin#
end
# ⌃ enclosing_range_end [..] WithMixedIn#
18 changes: 18 additions & 0 deletions test/scip/testdata/alias.snapshot.rb
Original file line number Diff line number Diff line change
@@ -1,32 +1,41 @@
# typed: true

#⌄ enclosing_range_start [..] X#
class X
# ^ definition [..] X#
alias_method :am_aaa, :aaa
# ^^^^^^^^^^^^ reference [..] Module#alias_method().
alias :a_aaa :aaa

# ⌄ enclosing_range_start [..] X#aaa().
def aaa
# ^^^ definition [..] X#aaa().
puts "AAA"
# ^^^^ reference [..] Kernel#puts().
end
# ⌃ enclosing_range_end [..] X#aaa().

# ⌄ enclosing_range_start [..] X#check_alias().
def check_alias
# ^^^^^^^^^^^ definition [..] X#check_alias().
return [am_aaa, a_aaa]
# ^^^^^^ reference [..] X#aaa().
# ^^^^^ reference [..] X#aaa().
end
# ⌃ enclosing_range_end [..] X#check_alias().
end
# ⌃ enclosing_range_end [..] X#

#⌄ enclosing_range_start [..] Mod1#
module Mod1
# ^^^^ definition [..] Mod1#
ABC = 10
# ^^^ definition [..] Mod1#ABC.
# ^^^^^^^^ reference [..] Mod1#ABC.
end
# ⌃ enclosing_range_end [..] Mod1#

#⌄ enclosing_range_start [..] Mod2#
module Mod2
# ^^^^ definition [..] Mod2#
FEG = Mod1::ABC
Expand All @@ -36,7 +45,9 @@ module Mod2
# ^^^ reference [..] Mod1#ABC.
# ^^^ reference [..] Mod2#FEG.
end
# ⌃ enclosing_range_end [..] Mod2#

#⌄ enclosing_range_start [..] Object#myfunction().
def myfunction(myparam)
# ^^^^^^^^^^ definition [..] Object#myfunction().
# ^^^^^^^ definition local 1$3083414419
Expand All @@ -45,7 +56,10 @@ def myfunction(myparam)
# ^^^^ reference [..] Mod2#
# ^^^ reference [..] Mod2#FEG.
end
# ⌃ enclosing_range_end [..] Object#myfunction().

#⌄ enclosing_range_start [..] X#
#⌄ enclosing_range_start [..] X#serialize().
class X < T::Enum
# ^ definition [..] X#
# ^ definition [..] X#serialize().
Expand Down Expand Up @@ -73,9 +87,12 @@ class X < T::Enum
# ^^^^^^^^ definition local 4$119448696
# ^ reference [..] X#
end
# ⌃ enclosing_range_end [..] X#
# ⌃ enclosing_range_end [..] X#serialize().

# Adding more cases like this is not supported (c.f. isTEnum),
# but let's at least add a test.
#⌄ enclosing_range_start [..] Y#
class Y < X
# ^ definition [..] Y#
# ^ reference [..] X#
Expand All @@ -90,3 +107,4 @@ class Y < X
# ^ reference [..] X#B.
end
end
# ⌃ enclosing_range_end [..] Y#
6 changes: 6 additions & 0 deletions test/scip/testdata/args.snapshot.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# typed: true

#⌄ enclosing_range_start [..] Object#args().
def args(x, y)
# ^^^^ definition [..] Object#args().
# ^ definition local 1$2634721084
Expand All @@ -24,7 +25,9 @@ def args(x, y)
z
# ^ reference local 3$2634721084
end
# ⌃ enclosing_range_end [..] Object#args().

#⌄ enclosing_range_start [..] Object#keyword_args().
def keyword_args(w:, x: 3, y: [], **kwargs)
# ^^^^^^^^^^^^ definition [..] Object#keyword_args().
# ^^ definition local 1$3526982640
Expand All @@ -38,7 +41,9 @@ def keyword_args(w:, x: 3, y: [], **kwargs)
# ^ reference local 3$3526982640
return
end
# ⌃ enclosing_range_end [..] Object#keyword_args().

#⌄ enclosing_range_start [..] Object#use_kwargs().
def use_kwargs
# ^^^^^^^^^^ definition [..] Object#use_kwargs().
h = { a: 3 }
Expand All @@ -51,3 +56,4 @@ def use_kwargs
# ^ reference local 1$571973038
return
end
# ⌃ enclosing_range_end [..] Object#use_kwargs().
2 changes: 2 additions & 0 deletions test/scip/testdata/arrays.snapshot.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# typed: true

#⌄ enclosing_range_start [..] Object#arrays().
def arrays(a, i)
# ^^^^^^ definition [..] Object#arrays().
# ^ definition local 1$513334479
Expand All @@ -21,3 +22,4 @@ def arrays(a, i)
# ^ reference local 1$513334479
# ^ reference local 1$513334479
end
# ⌃ enclosing_range_end [..] Object#arrays().
10 changes: 10 additions & 0 deletions test/scip/testdata/blocks_lambdas_procs.snapshot.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# typed: true

#⌄ enclosing_range_start [..] Object#blk().
def blk
# ^^^ definition [..] Object#blk().
y = 0
Expand All @@ -21,7 +22,9 @@ def blk
# ^ reference local 3$1472469056
end
end
# ⌃ enclosing_range_end [..] Object#blk().

#⌄ enclosing_range_start [..] Object#lam().
def lam
# ^^^ definition [..] Object#lam().
y = 0
Expand Down Expand Up @@ -81,7 +84,9 @@ def lam
# ^^ reference local 11$1499497673
# ^^^^ reference [..] Proc#call().
end
# ⌃ enclosing_range_end [..] Object#lam().

#⌄ enclosing_range_start [..] Object#prc().
def prc
# ^^^ definition [..] Object#prc().
y = 0
Expand Down Expand Up @@ -141,14 +146,18 @@ def prc
# ^^ reference local 11$1283111692
# ^^^^ reference [..] Proc#call().
end
# ⌃ enclosing_range_end [..] Object#prc().

#⌄ enclosing_range_start [..] Object#call_block().
def call_block(&blk)
# ^^^^^^^^^^ definition [..] Object#call_block().
# ^^^ definition local 1$1487178087
blk.call
# ^^^ reference local 1$1487178087
end
# ⌃ enclosing_range_end [..] Object#call_block().

#⌄ enclosing_range_start [..] Object#use_block_with_defaults().
def use_block_with_defaults
# ^^^^^^^^^^^^^^^^^^^^^^^ definition [..] Object#use_block_with_defaults().
call_block do |oops: nil|
Expand All @@ -161,3 +170,4 @@ def use_block_with_defaults
# ^^^^ definition local 2$4118119342
end
end
# ⌃ enclosing_range_end [..] Object#use_block_with_defaults().
Loading
Loading