rubydex 0.4.1 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +11 -0
- data/THIRD_PARTY_LICENSES.html +13 -24
- data/lib/rubydex/cli/command/dead_code.rb +59 -0
- data/lib/rubydex/mcp_server/tools/codebase_stats_tool.rb +1 -1
- data/lib/rubydex/mcp_server/tools/find_constant_references_tool.rb +4 -4
- data/lib/rubydex/mcp_server/tools/find_dead_code_candidates_tool.rb +33 -0
- data/lib/rubydex/mcp_server/tools/get_declaration_tool.rb +2 -2
- data/lib/rubydex/mcp_server/tools/get_descendants_tool.rb +4 -4
- data/lib/rubydex/mcp_server/tools/get_file_declarations_tool.rb +2 -2
- data/lib/rubydex/mcp_server/tools/search_declarations_tool.rb +6 -6
- data/lib/rubydex/mcp_server.rb +24 -12
- data/lib/rubydex/version.rb +1 -1
- data/rust/Cargo.lock +17 -11
- data/rust/Cargo.toml +3 -0
- data/rust/rubydex/Cargo.toml +2 -2
- data/rust/rubydex/src/compile_assertions.rs +2 -0
- data/rust/rubydex/src/config.rs +1 -1
- data/rust/rubydex/src/indexing/rbs_indexer.rs +4 -4
- data/rust/rubydex/src/indexing/ruby_indexer.rs +26 -18
- data/rust/rubydex/src/indexing/ruby_indexer_tests.rs +42 -2
- data/rust/rubydex/src/indexing.rs +6 -6
- data/rust/rubydex/src/listing.rs +12 -12
- data/rust/rubydex/src/model/built_in.rs +1 -1
- data/rust/rubydex/src/model/comment.rs +4 -4
- data/rust/rubydex/src/model/declaration.rs +25 -17
- data/rust/rubydex/src/model/document.rs +11 -11
- data/rust/rubydex/src/model/graph.rs +3 -3
- data/rust/rubydex/src/offset.rs +1 -13
- data/rust/rubydex/src/operation/ruby_builder.rs +29 -19
- data/rust/rubydex/src/query.rs +3 -2
- data/rust/rubydex/src/test_utils/graph_test.rs +2 -2
- data/rust/rubydex/src/test_utils/local_graph_test.rs +13 -6
- data/rust/rubydex-sys/Cargo.toml +2 -2
- data/rust/rubydex-sys/src/definition_api.rs +1 -1
- data/rust/rubydex-sys/src/graph_api.rs +96 -49
- data/rust/rubydex-sys/src/name_api.rs +193 -58
- metadata +191 -191
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 49871847c0ed628c67f7233f7e4fce8b99c33f68e53e60a19b1123059d8183ba
|
|
4
|
+
data.tar.gz: 5895341c914855ebe268a74fe3272acb2ba31fc432f8f182bfaa3eb1c4e77589
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: efa3cae2e8ffc1505a299e15ecc809500bf1037bb57ef14c7fcf74ae45a5d076eaa14507177538157635dedae869b312c82fbb8c57d3389763882587604c711b
|
|
7
|
+
data.tar.gz: 31a384a22b06224be09df0a24dda784da19b18804ba3db39bab77a9768fd4abe834ac5ec206e307ac1737cfdfd89f425187e80c81cf425da015cdf765fbb6b57
|
data/README.md
CHANGED
|
@@ -157,6 +157,16 @@ puts Rubydex::Query.schema("table")
|
|
|
157
157
|
|
|
158
158
|
See the [linter docs](docs/linter.md).
|
|
159
159
|
|
|
160
|
+
### Dead code candidates
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
bundle exec rdx dead_code
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Prints a list of potentially dead code candidates. The list is composed of all declarations for which the analysis found no references for in the codebase.
|
|
167
|
+
|
|
168
|
+
Since some declarations may be used through meta-programming or otherwise untyped code, there may be false positives and the removal of candidates must be done carefully with context about the codebase.
|
|
169
|
+
|
|
160
170
|
### MCP server
|
|
161
171
|
|
|
162
172
|
Rubydex can run as an MCP (Model Context Protocol) server, enabling AI assistants
|
|
@@ -198,6 +208,7 @@ like Claude to semantically query your Ruby codebase.
|
|
|
198
208
|
| `get_declaration` | Full details by fully qualified name with docs, ancestors, members |
|
|
199
209
|
| `get_descendants` | What classes/modules inherit from or include this one |
|
|
200
210
|
| `find_constant_references` | All precise, resolved constant references across the codebase |
|
|
211
|
+
| `find_dead_code_candidates` | List of potentially unused code |
|
|
201
212
|
| `get_file_declarations` | List declarations defined in a specific file |
|
|
202
213
|
| `codebase_stats` | High-level statistics about the indexed codebase |
|
|
203
214
|
|
data/THIRD_PARTY_LICENSES.html
CHANGED
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
|
|
51
51
|
<h2>Overview of licenses:</h2>
|
|
52
52
|
<ul class="licenses-overview">
|
|
53
|
-
<li><a href="#Apache-2.0">Apache License 2.0</a> (
|
|
53
|
+
<li><a href="#Apache-2.0">Apache License 2.0</a> (120)</li>
|
|
54
54
|
<li><a href="#Unicode-3.0">Unicode License v3</a> (19)</li>
|
|
55
55
|
<li><a href="#MIT">MIT License</a> (17)</li>
|
|
56
56
|
<li><a href="#BSD-2-Clause">BSD 2-Clause "Simplified" License</a> (2)</li>
|
|
@@ -2515,6 +2515,9 @@ limitations under the License.
|
|
|
2515
2515
|
<li><a
|
|
2516
2516
|
href=" https://github.com/comex/rust-shlex ">shlex
|
|
2517
2517
|
1.3.0</a></li>
|
|
2518
|
+
<li><a
|
|
2519
|
+
href=" https://github.com/comex/rust-shlex ">shlex
|
|
2520
|
+
2.0.1</a></li>
|
|
2518
2521
|
<li><a
|
|
2519
2522
|
href=" https://github.com/dtolnay/syn ">syn
|
|
2520
2523
|
2.0.104</a></li>
|
|
@@ -2670,7 +2673,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
2670
2673
|
<ul class="license-used-by">
|
|
2671
2674
|
<li><a
|
|
2672
2675
|
href=" https://github.com/DoumanAsh/xxhash-rust ">xxhash-rust
|
|
2673
|
-
0.8.
|
|
2676
|
+
0.8.16</a></li>
|
|
2674
2677
|
</ul>
|
|
2675
2678
|
<pre class="license-text">Boost Software License - Version 1.0 - August 17th, 2003
|
|
2676
2679
|
|
|
@@ -2821,26 +2824,6 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
|
2821
2824
|
|
|
2822
2825
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
2823
2826
|
|
|
2824
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
2825
|
-
</pre>
|
|
2826
|
-
</li>
|
|
2827
|
-
<li class="license">
|
|
2828
|
-
<h3 id="MIT">MIT License</h3>
|
|
2829
|
-
<h4>Used by:</h4>
|
|
2830
|
-
<ul class="license-used-by">
|
|
2831
|
-
<li><a
|
|
2832
|
-
href=" https://github.com/ruby/prism ">ruby-prism-sys
|
|
2833
|
-
1.9.0</a></li>
|
|
2834
|
-
<li><a
|
|
2835
|
-
href=" https://github.com/ruby/prism ">ruby-prism
|
|
2836
|
-
1.9.0</a></li>
|
|
2837
|
-
</ul>
|
|
2838
|
-
<pre class="license-text">Copyright 2022-present, Shopify Inc.
|
|
2839
|
-
|
|
2840
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
2841
|
-
|
|
2842
|
-
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
2843
|
-
|
|
2844
2827
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
2845
2828
|
</pre>
|
|
2846
2829
|
</li>
|
|
@@ -2881,13 +2864,19 @@ SOFTWARE.
|
|
|
2881
2864
|
<ul class="license-used-by">
|
|
2882
2865
|
<li><a
|
|
2883
2866
|
href=" https://github.com/Shopify/rubydex ">rubydex
|
|
2884
|
-
0.2
|
|
2867
|
+
0.4.2</a></li>
|
|
2885
2868
|
<li><a
|
|
2886
2869
|
href=" https://github.com/Shopify/rubydex ">rubydex-sys
|
|
2887
|
-
0.2
|
|
2870
|
+
0.4.2</a></li>
|
|
2888
2871
|
<li><a
|
|
2889
2872
|
href=" https://github.com/DimaKudosh/difflib ">difflib
|
|
2890
2873
|
0.4.0</a></li>
|
|
2874
|
+
<li><a
|
|
2875
|
+
href=" https://github.com/ruby/prism ">ruby-prism-sys
|
|
2876
|
+
2.0.0-rc.2</a></li>
|
|
2877
|
+
<li><a
|
|
2878
|
+
href=" https://github.com/ruby/prism ">ruby-prism
|
|
2879
|
+
2.0.0-rc.2</a></li>
|
|
2891
2880
|
</ul>
|
|
2892
2881
|
<pre class="license-text">MIT License
|
|
2893
2882
|
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rubydex/cli/command"
|
|
4
|
+
|
|
5
|
+
module Rubydex
|
|
6
|
+
module CLI
|
|
7
|
+
# `rdx dead_code` — lists dead code candidates in the current workspace.
|
|
8
|
+
class Command
|
|
9
|
+
class DeadCode < Command
|
|
10
|
+
command "dead_code"
|
|
11
|
+
summary "List dead code candidates in the current workspace"
|
|
12
|
+
|
|
13
|
+
#: -> void
|
|
14
|
+
def run
|
|
15
|
+
parse_options!
|
|
16
|
+
abort_with_usage("unexpected argument: #{argv.first}") unless argv.empty?
|
|
17
|
+
|
|
18
|
+
require "rubydex/linter/helpers/path_helpers"
|
|
19
|
+
|
|
20
|
+
$stderr.puts("Looking for potentially dead code...")
|
|
21
|
+
graph = build_graph($stderr, workspace_path: current_workspace_path)
|
|
22
|
+
candidates = graph.dead_code_candidates.sort_by(&:name)
|
|
23
|
+
|
|
24
|
+
candidates.each do |candidate|
|
|
25
|
+
puts(candidate.name)
|
|
26
|
+
candidate.definitions.map(&:location).sort.each do |location|
|
|
27
|
+
display = location.to_display
|
|
28
|
+
path = Rubydex::Linter::Helpers::PathHelpers.display_path(display, workspace: graph.workspace_path)
|
|
29
|
+
puts(" #{path}:#{display.start_line},#{display.start_column}-#{display.end_line},#{display.end_column}")
|
|
30
|
+
end
|
|
31
|
+
puts
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
print_summary(graph.documents.count, candidates.length)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
#: (Integer file_count, Integer candidate_count) -> void
|
|
40
|
+
def print_summary(file_count, candidate_count)
|
|
41
|
+
if candidate_count.zero?
|
|
42
|
+
puts("#{file_count} #{pluralize("file", file_count)} inspected, no dead code candidates found")
|
|
43
|
+
return
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
puts(
|
|
47
|
+
"#{file_count} #{pluralize("file", file_count)} inspected, " \
|
|
48
|
+
"#{candidate_count} dead code #{pluralize("candidate", candidate_count)} found",
|
|
49
|
+
)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
#: (String word, Integer count) -> String
|
|
53
|
+
def pluralize(word, count)
|
|
54
|
+
count == 1 ? word : "#{word}s"
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -4,7 +4,7 @@ module Rubydex
|
|
|
4
4
|
module MCPServer
|
|
5
5
|
class CodebaseStatsTool < BaseTool
|
|
6
6
|
tool_name "codebase_stats"
|
|
7
|
-
description "
|
|
7
|
+
description "Count indexed files, declarations, definitions, and references, with declarations grouped by kind."
|
|
8
8
|
input_schema(properties: {})
|
|
9
9
|
|
|
10
10
|
#: -> Tool::Response
|
|
@@ -4,12 +4,12 @@ module Rubydex
|
|
|
4
4
|
module MCPServer
|
|
5
5
|
class FindConstantReferencesTool < BaseTool
|
|
6
6
|
tool_name "find_constant_references"
|
|
7
|
-
description "
|
|
7
|
+
description "Locate resolved references to a Ruby class, module, or constant."
|
|
8
8
|
input_schema(
|
|
9
9
|
properties: {
|
|
10
|
-
name: { type: "string", description: "Fully qualified
|
|
11
|
-
limit: { type: "integer", description: "
|
|
12
|
-
offset: { type: "integer", description: "Number of
|
|
10
|
+
name: { type: "string", description: "Fully qualified class, module, or constant name" },
|
|
11
|
+
limit: { type: "integer", description: "Page size (default 50, capped at 200)" },
|
|
12
|
+
offset: { type: "integer", description: "Number of results to skip (default 0)" },
|
|
13
13
|
},
|
|
14
14
|
required: ["name"],
|
|
15
15
|
)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rubydex
|
|
4
|
+
module MCPServer
|
|
5
|
+
class FindDeadCodeCandidatesTool < BaseTool
|
|
6
|
+
tool_name "find_dead_code_candidates"
|
|
7
|
+
description "Find Ruby classes, modules, and constants with no detected references, including dependency code. Dynamic usage through DSLs or metaprogramming may not be detected."
|
|
8
|
+
input_schema(
|
|
9
|
+
properties: {
|
|
10
|
+
limit: { type: "integer", description: "Page size (default 50, capped at 100)" },
|
|
11
|
+
offset: { type: "integer", description: "Number of results to skip (default 0)" },
|
|
12
|
+
},
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
#: (?limit: Integer, ?offset: Integer) -> Tool::Response
|
|
16
|
+
def call(limit: nil, offset: nil)
|
|
17
|
+
declarations = @graph.dead_code_candidates.sort_by(&:name)
|
|
18
|
+
page, total = paginate(declarations, offset, limit, 100)
|
|
19
|
+
candidates = page.map do |declaration|
|
|
20
|
+
{
|
|
21
|
+
name: declaration.name,
|
|
22
|
+
kind: declaration_kind(declaration),
|
|
23
|
+
locations: declaration.definitions.sort_by(&:location).map do |definition|
|
|
24
|
+
display_location(definition.location)
|
|
25
|
+
end,
|
|
26
|
+
}
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
response(candidates: candidates, total: total)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -4,10 +4,10 @@ module Rubydex
|
|
|
4
4
|
module MCPServer
|
|
5
5
|
class GetDeclarationTool < BaseTool
|
|
6
6
|
tool_name "get_declaration"
|
|
7
|
-
description
|
|
7
|
+
description "Get a Ruby declaration's definition locations, documentation, ancestors, and members."
|
|
8
8
|
input_schema(
|
|
9
9
|
properties: {
|
|
10
|
-
name: { type: "string", description:
|
|
10
|
+
name: { type: "string", description: 'Exact fully qualified name: "Foo::Bar", "Foo::Bar#method_name()" (instance method), "Foo::Bar::<Bar>" (singleton class), or "Foo::Bar::<Bar>#method_name()" (class method)' },
|
|
11
11
|
},
|
|
12
12
|
required: ["name"],
|
|
13
13
|
)
|
|
@@ -4,12 +4,12 @@ module Rubydex
|
|
|
4
4
|
module MCPServer
|
|
5
5
|
class GetDescendantsTool < BaseTool
|
|
6
6
|
tool_name "get_descendants"
|
|
7
|
-
description "
|
|
7
|
+
description "List a class or module and its known descendants, including transitive descendants."
|
|
8
8
|
input_schema(
|
|
9
9
|
properties: {
|
|
10
|
-
name: { type: "string", description: "Fully qualified
|
|
11
|
-
limit: { type: "integer", description: "
|
|
12
|
-
offset: { type: "integer", description: "Number of
|
|
10
|
+
name: { type: "string", description: "Fully qualified class or module name" },
|
|
11
|
+
limit: { type: "integer", description: "Page size (default 50, capped at 500)" },
|
|
12
|
+
offset: { type: "integer", description: "Number of results to skip (default 0)" },
|
|
13
13
|
},
|
|
14
14
|
required: ["name"],
|
|
15
15
|
)
|
|
@@ -4,10 +4,10 @@ module Rubydex
|
|
|
4
4
|
module MCPServer
|
|
5
5
|
class GetFileDeclarationsTool < BaseTool
|
|
6
6
|
tool_name "get_file_declarations"
|
|
7
|
-
description "List
|
|
7
|
+
description "List Ruby declarations defined in an indexed file."
|
|
8
8
|
input_schema(
|
|
9
9
|
properties: {
|
|
10
|
-
file_path: { type: "string", description: "
|
|
10
|
+
file_path: { type: "string", description: "Absolute path or path relative to the workspace root" },
|
|
11
11
|
},
|
|
12
12
|
required: ["file_path"],
|
|
13
13
|
)
|
|
@@ -4,14 +4,14 @@ module Rubydex
|
|
|
4
4
|
module MCPServer
|
|
5
5
|
class SearchDeclarationsTool < BaseTool
|
|
6
6
|
tool_name "search_declarations"
|
|
7
|
-
description
|
|
7
|
+
description "Find definitions of Ruby classes, modules, methods, or constants by full or partial name."
|
|
8
8
|
input_schema(
|
|
9
9
|
properties: {
|
|
10
|
-
query: { type: "string", description: "
|
|
11
|
-
kind: { type: "string", description: "
|
|
12
|
-
match_mode: { type: "string", description: '
|
|
13
|
-
limit: { type: "integer", description: "
|
|
14
|
-
offset: { type: "integer", description: "Number of results to skip
|
|
10
|
+
query: { type: "string", description: "Text to match against fully qualified names. An empty string matches all declarations." },
|
|
11
|
+
kind: { type: "string", description: "Case-insensitive declaration kind, such as Class, Module, Method, or Constant" },
|
|
12
|
+
match_mode: { type: "string", description: '"fuzzy" (default) matches characters in order, ignoring ASCII case. "exact" matches a case-sensitive substring.' },
|
|
13
|
+
limit: { type: "integer", description: "Page size (default 50, capped at 100)" },
|
|
14
|
+
offset: { type: "integer", description: "Number of results to skip (default 0)" },
|
|
15
15
|
},
|
|
16
16
|
required: ["query"],
|
|
17
17
|
)
|
data/lib/rubydex/mcp_server.rb
CHANGED
|
@@ -10,19 +10,13 @@ Dir[File.join(__dir__, "mcp_server", "tools", "*_tool.rb")].sort.each { |file| r
|
|
|
10
10
|
module Rubydex
|
|
11
11
|
module MCPServer
|
|
12
12
|
SERVER_INSTRUCTIONS = <<~TEXT
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
Use these tools for Ruby source files (.rb, .rbi, .rbs) when you need structural information about declarations, locations, hierarchy, references, or codebase composition.
|
|
16
|
-
|
|
17
|
-
Use text search instead for literal strings, comments, log messages, non-Ruby files, or content search rather than structural queries.
|
|
18
|
-
|
|
19
|
-
Fully qualified name format: "Foo::Bar" for classes/modules/constants, "Foo::Bar#method_name" for instance methods.
|
|
20
|
-
|
|
21
|
-
Pagination: tools that may return a high number of results include `total` for pagination. When `total` exceeds the number of returned items, use `offset` to fetch the next page.
|
|
13
|
+
Tools query a static index of workspace code, available bundle dependencies, and available Ruby core and standard-library RBS definitions.
|
|
14
|
+
The index is built at server startup and does not track file changes; restart the server to refresh it.
|
|
22
15
|
TEXT
|
|
23
16
|
|
|
24
17
|
class Server
|
|
25
18
|
WORKER_COUNT = 4
|
|
19
|
+
SHUTDOWN_JOIN_TIMEOUT = 2
|
|
26
20
|
|
|
27
21
|
#: (root_path: String, ?transport: StdioTransport) -> void
|
|
28
22
|
def initialize(root_path:, transport: nil)
|
|
@@ -34,13 +28,14 @@ module Rubydex
|
|
|
34
28
|
@outgoing_queue = Thread::Queue.new
|
|
35
29
|
@workers = []
|
|
36
30
|
@outgoing_dispatcher = nil
|
|
31
|
+
@indexer = nil
|
|
37
32
|
end
|
|
38
33
|
|
|
39
34
|
attr_reader :root_path
|
|
40
35
|
|
|
41
36
|
#: -> Thread
|
|
42
37
|
def spawn_indexer
|
|
43
|
-
Thread.new do
|
|
38
|
+
@indexer = Thread.new do
|
|
44
39
|
@graph.index_workspace
|
|
45
40
|
@graph.resolve
|
|
46
41
|
@index_finished = true
|
|
@@ -150,9 +145,26 @@ module Rubydex
|
|
|
150
145
|
#: -> void
|
|
151
146
|
def run_shutdown
|
|
152
147
|
@incoming_queue.close unless @incoming_queue.closed?
|
|
153
|
-
@workers
|
|
148
|
+
join_or_kill_all(@workers + [@indexer])
|
|
154
149
|
@outgoing_queue.close unless @outgoing_queue.closed?
|
|
155
|
-
@outgoing_dispatcher
|
|
150
|
+
join_or_kill_all([@outgoing_dispatcher])
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
#: (Array[Thread?]) -> void
|
|
154
|
+
def join_or_kill_all(threads)
|
|
155
|
+
live_threads = threads.compact.select(&:alive?)
|
|
156
|
+
return if live_threads.empty?
|
|
157
|
+
|
|
158
|
+
deadline = Process.clock_gettime(Process::CLOCK_MONOTONIC) + SHUTDOWN_JOIN_TIMEOUT
|
|
159
|
+
live_threads.each do |thread|
|
|
160
|
+
remaining = deadline - Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
161
|
+
break if remaining <= 0
|
|
162
|
+
|
|
163
|
+
thread.join(remaining)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
live_threads.select(&:alive?).each(&:kill)
|
|
167
|
+
live_threads.select(&:alive?).each(&:join)
|
|
156
168
|
end
|
|
157
169
|
|
|
158
170
|
#: -> Thread
|
data/lib/rubydex/version.rb
CHANGED
data/rust/Cargo.lock
CHANGED
|
@@ -99,7 +99,7 @@ dependencies = [
|
|
|
99
99
|
"quote",
|
|
100
100
|
"regex",
|
|
101
101
|
"rustc-hash",
|
|
102
|
-
"shlex",
|
|
102
|
+
"shlex 1.3.0",
|
|
103
103
|
"syn",
|
|
104
104
|
]
|
|
105
105
|
|
|
@@ -151,7 +151,7 @@ version = "1.2.30"
|
|
|
151
151
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
152
152
|
checksum = "deec109607ca693028562ed836a5f1c4b8bd77755c4e132fc5ce11b0b6211ae7"
|
|
153
153
|
dependencies = [
|
|
154
|
-
"shlex",
|
|
154
|
+
"shlex 1.3.0",
|
|
155
155
|
]
|
|
156
156
|
|
|
157
157
|
[[package]]
|
|
@@ -718,9 +718,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
|
|
718
718
|
|
|
719
719
|
[[package]]
|
|
720
720
|
name = "ruby-prism"
|
|
721
|
-
version = "
|
|
721
|
+
version = "2.0.0-rc.2"
|
|
722
722
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
723
|
-
checksum = "
|
|
723
|
+
checksum = "6d34b0f30ca0b7233a454827204ee7dc1a70d8faa3a26eae95f09ada5386757c"
|
|
724
724
|
dependencies = [
|
|
725
725
|
"ruby-prism-sys",
|
|
726
726
|
"serde",
|
|
@@ -729,12 +729,12 @@ dependencies = [
|
|
|
729
729
|
|
|
730
730
|
[[package]]
|
|
731
731
|
name = "ruby-prism-sys"
|
|
732
|
-
version = "
|
|
732
|
+
version = "2.0.0-rc.2"
|
|
733
733
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
734
|
-
checksum = "
|
|
734
|
+
checksum = "f0e59b94e20c878bb618a355abd00724ad1eb4514341936c6668bea987437a29"
|
|
735
735
|
dependencies = [
|
|
736
|
-
"bindgen",
|
|
737
736
|
"cc",
|
|
737
|
+
"shlex 2.0.1",
|
|
738
738
|
]
|
|
739
739
|
|
|
740
740
|
[[package]]
|
|
@@ -760,7 +760,7 @@ dependencies = [
|
|
|
760
760
|
|
|
761
761
|
[[package]]
|
|
762
762
|
name = "rubydex"
|
|
763
|
-
version = "0.2
|
|
763
|
+
version = "0.4.2"
|
|
764
764
|
dependencies = [
|
|
765
765
|
"assert_cmd",
|
|
766
766
|
"bitflags",
|
|
@@ -789,7 +789,7 @@ dependencies = [
|
|
|
789
789
|
|
|
790
790
|
[[package]]
|
|
791
791
|
name = "rubydex-sys"
|
|
792
|
-
version = "0.2
|
|
792
|
+
version = "0.4.2"
|
|
793
793
|
dependencies = [
|
|
794
794
|
"cbindgen",
|
|
795
795
|
"libc",
|
|
@@ -902,6 +902,12 @@ version = "1.3.0"
|
|
|
902
902
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
903
903
|
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
|
904
904
|
|
|
905
|
+
[[package]]
|
|
906
|
+
name = "shlex"
|
|
907
|
+
version = "2.0.1"
|
|
908
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
909
|
+
checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba"
|
|
910
|
+
|
|
905
911
|
[[package]]
|
|
906
912
|
name = "smallvec"
|
|
907
913
|
version = "1.15.1"
|
|
@@ -1326,9 +1332,9 @@ checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb"
|
|
|
1326
1332
|
|
|
1327
1333
|
[[package]]
|
|
1328
1334
|
name = "xxhash-rust"
|
|
1329
|
-
version = "0.8.
|
|
1335
|
+
version = "0.8.16"
|
|
1330
1336
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1331
|
-
checksum = "
|
|
1337
|
+
checksum = "4d93c89cdc2d3a63c3ec48ffe926931bdc069eafa8e4402fe6d8f790c9d1e576"
|
|
1332
1338
|
|
|
1333
1339
|
[[package]]
|
|
1334
1340
|
name = "yoke"
|
data/rust/Cargo.toml
CHANGED
data/rust/rubydex/Cargo.toml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "rubydex"
|
|
3
|
-
version =
|
|
3
|
+
version.workspace = true
|
|
4
4
|
edition = "2024"
|
|
5
5
|
rust-version = "1.89.0"
|
|
6
6
|
license = "MIT"
|
|
@@ -32,7 +32,7 @@ test_utils = ["dep:tempfile"]
|
|
|
32
32
|
|
|
33
33
|
[dependencies]
|
|
34
34
|
cypher-parser = "0.8.1"
|
|
35
|
-
ruby-prism = "
|
|
35
|
+
ruby-prism = "2.0.0-rc.2"
|
|
36
36
|
ruby-rbs = "0.3"
|
|
37
37
|
url = "2.5.4"
|
|
38
38
|
xxhash-rust = { version = "0.8.15", features = ["xxh3"] }
|
|
@@ -3,11 +3,13 @@
|
|
|
3
3
|
macro_rules! assert_mem_size {
|
|
4
4
|
($struct:ident, $size:expr) => {
|
|
5
5
|
// Check struct name on this assert! error
|
|
6
|
+
#[cfg(target_pointer_width = "64")]
|
|
6
7
|
const _: () = assert!(
|
|
7
8
|
std::mem::size_of::<$struct>() == $size,
|
|
8
9
|
concat!("Incorrect size for `", stringify!($struct), "`")
|
|
9
10
|
);
|
|
10
11
|
// Check actual size on this array error
|
|
12
|
+
#[cfg(target_pointer_width = "64")]
|
|
11
13
|
const _: [(); $size] = [(); std::mem::size_of::<$struct>()];
|
|
12
14
|
};
|
|
13
15
|
}
|
data/rust/rubydex/src/config.rs
CHANGED
|
@@ -433,7 +433,7 @@ mod tests {
|
|
|
433
433
|
|
|
434
434
|
let other = rules.iter().find(|rule| rule.name() == "Other").unwrap();
|
|
435
435
|
assert!(!other.enabled());
|
|
436
|
-
|
|
436
|
+
assert_eq!(other.exclude_patterns(), []);
|
|
437
437
|
assert_eq!(other.severity(), None);
|
|
438
438
|
}
|
|
439
439
|
|
|
@@ -33,8 +33,8 @@ pub struct RBSIndexer<'a> {
|
|
|
33
33
|
|
|
34
34
|
impl<'a> RBSIndexer<'a> {
|
|
35
35
|
#[must_use]
|
|
36
|
-
pub fn new(uri:
|
|
37
|
-
let uri_id = UriId::from(
|
|
36
|
+
pub fn new(uri: Box<str>, source: &'a str) -> Self {
|
|
37
|
+
let uri_id = UriId::from(&*uri);
|
|
38
38
|
let local_graph = LocalGraph::new(uri_id, Document::new(uri, source));
|
|
39
39
|
|
|
40
40
|
Self {
|
|
@@ -197,7 +197,7 @@ impl<'a> RBSIndexer<'a> {
|
|
|
197
197
|
// Skip past indentation to the comment text
|
|
198
198
|
current_offset += line_indent as u32;
|
|
199
199
|
|
|
200
|
-
let line_text = line[line_indent..].
|
|
200
|
+
let line_text: Box<str> = line[line_indent..].into();
|
|
201
201
|
let line_bytes = line_text.len() as u32;
|
|
202
202
|
let offset = Offset::new(current_offset, current_offset + line_bytes);
|
|
203
203
|
comments.push(Comment::new(offset, line_text));
|
|
@@ -1454,7 +1454,7 @@ mod tests {
|
|
|
1454
1454
|
fn split_multiline_comments_crlf() {
|
|
1455
1455
|
// Build the indexer directly to bypass normalize_indentation, which strips \r
|
|
1456
1456
|
let source = "# First line\r\n# Second line\r\nclass Foo\r\nend\r\n";
|
|
1457
|
-
let mut indexer = RBSIndexer::new("file:///foo.rbs".
|
|
1457
|
+
let mut indexer = RBSIndexer::new("file:///foo.rbs".into(), source);
|
|
1458
1458
|
indexer.index();
|
|
1459
1459
|
let context = LocalGraphTest::from_local_graph("file:///foo.rbs", source, indexer.local_graph());
|
|
1460
1460
|
|