-
Notifications
You must be signed in to change notification settings - Fork 3
feat: Infer gem info from standard filesystem layout. #155
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -187,6 +187,31 @@ GemMapping::GemMapping() | |
: currentGem(), map(), stdlibGem(make_shared<GemMetadata>(GemMetadata::tryParse("ruby@latest").value())), | ||
globalPlaceholderGem(make_shared<GemMetadata>(GemMetadata::tryParse("_global_@latest").value())) {} | ||
|
||
optional<shared_ptr<GemMetadata>> tryParseFilepath(std::string_view filepath) { | ||
auto filenameStartIndex = filepath.find_last_of('/') + 1; | ||
// E.g. foo/bar, | ||
// 0123456 ; startIndex = 4, size = 7 | ||
auto filename = filepath.substr(filenameStartIndex, filepath.size() - filenameStartIndex); | ||
auto dotIndex = filename.find_last_of('.'); | ||
if (dotIndex == std::string::npos) { | ||
// Should have .rbi files here | ||
return nullopt; | ||
} | ||
auto basename = filename.substr(0, dotIndex); | ||
if (absl::StrContains(basename, '@')) { | ||
auto metadata = GemMetadata::tryParse(basename); | ||
ENFORCE(metadata.has_value()); | ||
return make_shared<GemMetadata>(metadata.value()); | ||
} | ||
// TODO: Can we do better here by getting dependency versions from somewhere | ||
// else, like Gemfile.lock? In practice, it looks like files under gems/ have associated | ||
// versions, whereas files under annotations/ and gems/ do not have versions. | ||
// Another potential option is to do two passes over the list of files; first collecting | ||
// all external gem names+versions based on sorbet/rbi/gems, and then checking | ||
// if the name here matches any known external gem name. | ||
return make_shared<GemMetadata>(GemMetadata::forTest(string(basename), "latest")); | ||
} | ||
|
||
optional<shared_ptr<GemMetadata>> GemMapping::lookupGemForFile(const core::GlobalState &gs, core::FileRef file) const { | ||
ENFORCE(file.exists()); | ||
auto it = this->map.find(file); | ||
|
@@ -197,6 +222,19 @@ optional<shared_ptr<GemMetadata>> GemMapping::lookupGemForFile(const core::Globa | |
if (absl::StartsWith(filepath, core::File::URL_PREFIX)) { | ||
return this->stdlibGem; | ||
} | ||
// See https://sorbet.org/docs/rbi#quickref for description of the standard layout. | ||
// Based on some Sourcegraph searches, it looks like RBI files can be named either | ||
// gem_name.rbi or [email protected]. | ||
if (absl::StrContains(filepath, "sorbet/rbi/")) { | ||
if (absl::StrContains(filepath, "sorbet/rbi/gems/") || absl::StrContains(filepath, "sorbet/rbi/annotations/") || | ||
absl::StrContains(filepath, "sorbet/rbi/dsl/")) { | ||
auto metadata = tryParseFilepath(filepath); | ||
if (metadata.has_value()) { | ||
return metadata; | ||
} | ||
} | ||
// hidden-definitions and todo.rbi get treated as part of the current gem | ||
} | ||
if (this->currentGem.has_value()) { | ||
// TODO Should we enforce here in debug builds? | ||
// Fallback to this if set, to avoid collisions with other gems. | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# typed: true | ||
|
||
module CurrentGem | ||
def gem_fun | ||
puts 'Hello World' | ||
end | ||
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# typed: true | ||
|
||
module CurrentGem | ||
def gem_fun; end | ||
end |
9 changes: 9 additions & 0 deletions
9
test/scip/testdata/multifile/infer-gem-map/current_gem.snapshot.rb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# typed: true | ||
|
||
module CurrentGem | ||
# ^^^^^^^^^^ definition currentgem 77 CurrentGem# | ||
def gem_fun | ||
# ^^^^^^^ definition currentgem 77 CurrentGem#gem_fun(). | ||
puts 'Hello World' | ||
end | ||
end |
7 changes: 7 additions & 0 deletions
7
test/scip/testdata/multifile/infer-gem-map/current_gem.snapshot.rbi
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# typed: true | ||
|
||
module CurrentGem | ||
# ^^^^^^^^^^ definition currentgem 77 CurrentGem# | ||
def gem_fun; end | ||
# ^^^^^^^ definition currentgem 77 CurrentGem#gem_fun(). | ||
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# gem-metadata: currentgem@77 |
5 changes: 5 additions & 0 deletions
5
test/scip/testdata/multifile/infer-gem-map/sorbet/rbi/annotations/annotgem.rbi
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# typed: true | ||
|
||
module AnnotGem | ||
def annot_fun; end | ||
end |
7 changes: 7 additions & 0 deletions
7
test/scip/testdata/multifile/infer-gem-map/sorbet/rbi/annotations/annotgem.snapshot.rbi
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# typed: true | ||
|
||
module AnnotGem | ||
# ^^^^^^^^ definition annotgem latest AnnotGem# | ||
def annot_fun; end | ||
# ^^^^^^^^^ definition annotgem latest AnnotGem#annot_fun(). | ||
end |
5 changes: 5 additions & 0 deletions
5
test/scip/testdata/multifile/infer-gem-map/sorbet/rbi/dsl/railsgem.rbi
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# typed: true | ||
|
||
module DSLGem | ||
def create; end | ||
end |
7 changes: 7 additions & 0 deletions
7
test/scip/testdata/multifile/infer-gem-map/sorbet/rbi/dsl/railsgem.snapshot.rbi
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# typed: true | ||
|
||
module DSLGem | ||
# ^^^^^^ definition railsgem latest DSLGem# | ||
def create; end | ||
# ^^^^^^ definition railsgem latest DSLGem#create(). | ||
end |
5 changes: 5 additions & 0 deletions
5
test/scip/testdata/multifile/infer-gem-map/sorbet/rbi/gems/[email protected]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# typed: true | ||
|
||
module ExternalGem | ||
def ext_fun; end | ||
end |
7 changes: 7 additions & 0 deletions
7
test/scip/testdata/multifile/infer-gem-map/sorbet/rbi/gems/[email protected]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# typed: true | ||
|
||
module ExternalGem | ||
# ^^^^^^^^^^^ definition extgem 99 ExternalGem# | ||
def ext_fun; end | ||
# ^^^^^^^ definition extgem 99 ExternalGem#ext_fun(). | ||
end |
5 changes: 5 additions & 0 deletions
5
test/scip/testdata/multifile/infer-gem-map/sorbet/rbi/hidden-definitions/hidden.rbi
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# typed: true | ||
|
||
module Hidden | ||
def hidden_fun; end | ||
end |
7 changes: 7 additions & 0 deletions
7
test/scip/testdata/multifile/infer-gem-map/sorbet/rbi/hidden-definitions/hidden.snapshot.rbi
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# typed: true | ||
|
||
module Hidden | ||
# ^^^^^^ definition currentgem 77 Hidden# | ||
def hidden_fun; end | ||
# ^^^^^^^^^^ definition currentgem 77 Hidden#hidden_fun(). | ||
end |
5 changes: 5 additions & 0 deletions
5
test/scip/testdata/multifile/infer-gem-map/sorbet/rbi/todo.rbi
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# typed: true | ||
|
||
module TODO | ||
TODO_CONSTANT = 1 | ||
end |
8 changes: 8 additions & 0 deletions
8
test/scip/testdata/multifile/infer-gem-map/sorbet/rbi/todo.snapshot.rbi
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# typed: true | ||
|
||
module TODO | ||
# ^^^^ definition currentgem 77 TODO# | ||
TODO_CONSTANT = 1 | ||
# ^^^^^^^^^^^^^ definition currentgem 77 TODO#TODO_CONSTANT. | ||
# ^^^^^^^^^^^^^^^^^ reference currentgem 77 TODO#TODO_CONSTANT. | ||
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -176,6 +176,51 @@ TEST_CASE("GemMapParsing") { | |
ENFORCE(gemMap.lookupGemForFile(gs, unnormalized2).has_value()); | ||
} | ||
|
||
// This test might feel a little redundant since we also have a similar integration test. | ||
// However, the integration test is making sure that the emitted index has the right | ||
// gem info, which is not checked by this test. | ||
TEST_CASE("GemInference") { | ||
if (!onlyRunUnitTests) { | ||
return; | ||
} | ||
vector<unique_ptr<core::Error>> errors; | ||
|
||
auto logger = spdlog::stderr_color_mt("gem-inference-test"); | ||
auto errorCollector = make_shared<core::ErrorCollector>(); | ||
auto errorQueue = make_shared<core::ErrorQueue>(*logger, *logger, errorCollector); | ||
core::GlobalState gs(errorQueue); | ||
gs.initEmpty(); // needed for proper file table access | ||
|
||
core::FileRef externalGemRBI, annotationsRBI, dslRBI, todoRBI, hiddenDefsRBI, notSorbetRBI; | ||
{ | ||
core::UnfreezeFileTable fileTableAccess(gs); | ||
externalGemRBI = gs.enterFile("./sorbet/rbi/gems/[email protected]", ""); | ||
annotationsRBI = gs.enterFile("./sorbet/rbi/annotations/myannot.rbi", ""); | ||
dslRBI = gs.enterFile("sorbet/rbi/dsl/myrails.rbi", ""); | ||
todoRBI = gs.enterFile("./sorbet/rbi/todo.rbi", ""); | ||
hiddenDefsRBI = gs.enterFile("./sorbet/rbi/hidden-definitions/hidden.rbi", ""); | ||
notSorbetRBI = gs.enterFile("myproject/x.rbi", ""); | ||
} | ||
|
||
scip_indexer::GemMapping gemMap{}; | ||
gemMap.markCurrentGem(scip_indexer::GemMetadata::forTest("mygem", "33")); | ||
|
||
auto checkGem = [&](core::FileRef file, string name, string version) { | ||
auto gem = gemMap.lookupGemForFile(gs, file); | ||
ENFORCE(gem.has_value()); | ||
ENFORCE(*gem->get() == scip_indexer::GemMetadata::forTest(name, version), | ||
"\nexpected: name {}, version {}\nobtained: name {}, version {}", name, version, gem->get()->name(), | ||
gem->get()->version()); | ||
}; | ||
|
||
checkGem(externalGemRBI, "extgem", "0"); | ||
checkGem(annotationsRBI, "myannot", "latest"); | ||
checkGem(dslRBI, "myrails", "latest"); | ||
checkGem(todoRBI, "mygem", "33"); | ||
checkGem(hiddenDefsRBI, "mygem", "33"); | ||
checkGem(notSorbetRBI, "mygem", "33"); | ||
} | ||
|
||
// Copied from pipeline_test_runner.cc | ||
class CFGCollectorAndTyper { // TODO(varun): Copy this over to scip_test_runner.cc | ||
public: | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.