rigortype 0.2.3 → 0.2.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 775a0b6e3050294352d505366428814ab73348d2ced5ccf45842644c38752155
4
- data.tar.gz: 7ec72c4aa56cbb43ae18dd3c1a029da3bb6746a604c4a3d72811b34b5d1c1439
3
+ metadata.gz: 749e0e15c9b85dcec97c9afc1b107d5ebc1a1a685cc19aa39d316a9826992d4a
4
+ data.tar.gz: 45bcee26284594e35b51a050ce8ac234935bee954063b50fdfe1b0c6a9bcddea
5
5
  SHA512:
6
- metadata.gz: cc0650acb783740184fb76f0c5382fefe3950bd84011c84ccd2e23a60ff703519de94a294b39e96e11198748b2539917fae117972be7366dd06725ee54975935
7
- data.tar.gz: d06b60ff922cfb4ab77ea680b5d624702a4f782b65c1dcb2e3f631793fe90cb4bb8302d50ac5a3656cbd1a1fe79e198cfee9c8641b037acf48906ae1aa63eeb8
6
+ metadata.gz: fbf022b6e92a96e1c095cb3d887936161e836201662f051c60de5d0d78494f263228a28df509c3b937768735b5ce18162ee28657b2aaf1cd7a8b2d4851338a53
7
+ data.tar.gz: a49e89a07950f54fcf8f38e328b8fdb658aaf0802154df457c7b9b1370f35279c1d6d5fe3acf6a45c9e49ff2f7c09ff9f209b1f7dab68d20b283c9baa4b2760b
@@ -47,6 +47,9 @@ module Rigor
47
47
  def initialize(path:, line:, column:, message:, severity: :error, rule: nil, # rubocop:disable Metrics/ParameterLists
48
48
  source_family: DEFAULT_SOURCE_FAMILY,
49
49
  receiver_type: nil, method_name: nil, project_definition_site: nil)
50
+ raise ArgumentError, "line must be >= 1, got #{line}" if line < 1
51
+ raise ArgumentError, "column must be >= 1, got #{column}" if column < 1
52
+
50
53
  @path = path
51
54
  @line = line
52
55
  @column = column
@@ -208,8 +208,14 @@ module Rigor
208
208
  ["rigor-rbs-setup", "your gems ship no community RBS yet — install it so Rigor stops typing them as Dynamic."]
209
209
  elsif state.fetch(:ci) != :wired
210
210
  ["rigor-ci-setup", "Rigor is configured but not wired into CI — lock in the regression guard."]
211
- elsif state.fetch(:baseline)
212
- ["rigor-baseline-reduce", "a baseline is in place work it down rule by rule."]
211
+ # A present baseline is deliberately NOT a recommendation trigger.
212
+ # A baseline is a healthy, finished onboarding state, not a problem to
213
+ # work off; pushing every baselined project to "reduce it" turns a
214
+ # working build into a chore and tempts scattering `# rigor:disable`
215
+ # through the code to make a number go down — means over ends.
216
+ # `rigor-baseline-reduce` stays in the catalogue for the intermediate
217
+ # user who *chooses* to invest in it; the headline routes to genuinely
218
+ # additive steps instead.
213
219
  elsif state.fetch(:editor) == :unwired
214
220
  ["rigor-editor-setup",
215
221
  "you have an editor config but no Rigor LSP — wire `rigor lsp` for live diagnostics and hover types."]
@@ -297,7 +303,6 @@ module Rigor
297
303
  The recommendation above is from a presence-only probe — it does not run
298
304
  `rigor check`. If you have run (or now run) `rigor check`, let its findings
299
305
  refine the choice:
300
- - errors present and no baseline yet → rigor-baseline-reduce
301
306
  - a `call.unresolved-toplevel` / `call.undefined-method` cluster on the
302
307
  project's own monkey-patches → rigor-monkeypatch-resolve
303
308
  - framework calls (ActiveRecord, routes, i18n …) typing as Dynamic with no
@@ -170,7 +170,7 @@ module Rigor
170
170
  source = missing.map { |name| "module #{name}\nend\n" }.join
171
171
  buffer = ::RBS::Buffer.new(name: SYNTHETIC_NAMESPACE_BUFFER, content: source)
172
172
  _, directives, decls = ::RBS::Parser.parse_signature(buffer)
173
- env.add_source(::RBS::Source::RBS.new(buffer, directives || [], decls || []))
173
+ add_parsed_decls(env, buffer, directives, decls)
174
174
  rescue ::RBS::BaseError
175
175
  # Fail-soft: synthesis is an opportunistic uplift, never a
176
176
  # hard requirement. A parse failure here just leaves the env
@@ -232,11 +232,52 @@ module Rigor
232
232
  missing.uniq
233
233
  end
234
234
 
235
+ # Normalises a `class_decls` entry's representative declaration
236
+ # across the gemspec's supported RBS range (`rbs >= 3.0, < 5.0`).
237
+ # RBS 4.x exposes it as `entry.primary_decl` (the AST declaration
238
+ # directly); RBS 3.x exposes `entry.primary` (a wrapper whose
239
+ # `#decl` is the AST declaration). Returns the AST declaration, or
240
+ # nil when neither accessor is present. Without this guard,
241
+ # `class_decl_paths` crashed under RBS 3.x with
242
+ # `undefined method 'primary_decl'`.
243
+ def primary_decl_for(entry)
244
+ if entry.respond_to?(:primary_decl)
245
+ entry.primary_decl
246
+ elsif entry.respond_to?(:primary)
247
+ primary = entry.primary
248
+ primary.respond_to?(:decl) ? primary.decl : primary
249
+ end
250
+ end
251
+
252
+ # Appends freshly-parsed declarations to an `RBS::Environment`
253
+ # across the gemspec's supported RBS range (`rbs >= 3.0, < 5.0`).
254
+ # RBS 4.x wraps the declarations in an `RBS::Source::RBS` and
255
+ # takes them through `env.add_source`; RBS 3.x has neither
256
+ # `RBS::Source` nor `add_source` and instead registers them with
257
+ # `env.add_signature(buffer:, directives:, decls:)` (a bare
258
+ # `env << decl` is NOT enough — it skips the `signatures` table
259
+ # that `resolve_type_names` rebuilds from, so the synthesized
260
+ # declarations silently vanish on resolve). Without this guard
261
+ # the synthesis paths (`synthesize_missing_namespaces`,
262
+ # `append_stub_declarations`, `add_virtual_rbs`) crashed under
263
+ # RBS 3.x with `uninitialized constant RBS::Source`.
264
+ def add_parsed_decls(env, buffer, directives, decls)
265
+ decls ||= []
266
+ directives ||= []
267
+ if env.respond_to?(:add_source)
268
+ env.add_source(::RBS::Source::RBS.new(buffer, directives, decls))
269
+ elsif env.respond_to?(:add_signature)
270
+ env.add_signature(buffer: buffer, directives: directives, decls: decls)
271
+ else
272
+ decls.each { |decl| env << decl }
273
+ end
274
+ end
275
+
235
276
  # True when a `class_decls` entry was declared in one of the
236
277
  # project's own signature files (by declaration location), so
237
278
  # the sweep skips the bundled stdlib / vendored universe.
238
279
  def project_entry?(entry, project_files)
239
- decl = entry.respond_to?(:primary_decl) ? entry.primary_decl : nil
280
+ decl = primary_decl_for(entry)
240
281
  location = decl&.location
241
282
  buffer_name = location&.buffer&.name
242
283
  return false unless buffer_name
@@ -262,7 +303,7 @@ module Rigor
262
303
  end.join
263
304
  buffer = ::RBS::Buffer.new(name: SYNTHETIC_STUB_BUFFER, content: source)
264
305
  _, directives, decls = ::RBS::Parser.parse_signature(buffer)
265
- base_env.add_source(::RBS::Source::RBS.new(buffer, directives || [], decls || []))
306
+ add_parsed_decls(base_env, buffer, directives, decls)
266
307
  rescue ::RBS::BaseError
267
308
  nil
268
309
  end
@@ -284,8 +325,7 @@ module Rigor
284
325
 
285
326
  buffer = ::RBS::Buffer.new(name: filename.to_s, content: content.to_s)
286
327
  _, directives, decls = ::RBS::Parser.parse_signature(buffer)
287
- source = ::RBS::Source::RBS.new(buffer, directives || [], decls || [])
288
- env.add_source(source)
328
+ add_parsed_decls(env, buffer, directives, decls)
289
329
  rescue ::RBS::BaseError
290
330
  # WD6 fail-soft: a single broken virtual RBS contribution
291
331
  # does not pull the whole env down. The plugin layer
@@ -589,7 +629,7 @@ module Rigor
589
629
 
590
630
  result = {}
591
631
  env.class_decls.each do |rbs_name, entry|
592
- decl = entry.primary_decl
632
+ decl = self.class.primary_decl_for(entry)
593
633
  next if decl.nil?
594
634
 
595
635
  location = decl.location
@@ -911,12 +951,17 @@ module Rigor
911
951
  end
912
952
 
913
953
  # Collects the AST declaration nodes behind a `class_decls`
914
- # entry. RBS 4's `ModuleEntry` / `ClassEntry` expose `each_decl`;
915
- # the older single-`decl` shape is handled defensively so the
916
- # loader survives an rbs-gem minor bump.
954
+ # entry across the supported RBS range (`rbs >= 3.0, < 5.0`).
955
+ # RBS 4's `ModuleEntry` / `ClassEntry` expose `each_decl` yielding
956
+ # bare AST declarations; RBS 3.x exposes `decls`, an array of
957
+ # `MultiEntry::D` wrappers whose `#decl` is the AST declaration.
958
+ # The single-`decl` shape is handled defensively so the loader
959
+ # survives an rbs-gem minor bump.
917
960
  def entry_declarations(entry)
918
961
  if entry.respond_to?(:each_decl)
919
962
  [].tap { |acc| entry.each_decl { |decl| acc << decl } }
963
+ elsif entry.respond_to?(:decls)
964
+ entry.decls.map { |d| d.respond_to?(:decl) ? d.decl : d }
920
965
  elsif entry.respond_to?(:decl)
921
966
  [entry.decl]
922
967
  else
data/lib/rigor/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rigor
4
- VERSION = "0.2.3"
4
+ VERSION = "0.2.4"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rigortype
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rigor contributors