rubydex 0.3.0 → 0.4.0
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 +45 -7
- data/THIRD_PARTY_LICENSES.html +238 -2
- data/exe/rdx +2 -149
- data/ext/rubydex/config.c +140 -0
- data/ext/rubydex/config.h +16 -0
- data/ext/rubydex/diagnostic.c +75 -1
- data/ext/rubydex/diagnostic.h +2 -0
- data/ext/rubydex/graph.c +13 -45
- data/ext/rubydex/graph.h +6 -0
- data/ext/rubydex/query.c +398 -16
- data/ext/rubydex/rubydex.c +2 -0
- data/ext/rubydex/utils.c +11 -4
- data/lib/ruby_lsp/rubydex/addon.rb +211 -0
- data/lib/rubydex/cli/command/console.rb +55 -0
- data/lib/rubydex/cli/command/lint/explain.rb +74 -0
- data/lib/rubydex/cli/command/lint.rb +202 -0
- data/lib/rubydex/cli/command/mcp.rb +30 -0
- data/lib/rubydex/cli/command/query.rb +70 -0
- data/lib/rubydex/cli/command/skill.rb +69 -0
- data/lib/rubydex/cli/command.rb +168 -0
- data/lib/rubydex/cli.rb +93 -0
- data/lib/rubydex/config.rb +59 -0
- data/lib/rubydex/diagnostic.rb +12 -3
- data/lib/rubydex/errors.rb +42 -1
- data/lib/rubydex/graph.rb +10 -3
- data/lib/rubydex/linter/custom_rule.rb +97 -0
- data/lib/rubydex/linter/helpers/path_helpers.rb +78 -0
- data/lib/rubydex/linter/helpers/source_access_helpers.rb +31 -0
- data/lib/rubydex/linter/rule_loader.rb +36 -0
- data/lib/rubydex/linter/rule_test_case.rb +343 -0
- data/lib/rubydex/linter/runner.rb +56 -0
- data/lib/rubydex/linter.rb +19 -0
- data/lib/rubydex/location.rb +3 -0
- data/lib/rubydex/mcp_server.rb +1 -2
- data/lib/rubydex/related_information.rb +17 -0
- data/lib/rubydex/rule.rb +33 -0
- data/lib/rubydex/severity.rb +70 -0
- data/lib/rubydex/skill.rb +88 -0
- data/lib/rubydex/skill_registry.rb +62 -0
- data/lib/rubydex/version.rb +1 -1
- data/lib/rubydex.rb +6 -0
- data/lib/rubydex_linter/rules/rule_structure.rb +125 -0
- data/rbi/rubydex.rbi +558 -17
- data/rust/Cargo.lock +2 -2
- data/rust/rubydex/Cargo.toml +1 -1
- data/rust/rubydex/benches/graph_memory.rs +3 -5
- data/rust/rubydex/src/config.rs +538 -157
- data/rust/rubydex/src/diagnostic.rs +66 -40
- data/rust/rubydex/src/errors.rs +0 -1
- data/rust/rubydex/src/indexing/local_graph.rs +6 -5
- data/rust/rubydex/src/indexing/rbs_indexer.rs +270 -6
- data/rust/rubydex/src/indexing/ruby_indexer.rs +10 -12
- data/rust/rubydex/src/indexing/ruby_indexer_tests.rs +134 -81
- data/rust/rubydex/src/lib.rs +1 -0
- data/rust/rubydex/src/listing.rs +26 -1
- data/rust/rubydex/src/main.rs +7 -4
- data/rust/rubydex/src/model/declaration.rs +302 -219
- data/rust/rubydex/src/model/graph.rs +27 -40
- data/rust/rubydex/src/model/name.rs +58 -17
- data/rust/rubydex/src/operation/ruby_builder.rs +30 -45
- data/rust/rubydex/src/path_helpers.rs +77 -0
- data/rust/rubydex/src/query/cypher/schema.rs +63 -0
- data/rust/rubydex/src/query/cypher/tests.rs +26 -1
- data/rust/rubydex/src/query/cypher.rs +8 -11
- data/rust/rubydex/src/query.rs +123 -43
- data/rust/rubydex/src/resolution.rs +139 -187
- data/rust/rubydex/src/resolution_tests.rs +247 -19
- data/rust/rubydex/src/test_utils/context.rs +2 -1
- data/rust/rubydex/src/test_utils/graph_test.rs +26 -12
- data/rust/rubydex/src/test_utils/local_graph_test.rs +19 -0
- data/rust/rubydex/tests/cli.rs +4 -4
- data/rust/rubydex-sys/src/config_api.rs +205 -0
- data/rust/rubydex-sys/src/cypher_api.rs +791 -0
- data/rust/rubydex-sys/src/diagnostic_api.rs +77 -8
- data/rust/rubydex-sys/src/graph_api.rs +13 -194
- data/rust/rubydex-sys/src/lib.rs +2 -0
- data/rust/rubydex-sys/src/name_api.rs +2 -6
- data/rust/rubydex-sys/src/utils.rs +37 -0
- data/skills/send-private-method/SKILL.md +133 -0
- metadata +31 -2
data/rbi/rubydex.rbi
CHANGED
|
@@ -182,11 +182,91 @@ class Rubydex::GlobalVariableDefinition < Rubydex::Definition; end
|
|
|
182
182
|
class Rubydex::InstanceVariableDefinition < Rubydex::Definition; end
|
|
183
183
|
|
|
184
184
|
class Rubydex::MethodAliasDefinition < Rubydex::Definition
|
|
185
|
+
sig { returns(T::Array[Rubydex::Signature]) }
|
|
186
|
+
def signatures; end
|
|
187
|
+
|
|
185
188
|
sig { returns(T.nilable(Rubydex::Method)) }
|
|
186
189
|
def target; end
|
|
187
190
|
end
|
|
188
191
|
|
|
189
|
-
class Rubydex::MethodDefinition < Rubydex::Definition
|
|
192
|
+
class Rubydex::MethodDefinition < Rubydex::Definition
|
|
193
|
+
sig { returns(T::Array[Rubydex::Signature]) }
|
|
194
|
+
def signatures; end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
class Rubydex::Signature
|
|
198
|
+
sig { params(parameters: T::Array[Rubydex::Signature::Parameter]).void }
|
|
199
|
+
def initialize(parameters); end
|
|
200
|
+
|
|
201
|
+
sig { returns(T::Array[Rubydex::Signature::Parameter]) }
|
|
202
|
+
def parameters; end
|
|
203
|
+
|
|
204
|
+
sig do
|
|
205
|
+
returns([
|
|
206
|
+
T::Array[Rubydex::Signature::PositionalParameter],
|
|
207
|
+
T::Array[Rubydex::Signature::OptionalPositionalParameter],
|
|
208
|
+
T.nilable(Rubydex::Signature::RestPositionalParameter),
|
|
209
|
+
T::Array[Rubydex::Signature::PostParameter],
|
|
210
|
+
T::Array[Rubydex::Signature::KeywordParameter],
|
|
211
|
+
T::Array[Rubydex::Signature::OptionalKeywordParameter],
|
|
212
|
+
T.nilable(Rubydex::Signature::RestKeywordParameter),
|
|
213
|
+
T.nilable(Rubydex::Signature::ForwardParameter),
|
|
214
|
+
T.nilable(Rubydex::Signature::BlockParameter),
|
|
215
|
+
])
|
|
216
|
+
end
|
|
217
|
+
def deconstruct; end
|
|
218
|
+
|
|
219
|
+
sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) }
|
|
220
|
+
def deconstruct_keys(keys); end
|
|
221
|
+
|
|
222
|
+
sig { returns(T::Array[Rubydex::Signature::PositionalParameter]) }
|
|
223
|
+
def positional_parameters; end
|
|
224
|
+
|
|
225
|
+
sig { returns(T::Array[Rubydex::Signature::OptionalPositionalParameter]) }
|
|
226
|
+
def optional_positional_parameters; end
|
|
227
|
+
|
|
228
|
+
sig { returns(T.nilable(Rubydex::Signature::RestPositionalParameter)) }
|
|
229
|
+
def rest_positional_parameter; end
|
|
230
|
+
|
|
231
|
+
sig { returns(T::Array[Rubydex::Signature::PostParameter]) }
|
|
232
|
+
def post_parameters; end
|
|
233
|
+
|
|
234
|
+
sig { returns(T::Array[Rubydex::Signature::KeywordParameter]) }
|
|
235
|
+
def keyword_parameters; end
|
|
236
|
+
|
|
237
|
+
sig { returns(T::Array[Rubydex::Signature::OptionalKeywordParameter]) }
|
|
238
|
+
def optional_keyword_parameters; end
|
|
239
|
+
|
|
240
|
+
sig { returns(T.nilable(Rubydex::Signature::RestKeywordParameter)) }
|
|
241
|
+
def rest_keyword_parameter; end
|
|
242
|
+
|
|
243
|
+
sig { returns(T.nilable(Rubydex::Signature::ForwardParameter)) }
|
|
244
|
+
def forward_parameter; end
|
|
245
|
+
|
|
246
|
+
sig { returns(T.nilable(Rubydex::Signature::BlockParameter)) }
|
|
247
|
+
def block_parameter; end
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
class Rubydex::Signature::Parameter
|
|
251
|
+
sig { returns(Symbol) }
|
|
252
|
+
def name; end
|
|
253
|
+
|
|
254
|
+
sig { returns(Rubydex::Location) }
|
|
255
|
+
def location; end
|
|
256
|
+
|
|
257
|
+
sig { params(name: Symbol, location: Rubydex::Location).void }
|
|
258
|
+
def initialize(name, location); end
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
class Rubydex::Signature::PositionalParameter < Rubydex::Signature::Parameter; end
|
|
262
|
+
class Rubydex::Signature::OptionalPositionalParameter < Rubydex::Signature::Parameter; end
|
|
263
|
+
class Rubydex::Signature::RestPositionalParameter < Rubydex::Signature::Parameter; end
|
|
264
|
+
class Rubydex::Signature::PostParameter < Rubydex::Signature::Parameter; end
|
|
265
|
+
class Rubydex::Signature::KeywordParameter < Rubydex::Signature::Parameter; end
|
|
266
|
+
class Rubydex::Signature::OptionalKeywordParameter < Rubydex::Signature::Parameter; end
|
|
267
|
+
class Rubydex::Signature::RestKeywordParameter < Rubydex::Signature::Parameter; end
|
|
268
|
+
class Rubydex::Signature::ForwardParameter < Rubydex::Signature::Parameter; end
|
|
269
|
+
class Rubydex::Signature::BlockParameter < Rubydex::Signature::Parameter; end
|
|
190
270
|
|
|
191
271
|
class Rubydex::ModuleDefinition < Rubydex::Definition
|
|
192
272
|
sig { returns(T::Array[Rubydex::Mixin]) }
|
|
@@ -220,9 +300,138 @@ class Rubydex::Include < Rubydex::Mixin; end
|
|
|
220
300
|
class Rubydex::Prepend < Rubydex::Mixin; end
|
|
221
301
|
class Rubydex::Extend < Rubydex::Mixin; end
|
|
222
302
|
|
|
303
|
+
module Rubydex::Severity
|
|
304
|
+
# Every severity, ordered from the most to the least severe.
|
|
305
|
+
ALL = T.let(T.unsafe(nil), T::Array[T.class_of(Rubydex::Severity::Base)])
|
|
306
|
+
|
|
307
|
+
sig { params(value: Symbol).returns(T.class_of(Rubydex::Severity::Base)) }
|
|
308
|
+
def self.from_value(value); end
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
class Rubydex::Severity::Base
|
|
312
|
+
abstract!
|
|
313
|
+
|
|
314
|
+
sig { returns(Symbol) }
|
|
315
|
+
def self.value; end
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
class Rubydex::Severity::Error < Rubydex::Severity::Base; end
|
|
319
|
+
class Rubydex::Severity::Warning < Rubydex::Severity::Base; end
|
|
320
|
+
class Rubydex::Severity::Information < Rubydex::Severity::Base; end
|
|
321
|
+
class Rubydex::Severity::Hint < Rubydex::Severity::Base; end
|
|
322
|
+
|
|
323
|
+
class Rubydex::Rule
|
|
324
|
+
abstract!
|
|
325
|
+
|
|
326
|
+
class << self
|
|
327
|
+
abstract!
|
|
328
|
+
|
|
329
|
+
sig { returns(String) }
|
|
330
|
+
def rule_name; end
|
|
331
|
+
|
|
332
|
+
sig { abstract.returns(T.class_of(Rubydex::Severity::Base)) }
|
|
333
|
+
def default_severity; end
|
|
334
|
+
|
|
335
|
+
sig { params(config: Rubydex::LinterConfig).returns(T.class_of(Rubydex::Severity::Base)) }
|
|
336
|
+
def severity(config); end
|
|
337
|
+
end
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
module Rubydex::Rules
|
|
341
|
+
ALL = T.let(T.unsafe(nil), T::Array[T.class_of(Rubydex::Rule)])
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
class Rubydex::Rules::ParseError < Rubydex::Rule
|
|
345
|
+
class << self
|
|
346
|
+
sig { override.returns(T.class_of(Rubydex::Severity::Base)) }
|
|
347
|
+
def default_severity; end
|
|
348
|
+
end
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
class Rubydex::Rules::ParseWarning < Rubydex::Rule
|
|
352
|
+
class << self
|
|
353
|
+
sig { override.returns(T.class_of(Rubydex::Severity::Base)) }
|
|
354
|
+
def default_severity; end
|
|
355
|
+
end
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
class Rubydex::Rules::DynamicConstantReference < Rubydex::Rule
|
|
359
|
+
class << self
|
|
360
|
+
sig { override.returns(T.class_of(Rubydex::Severity::Base)) }
|
|
361
|
+
def default_severity; end
|
|
362
|
+
end
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
class Rubydex::Rules::DynamicSingletonDefinition < Rubydex::Rule
|
|
366
|
+
class << self
|
|
367
|
+
sig { override.returns(T.class_of(Rubydex::Severity::Base)) }
|
|
368
|
+
def default_severity; end
|
|
369
|
+
end
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
class Rubydex::Rules::DynamicAncestor < Rubydex::Rule
|
|
373
|
+
class << self
|
|
374
|
+
sig { override.returns(T.class_of(Rubydex::Severity::Base)) }
|
|
375
|
+
def default_severity; end
|
|
376
|
+
end
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
class Rubydex::Rules::TopLevelMixinSelf < Rubydex::Rule
|
|
380
|
+
class << self
|
|
381
|
+
sig { override.returns(T.class_of(Rubydex::Severity::Base)) }
|
|
382
|
+
def default_severity; end
|
|
383
|
+
end
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
class Rubydex::Rules::InvalidConstantVisibility < Rubydex::Rule
|
|
387
|
+
class << self
|
|
388
|
+
sig { override.returns(T.class_of(Rubydex::Severity::Base)) }
|
|
389
|
+
def default_severity; end
|
|
390
|
+
end
|
|
391
|
+
end
|
|
392
|
+
|
|
393
|
+
class Rubydex::Rules::InvalidMethodVisibility < Rubydex::Rule
|
|
394
|
+
class << self
|
|
395
|
+
sig { override.returns(T.class_of(Rubydex::Severity::Base)) }
|
|
396
|
+
def default_severity; end
|
|
397
|
+
end
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
class Rubydex::Rules::UndefinedMethodVisibilityTarget < Rubydex::Rule
|
|
401
|
+
class << self
|
|
402
|
+
sig { override.returns(T.class_of(Rubydex::Severity::Base)) }
|
|
403
|
+
def default_severity; end
|
|
404
|
+
end
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
class Rubydex::Rules::UndefinedConstantVisibilityTarget < Rubydex::Rule
|
|
408
|
+
class << self
|
|
409
|
+
sig { override.returns(T.class_of(Rubydex::Severity::Base)) }
|
|
410
|
+
def default_severity; end
|
|
411
|
+
end
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
class Rubydex::RelatedInformation
|
|
415
|
+
sig { params(message: String, location: Rubydex::Location).void }
|
|
416
|
+
def initialize(message, location); end
|
|
417
|
+
|
|
418
|
+
sig { returns(Rubydex::Location) }
|
|
419
|
+
def location; end
|
|
420
|
+
|
|
421
|
+
sig { returns(String) }
|
|
422
|
+
def message; end
|
|
423
|
+
end
|
|
424
|
+
|
|
223
425
|
class Rubydex::Diagnostic
|
|
224
|
-
sig
|
|
225
|
-
|
|
426
|
+
sig do
|
|
427
|
+
params(
|
|
428
|
+
rule: T.class_of(Rubydex::Rule),
|
|
429
|
+
message: String,
|
|
430
|
+
location: Rubydex::Location,
|
|
431
|
+
related_information: T::Array[Rubydex::RelatedInformation],
|
|
432
|
+
).void
|
|
433
|
+
end
|
|
434
|
+
def initialize(rule:, message:, location:, related_information: []); end
|
|
226
435
|
|
|
227
436
|
sig { returns(Rubydex::Location) }
|
|
228
437
|
def location; end
|
|
@@ -230,8 +439,231 @@ class Rubydex::Diagnostic
|
|
|
230
439
|
sig { returns(String) }
|
|
231
440
|
def message; end
|
|
232
441
|
|
|
233
|
-
sig { returns(
|
|
442
|
+
sig { returns(T.class_of(Rubydex::Rule)) }
|
|
234
443
|
def rule; end
|
|
444
|
+
|
|
445
|
+
sig { returns(T::Array[Rubydex::RelatedInformation]) }
|
|
446
|
+
def related_information; end
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
module Rubydex::Linter; end
|
|
450
|
+
module Rubydex::Linter::Helpers; end
|
|
451
|
+
module Rubydex::Linter::Rules; end
|
|
452
|
+
|
|
453
|
+
module Rubydex::Linter::Helpers::PathHelpers
|
|
454
|
+
extend T::Helpers
|
|
455
|
+
|
|
456
|
+
requires_ancestor { Rubydex::Linter::CustomRule }
|
|
457
|
+
|
|
458
|
+
EXCLUDE_FNMATCH_FLAGS = T.let(T.unsafe(nil), Integer)
|
|
459
|
+
TEST_PATHS = T.let(T.unsafe(nil), T::Array[String])
|
|
460
|
+
|
|
461
|
+
sig do
|
|
462
|
+
params(
|
|
463
|
+
path: String,
|
|
464
|
+
patterns: T::Array[String],
|
|
465
|
+
workspace: String,
|
|
466
|
+
flags: Integer,
|
|
467
|
+
).returns(T::Boolean)
|
|
468
|
+
end
|
|
469
|
+
def self.path_matches_patterns?(path, patterns, workspace:, flags: 0); end
|
|
470
|
+
|
|
471
|
+
sig { params(location: Rubydex::Location, workspace: String).returns(String) }
|
|
472
|
+
def self.display_path(location, workspace:); end
|
|
473
|
+
|
|
474
|
+
sig do
|
|
475
|
+
params(
|
|
476
|
+
definitions: T::Enumerable[Rubydex::Definition],
|
|
477
|
+
excluded_patterns: T::Array[String],
|
|
478
|
+
).returns(T::Array[Rubydex::Definition])
|
|
479
|
+
end
|
|
480
|
+
def reject_definitions_in_paths(definitions, excluded_patterns); end
|
|
481
|
+
|
|
482
|
+
sig do
|
|
483
|
+
params(
|
|
484
|
+
definitions: T::Enumerable[Rubydex::Definition],
|
|
485
|
+
patterns: T::Array[String],
|
|
486
|
+
).returns(T::Array[Rubydex::Definition])
|
|
487
|
+
end
|
|
488
|
+
def select_definitions_in_paths(definitions, patterns); end
|
|
489
|
+
|
|
490
|
+
private
|
|
491
|
+
|
|
492
|
+
sig { params(path: String, patterns: T::Array[String]).returns(T::Boolean) }
|
|
493
|
+
def path_matches_patterns?(path, patterns); end
|
|
494
|
+
|
|
495
|
+
sig { params(path: String).returns(T::Boolean) }
|
|
496
|
+
def test_path?(path); end
|
|
497
|
+
|
|
498
|
+
sig { params(definition: Rubydex::Definition).returns(T.nilable(String)) }
|
|
499
|
+
def path_for_definition(definition); end
|
|
500
|
+
end
|
|
501
|
+
|
|
502
|
+
module Rubydex::Linter::Helpers::SourceAccessHelpers
|
|
503
|
+
sig { params(uri: String).returns(Rubydex::Location) }
|
|
504
|
+
def file_location(uri); end
|
|
505
|
+
|
|
506
|
+
sig { params(uri: String).returns(String) }
|
|
507
|
+
def path_for_uri(uri); end
|
|
508
|
+
|
|
509
|
+
private
|
|
510
|
+
|
|
511
|
+
sig { params(location: Rubydex::Location).returns(T.nilable(String)) }
|
|
512
|
+
def source_for_location(location); end
|
|
513
|
+
end
|
|
514
|
+
|
|
515
|
+
# Base class for semantic lint rules, which collect their diagnostics by walking a resolved graph.
|
|
516
|
+
class Rubydex::Linter::CustomRule < Rubydex::Rule
|
|
517
|
+
abstract!
|
|
518
|
+
|
|
519
|
+
sig { params(graph: Rubydex::Graph, config: Rubydex::LinterConfig).void }
|
|
520
|
+
def initialize(graph, config:); end
|
|
521
|
+
|
|
522
|
+
sig { returns(Rubydex::Graph) }
|
|
523
|
+
def graph; end
|
|
524
|
+
|
|
525
|
+
sig { returns(Rubydex::LinterConfig) }
|
|
526
|
+
def config; end
|
|
527
|
+
|
|
528
|
+
sig { returns(T::Array[Rubydex::Diagnostic]) }
|
|
529
|
+
def diagnostics; end
|
|
530
|
+
|
|
531
|
+
sig { params(definition: Rubydex::Definition).returns(Rubydex::Location) }
|
|
532
|
+
def diagnostic_location(definition); end
|
|
533
|
+
|
|
534
|
+
sig { params(base_name: String).returns(T::Enumerable[Rubydex::Class]) }
|
|
535
|
+
def child_classes(base_name); end
|
|
536
|
+
|
|
537
|
+
sig { params(name: String).returns(Rubydex::Namespace) }
|
|
538
|
+
def required_namespace(name); end
|
|
539
|
+
|
|
540
|
+
sig do
|
|
541
|
+
params(
|
|
542
|
+
namespace: Rubydex::Namespace,
|
|
543
|
+
method_name: String,
|
|
544
|
+
).returns(Rubydex::Method)
|
|
545
|
+
end
|
|
546
|
+
def required_method(namespace, method_name); end
|
|
547
|
+
|
|
548
|
+
sig { returns(String) }
|
|
549
|
+
def rule_name; end
|
|
550
|
+
|
|
551
|
+
sig { abstract.void }
|
|
552
|
+
def lint; end
|
|
553
|
+
|
|
554
|
+
protected
|
|
555
|
+
|
|
556
|
+
sig do
|
|
557
|
+
params(
|
|
558
|
+
message: String,
|
|
559
|
+
location: Rubydex::Location,
|
|
560
|
+
related_information: T::Array[Rubydex::RelatedInformation],
|
|
561
|
+
).void
|
|
562
|
+
end
|
|
563
|
+
def add_diagnostic(message, location, related_information: []); end
|
|
564
|
+
end
|
|
565
|
+
|
|
566
|
+
class Rubydex::Linter::MissingGraphDependencyError < StandardError
|
|
567
|
+
sig { params(rule_name: String, dependency: String).void }
|
|
568
|
+
def initialize(rule_name, dependency); end
|
|
569
|
+
end
|
|
570
|
+
|
|
571
|
+
class Rubydex::Linter::RuleLoadError < StandardError; end
|
|
572
|
+
|
|
573
|
+
class Rubydex::Linter::RuleLoader
|
|
574
|
+
RULE_GLOB = T.let(T.unsafe(nil), String)
|
|
575
|
+
|
|
576
|
+
sig { params(workspace_path: String).void }
|
|
577
|
+
def self.load(workspace_path); end
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
class Rubydex::Linter::Rules::RuleStructure < Rubydex::Linter::CustomRule
|
|
581
|
+
include Rubydex::Linter::Helpers::SourceAccessHelpers
|
|
582
|
+
|
|
583
|
+
BASE_RULE_NAME = T.let(T.unsafe(nil), String)
|
|
584
|
+
RULE_NAMESPACE = T.let(T.unsafe(nil), String)
|
|
585
|
+
RULE_FILE_PATTERNS = T.let(T.unsafe(nil), T::Array[String])
|
|
586
|
+
TEST_FILE_PATTERNS = T.let(T.unsafe(nil), T::Array[String])
|
|
587
|
+
|
|
588
|
+
class << self
|
|
589
|
+
sig { override.returns(T.class_of(Rubydex::Severity::Base)) }
|
|
590
|
+
def default_severity; end
|
|
591
|
+
end
|
|
592
|
+
|
|
593
|
+
sig { override.void }
|
|
594
|
+
def lint; end
|
|
595
|
+
end
|
|
596
|
+
|
|
597
|
+
class Rubydex::Linter::RuleTestCase < Minitest::Test
|
|
598
|
+
DEFAULT_FILE = T.let(T.unsafe(nil), String)
|
|
599
|
+
ANNOTATION_PATTERN = T.let(T.unsafe(nil), Regexp)
|
|
600
|
+
|
|
601
|
+
sig { returns(String) }
|
|
602
|
+
def workspace_path; end
|
|
603
|
+
|
|
604
|
+
sig { params(name: String).void }
|
|
605
|
+
def initialize(name); end
|
|
606
|
+
|
|
607
|
+
sig { void }
|
|
608
|
+
def teardown; end
|
|
609
|
+
|
|
610
|
+
sig { returns(T.class_of(Rubydex::Linter::CustomRule)) }
|
|
611
|
+
def rule_class; end
|
|
612
|
+
|
|
613
|
+
sig { params(sources: T::Hash[String, String]).void }
|
|
614
|
+
def add_shared_source(sources); end
|
|
615
|
+
|
|
616
|
+
sig { returns(T::Array[String]) }
|
|
617
|
+
def ignored_diagnostic_files; end
|
|
618
|
+
|
|
619
|
+
sig { returns(Rubydex::LinterConfig) }
|
|
620
|
+
def rule_config; end
|
|
621
|
+
|
|
622
|
+
sig do
|
|
623
|
+
params(
|
|
624
|
+
args: T.any(String, T::Hash[T.any(String, Symbol), String]),
|
|
625
|
+
rule_builder: T.nilable(T.proc.params(graph: Rubydex::Graph).returns(Rubydex::Linter::CustomRule)),
|
|
626
|
+
).returns(T::Array[Rubydex::Diagnostic])
|
|
627
|
+
end
|
|
628
|
+
def assert_diagnostics(*args, &rule_builder); end
|
|
629
|
+
|
|
630
|
+
sig do
|
|
631
|
+
params(
|
|
632
|
+
args: T.any(String, T::Hash[T.any(String, Symbol), String]),
|
|
633
|
+
rule_builder: T.nilable(T.proc.params(graph: Rubydex::Graph).returns(Rubydex::Linter::CustomRule)),
|
|
634
|
+
).returns(T::Array[Rubydex::Diagnostic])
|
|
635
|
+
end
|
|
636
|
+
def assert_no_diagnostics(*args, &rule_builder); end
|
|
637
|
+
|
|
638
|
+
sig do
|
|
639
|
+
params(
|
|
640
|
+
dependency: String,
|
|
641
|
+
args: T.any(String, T::Hash[T.any(String, Symbol), String]),
|
|
642
|
+
after_excluding: T::Array[String],
|
|
643
|
+
rule_builder: T.nilable(T.proc.params(graph: Rubydex::Graph).returns(Rubydex::Linter::CustomRule)),
|
|
644
|
+
).void
|
|
645
|
+
end
|
|
646
|
+
def assert_handles_missing_required_dependency(dependency, *args, after_excluding: [], &rule_builder); end
|
|
647
|
+
end
|
|
648
|
+
|
|
649
|
+
class Rubydex::Linter::Runner
|
|
650
|
+
sig do
|
|
651
|
+
params(
|
|
652
|
+
graph: Rubydex::Graph,
|
|
653
|
+
custom_rules: T::Array[T.class_of(Rubydex::Linter::CustomRule)],
|
|
654
|
+
config: Rubydex::LinterConfig,
|
|
655
|
+
).void
|
|
656
|
+
end
|
|
657
|
+
def initialize(graph, custom_rules:, config:); end
|
|
658
|
+
|
|
659
|
+
sig { returns(Rubydex::Graph) }
|
|
660
|
+
def graph; end
|
|
661
|
+
|
|
662
|
+
sig { returns(T::Array[T.class_of(Rubydex::Linter::CustomRule)]) }
|
|
663
|
+
def custom_rules; end
|
|
664
|
+
|
|
665
|
+
sig { returns(T::Array[Rubydex::Diagnostic]) }
|
|
666
|
+
def run; end
|
|
235
667
|
end
|
|
236
668
|
|
|
237
669
|
class Rubydex::Keyword
|
|
@@ -273,6 +705,74 @@ end
|
|
|
273
705
|
class Rubydex::Error < StandardError; end
|
|
274
706
|
class Rubydex::AliasCycleError < Rubydex::Error; end
|
|
275
707
|
class Rubydex::ConfigError < Rubydex::Error; end
|
|
708
|
+
class Rubydex::QueryError < Rubydex::Error; end
|
|
709
|
+
class Rubydex::QuerySyntaxError < Rubydex::QueryError; end
|
|
710
|
+
class Rubydex::QueryExecutionError < Rubydex::QueryError; end
|
|
711
|
+
class Rubydex::StaleQueryResultError < Rubydex::QueryError; end
|
|
712
|
+
|
|
713
|
+
# The configuration of a workspace, parsed from its `rubydex.toml`. It carries both the settings that are global to
|
|
714
|
+
# every built-in tool, such as the workspace being analyzed, and the typed settings of each tool's own section (e.g.
|
|
715
|
+
# `[graph]`, `[linter]`).
|
|
716
|
+
class Rubydex::Config
|
|
717
|
+
class << self
|
|
718
|
+
# Loads the configuration file for `workspace_path/rubydex.toml` if it exists or uses the defaults.
|
|
719
|
+
sig { params(workspace_path: String).returns(Rubydex::Config) }
|
|
720
|
+
def load(workspace_path); end
|
|
721
|
+
end
|
|
722
|
+
|
|
723
|
+
# The linter's settings, read from the `[linter]` section.
|
|
724
|
+
sig { returns(Rubydex::LinterConfig) }
|
|
725
|
+
def linter; end
|
|
726
|
+
|
|
727
|
+
# The configured workspace path, which is usually PWD, except for editors that spawn language servers outside of pwd.
|
|
728
|
+
sig { returns(String) }
|
|
729
|
+
def workspace_path; end
|
|
730
|
+
end
|
|
731
|
+
|
|
732
|
+
# The linter's settings, read from the `[linter]` section of the configuration file.
|
|
733
|
+
class Rubydex::LinterConfig
|
|
734
|
+
# The configured rules, keyed by rule name. Only rules the configuration file mentions appear here, so a rule that
|
|
735
|
+
# was never configured is absent rather than present with its defaults.
|
|
736
|
+
sig { returns(T::Hash[String, Rubydex::RuleConfig]) }
|
|
737
|
+
attr_reader :rules
|
|
738
|
+
|
|
739
|
+
sig { params(rules: T::Hash[String, Rubydex::RuleConfig]).void }
|
|
740
|
+
def initialize(rules); end
|
|
741
|
+
|
|
742
|
+
sig { params(rule_class: T.class_of(Rubydex::Rule)).returns(T::Boolean) }
|
|
743
|
+
def rule_enabled?(rule_class); end
|
|
744
|
+
|
|
745
|
+
sig { params(rule_class: T.class_of(Rubydex::Rule)).returns(T::Array[String]) }
|
|
746
|
+
def excludes_for(rule_class); end
|
|
747
|
+
|
|
748
|
+
sig { params(rule_class: T.class_of(Rubydex::Rule)).returns(T.nilable(T.class_of(Rubydex::Severity::Base))) }
|
|
749
|
+
def severity_for(rule_class); end
|
|
750
|
+
end
|
|
751
|
+
|
|
752
|
+
# The settings of a single linter rule, read from a `[linter.rules.RuleName]` table.
|
|
753
|
+
class Rubydex::RuleConfig
|
|
754
|
+
sig { returns(String) }
|
|
755
|
+
attr_reader :name
|
|
756
|
+
|
|
757
|
+
sig { returns(T::Array[String]) }
|
|
758
|
+
attr_reader :exclude_patterns
|
|
759
|
+
|
|
760
|
+
sig { returns(T.nilable(T.class_of(Rubydex::Severity::Base))) }
|
|
761
|
+
attr_reader :severity
|
|
762
|
+
|
|
763
|
+
sig do
|
|
764
|
+
params(
|
|
765
|
+
name: String,
|
|
766
|
+
enabled: T::Boolean,
|
|
767
|
+
exclude_patterns: T::Array[String],
|
|
768
|
+
severity: T.nilable(T.class_of(Rubydex::Severity::Base)),
|
|
769
|
+
).void
|
|
770
|
+
end
|
|
771
|
+
def initialize(name, enabled, exclude_patterns = [], severity = nil); end
|
|
772
|
+
|
|
773
|
+
sig { returns(T::Boolean) }
|
|
774
|
+
def enabled?; end
|
|
775
|
+
end
|
|
276
776
|
|
|
277
777
|
class Rubydex::Failure
|
|
278
778
|
sig { params(message: String).void }
|
|
@@ -293,13 +793,55 @@ class Rubydex::Query
|
|
|
293
793
|
def schema(format = :table); end
|
|
294
794
|
end
|
|
295
795
|
|
|
296
|
-
sig { params(graph: Rubydex::Graph
|
|
297
|
-
def
|
|
796
|
+
sig { params(graph: Rubydex::Graph).returns(Rubydex::Query::Result) }
|
|
797
|
+
def run(graph); end
|
|
798
|
+
end
|
|
799
|
+
|
|
800
|
+
# The columns and rows produced by one run of a query. Enumerable over its rows.
|
|
801
|
+
class Rubydex::Query::Result
|
|
802
|
+
include Enumerable
|
|
803
|
+
extend T::Generic
|
|
804
|
+
|
|
805
|
+
Elem = type_member { { fixed: T::Hash[String, T.untyped] } }
|
|
806
|
+
|
|
807
|
+
class << self
|
|
808
|
+
private
|
|
809
|
+
|
|
810
|
+
# A result only comes from `Query#run`. The C extension undefines `new`, so a call raises.
|
|
811
|
+
sig { returns(T.noreturn) }
|
|
812
|
+
def new; end
|
|
813
|
+
end
|
|
814
|
+
|
|
815
|
+
sig { returns(T::Array[String]) }
|
|
816
|
+
def columns; end
|
|
817
|
+
|
|
818
|
+
sig { returns(T::Array[T::Hash[String, T.untyped]]) }
|
|
819
|
+
def rows; end
|
|
820
|
+
|
|
821
|
+
sig { override.params(block: T.proc.params(row: T::Hash[String, T.untyped]).void).returns(T.self_type) }
|
|
822
|
+
sig { override.returns(T::Enumerator[T::Hash[String, T.untyped]]) }
|
|
823
|
+
def each(&block); end
|
|
824
|
+
|
|
825
|
+
sig { returns(Integer) }
|
|
826
|
+
def size; end
|
|
827
|
+
|
|
828
|
+
sig { returns(Integer) }
|
|
829
|
+
def length; end
|
|
830
|
+
|
|
831
|
+
sig { returns(T::Boolean) }
|
|
832
|
+
def empty?; end
|
|
833
|
+
|
|
834
|
+
sig { params(format: T.any(String, Symbol)).returns(String) }
|
|
835
|
+
def render(format = :table); end
|
|
298
836
|
end
|
|
299
837
|
|
|
300
838
|
class Rubydex::Graph
|
|
301
|
-
|
|
302
|
-
|
|
839
|
+
class << self
|
|
840
|
+
# Creates a new graph with the loaded configuration. For use cases where the graph must be shared between
|
|
841
|
+
# different tools, do not use this. Create and own a `Config` object instead.
|
|
842
|
+
sig { params(workspace_path: String).returns(T.attached_class) }
|
|
843
|
+
def configure_for_workspace(workspace_path); end
|
|
844
|
+
end
|
|
303
845
|
|
|
304
846
|
sig { params(fully_qualified_name: String).returns(T.nilable(Rubydex::Declaration)) }
|
|
305
847
|
def [](fully_qualified_name); end
|
|
@@ -332,12 +874,13 @@ class Rubydex::Graph
|
|
|
332
874
|
sig { returns(T::Array[String]) }
|
|
333
875
|
def index_workspace; end
|
|
334
876
|
|
|
335
|
-
#
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
877
|
+
# Returns the keyword object for the name, or `nil` if it is not a Ruby keyword
|
|
878
|
+
sig { params(name: String).returns(T.nilable(Rubydex::Keyword)) }
|
|
879
|
+
def keyword(name); end
|
|
880
|
+
|
|
881
|
+
# Loads the configuration in the graph.
|
|
882
|
+
sig { params(config: Rubydex::Config).void }
|
|
883
|
+
def load_config(config); end
|
|
341
884
|
|
|
342
885
|
sig { returns(T::Enumerable[Rubydex::MethodReference]) }
|
|
343
886
|
def method_references; end
|
|
@@ -363,12 +906,10 @@ class Rubydex::Graph
|
|
|
363
906
|
sig { params(encoding: String).void }
|
|
364
907
|
def encoding=(encoding); end
|
|
365
908
|
|
|
909
|
+
# The root directory of the workspace being analyzed, which comes from the loaded `Rubydex::Config`
|
|
366
910
|
sig { returns(String) }
|
|
367
911
|
def workspace_path; end
|
|
368
912
|
|
|
369
|
-
sig { params(workspace_path: String).returns(String) }
|
|
370
|
-
def workspace_path=(workspace_path); end
|
|
371
|
-
|
|
372
913
|
sig { returns(T::Array[String]) }
|
|
373
914
|
def workspace_paths; end
|
|
374
915
|
|
data/rust/Cargo.lock
CHANGED
|
@@ -262,9 +262,9 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
|
|
|
262
262
|
|
|
263
263
|
[[package]]
|
|
264
264
|
name = "cypher-parser"
|
|
265
|
-
version = "0.
|
|
265
|
+
version = "0.8.1"
|
|
266
266
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
267
|
-
checksum = "
|
|
267
|
+
checksum = "6ada60f869dbe5818d0ee40b06ad988627cc0d692d1ed42d692353bf0af8ddb6"
|
|
268
268
|
|
|
269
269
|
[[package]]
|
|
270
270
|
name = "difflib"
|
data/rust/rubydex/Cargo.toml
CHANGED
|
@@ -3,6 +3,7 @@ mod imp {
|
|
|
3
3
|
use std::time::Instant;
|
|
4
4
|
|
|
5
5
|
use rubydex::{
|
|
6
|
+
config::Config,
|
|
6
7
|
indexing::{self, IndexerBackend},
|
|
7
8
|
listing,
|
|
8
9
|
model::graph::Graph,
|
|
@@ -27,11 +28,8 @@ mod imp {
|
|
|
27
28
|
assert!(workspace_path.is_dir(), "the workspace path must be a directory");
|
|
28
29
|
|
|
29
30
|
let mut graph = Graph::new();
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
if let Err(error) = graph.load_config(None) {
|
|
33
|
-
eprintln!("{error}");
|
|
34
|
-
}
|
|
31
|
+
let config = Config::load(&workspace_path).expect("the workspace configuration must be valid");
|
|
32
|
+
graph.load_config(&config);
|
|
35
33
|
|
|
36
34
|
let time = Instant::now();
|
|
37
35
|
|