rbs-patch 0.1.4 → 0.1.7

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: ef229a0a3efd1a66cdc57652ef80b173d19311652f376422a06bad6d61d3c7b5
4
- data.tar.gz: 364bff243f157949a91b88c936a953e88cf275589312c664df1a9f6cc2d89c40
3
+ metadata.gz: 84022bf98bc54075dedb17f137e45f0a1f7571146987d4efc899fe65a4c71d46
4
+ data.tar.gz: 6743bda0891b9fee83b1dcd39b795d69cda6d75f6a47a342e4c4c6819affd900
5
5
  SHA512:
6
- metadata.gz: ad22a7fbeff8115b185977f5d21bfdbd51b53485f1e1896dc0e692fccbf6e8de82b90f499e3702343dbb579798cbe86b4ad871926aa8089763d4e1599d9c29e2
7
- data.tar.gz: 2850321317aa8b97317f315b4dce55af70330c724cd279dadbd5f8b0c8f9edc3e4305dbfaeca0aa85365123caa1772b4bb7137487df4b7fbf6c9b6d9ab66c7aa
6
+ metadata.gz: f1280e5b1e1cce06a9af9ca899d95c8896d5c14f21c0e0e46e5ac59b09795da27f78b425efe5cff1900f566612883851f48e78696eaf9d3fb3dc93ea2fde7866
7
+ data.tar.gz: 35be3d68b8dcdc4ab10ac4999adf87e1b17662d68f583c9084cbf1ead2325da84ca0ebc7825430d5939722dcf72c29e12da8ba8076ddf4af1b7de81920800e62
data/README.md CHANGED
@@ -143,6 +143,45 @@ class Guest
143
143
  end # Inserts Guest class before User class
144
144
  ```
145
145
 
146
+ ### Comment Handling in `override`
147
+
148
+ When `override` replaces a method, class, or module, the comment on the two sides is merged rather than always taken from one side:
149
+
150
+ - If the overriding declaration has a comment, it replaces the original comment.
151
+ - If the overriding declaration has no comment, the original comment (if any) is kept.
152
+
153
+ ```ruby
154
+ p.apply(<<~RBS)
155
+ class User
156
+ # The user's display name.
157
+ def name: () -> String
158
+ end
159
+ RBS
160
+
161
+ p.apply(<<~RBS)
162
+ class User
163
+ %a{patch:override}
164
+ def name: () -> String? # No comment here, so the original one is kept
165
+ end
166
+ RBS
167
+
168
+ # Result:
169
+ # class User
170
+ # # The user's display name.
171
+ # def name: () -> String?
172
+ # end
173
+ ```
174
+
175
+ There is currently no way to explicitly clear an existing comment through `override` — omitting the comment always keeps the original one.
176
+
177
+ > **Note:** In RBS syntax, a comment must be written *before* the annotation, not after it:
178
+ >
179
+ > ```ruby
180
+ > # This comment is attached to the method
181
+ > %a{patch:override}
182
+ > def name: () -> String?
183
+ > ```
184
+
146
185
  ### Working with Nested Modules
147
186
 
148
187
  Operations work correctly within nested module structures:
data/Steepfile CHANGED
@@ -5,4 +5,5 @@ target :lib do
5
5
 
6
6
  check "lib"
7
7
  library "rbs"
8
+ library "prism"
8
9
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RBS
4
4
  class Patch
5
- VERSION = "0.1.4"
5
+ VERSION = "0.1.7"
6
6
  end
7
7
  end
data/lib/rbs/patch.rb CHANGED
@@ -6,15 +6,21 @@ require_relative "patch/version"
6
6
 
7
7
  module RBS
8
8
  class Patch # rubocop:disable Style/Documentation
9
+ # @rbs! type t = ::RBS::AST::Declarations::t | ::RBS::AST::Members::t
10
+
9
11
  ANNOTATION_OVERRIDE = "patch:override"
10
12
  ANNOTATION_DELETE = "patch:delete"
11
13
  ANNOTATION_APPEND_AFTER = /\Apatch:append_after\((.*)\)\Z/
12
14
  ANNOTATION_PREPEND_BEFORE = /\Apatch:prepend_before\((.*)\)\Z/
13
15
 
16
+ # @rbs @decls: Array[::RBS::AST::Declarations::t]
17
+
18
+ #: -> void
14
19
  def initialize
15
20
  @decls = []
16
21
  end
17
22
 
23
+ #: -> String
18
24
  def to_s
19
25
  io = ::StringIO.new
20
26
  ::RBS::Writer.new(out: io).write(@decls)
@@ -22,6 +28,7 @@ module RBS
22
28
  io.read || ""
23
29
  end
24
30
 
31
+ #: (?untyped? String, ?path: Pathname?) -> void
25
32
  def apply(source = nil, path: nil)
26
33
  unless path.nil?
27
34
  files = Set[]
@@ -55,6 +62,7 @@ module RBS
55
62
 
56
63
  private
57
64
 
65
+ #: (t decl) -> String
58
66
  def extract_name(decl)
59
67
  if decl.is_a?(::RBS::AST::Declarations::AliasDecl) # rubocop:disable Style/CaseLikeIf
60
68
  decl.new_name.to_s
@@ -70,10 +78,51 @@ module RBS
70
78
  end
71
79
  end
72
80
 
81
+ #: (t decl) -> (Array[AST::Declarations::Class::member] | Array[AST::Declarations::Module::member] | nil)
73
82
  def extract_members(decl)
74
83
  decl.members if decl.is_a?(::RBS::AST::Declarations::NestedDeclarationHelper)
75
84
  end
76
85
 
86
+ #: (t decl, ?location: untyped, ?comment: untyped) -> t
87
+ def update(decl, location: decl.location, comment: nil)
88
+ if decl.is_a?(AST::Declarations::Constant) # rubocop:disable Style/CaseLikeIf
89
+ AST::Declarations::Constant.new(
90
+ name: decl.name, type: decl.type, location: location, comment: comment || decl.comment,
91
+ annotations: decl.annotations
92
+ )
93
+ elsif decl.is_a?(AST::Declarations::Global)
94
+ AST::Declarations::Global.new(
95
+ name: decl.name, type: decl.type, location: location, comment: comment || decl.comment,
96
+ annotations: decl.annotations
97
+ )
98
+ elsif decl.is_a?(AST::Declarations::TypeAlias)
99
+ AST::Declarations::TypeAlias.new(
100
+ name: decl.name, type_params: decl.type_params, type: decl.type, annotations: decl.annotations,
101
+ location: location, comment: comment || decl.comment
102
+ )
103
+ elsif decl.is_a?(AST::Declarations::AliasDecl)
104
+ decl.class.new(
105
+ new_name: decl.new_name, old_name: decl.old_name, location: location, comment: comment || decl.comment,
106
+ annotations: decl.annotations
107
+ )
108
+ elsif decl.is_a?(AST::Members::Mixin)
109
+ decl.class.new(
110
+ name: decl.name, args: decl.args, annotations: decl.annotations, location: location,
111
+ comment: comment || decl.comment
112
+ )
113
+ elsif decl.is_a?(AST::Members::Alias)
114
+ decl.class.new(
115
+ new_name: decl.new_name, old_name: decl.old_name, kind: decl.kind, annotations: decl.annotations,
116
+ location: location, comment: comment || decl.comment
117
+ )
118
+ elsif decl.is_a?(AST::Members::Var) || decl.is_a?(AST::Members::LocationOnly)
119
+ decl
120
+ else
121
+ decl.update(location: location, comment: comment || decl.comment)
122
+ end
123
+ end
124
+
125
+ #: (Array[t] decls, ?Array[String] name_stack) { (t, String) -> void } -> void
77
126
  def walk(decls, name_stack = [], &block)
78
127
  decls.each do |decl|
79
128
  name_stack << extract_name(decl)
@@ -88,6 +137,7 @@ module RBS
88
137
  end
89
138
  end
90
139
 
140
+ #: () -> Hash[String, t]
91
141
  def decl_map
92
142
  # @type var map: Hash[String, ::RBS::Patch::t]
93
143
  map = {}
@@ -95,6 +145,7 @@ module RBS
95
145
  map
96
146
  end
97
147
 
148
+ #: (t decl, to: String, ?after: String?, ?before: String?) -> void
98
149
  def add(decl, to:, after: nil, before: nil)
99
150
  map = decl_map
100
151
  return if map.key?(to)
@@ -104,36 +155,56 @@ module RBS
104
155
 
105
156
  target = namespace.empty? ? @decls : extract_members(map[namespace])
106
157
 
107
- if target
158
+ unless target
159
+ @decls << decl if decl.is_a?(AST::Declarations::Base)
160
+ return
161
+ end
162
+
163
+ if decl.is_a?(AST::Members::Var)
164
+ # AST::Members::Var does not support annotations.
165
+ index = target.rindex { |m| m.is_a?(decl.class) }
166
+ if index
167
+ decl = update(decl, location: target[index].location.dup)
168
+ target.insert(index + 1, decl)
169
+ else
170
+ index = target.find_index { |m| m.is_a?(AST::Members::MethodDefinition) }
171
+ if index
172
+ decl = update(decl, location: target[index].location.dup)
173
+ target.insert(index, decl)
174
+ else
175
+ target << decl
176
+ end
177
+ end
178
+ else
108
179
  decl.annotations.delete_if { |a| process_annotations([a]) } # steep:ignore
109
180
  if after
110
181
  index = target.find_index { |m| extract_name(m) == after }
111
- if index
112
- # steep:ignore:start
113
- decl = decl.update(location: target[index].location.dup) if decl.respond_to?(:update) # rubocop:disable Style/RedundantSelfAssignment
114
- # steep:ignore:end
115
- target.insert(index + 1, decl)
116
- end
182
+ return unless index
183
+
184
+ decl = update(decl, location: target[index].location.dup)
185
+ target.insert(index + 1, decl)
117
186
  elsif before
118
187
  index = target.find_index { |m| extract_name(m) == before }
119
- if index
120
- # steep:ignore:start
121
- decl = decl.update(location: target[index].location.dup) if decl.respond_to?(:update) # rubocop:disable Style/RedundantSelfAssignment
122
- # steep:ignore:end
123
- target.insert(index, decl)
124
- end
188
+ return unless index
189
+
190
+ decl = update(decl, location: target[index].location.dup)
191
+ target.insert(index, decl)
125
192
  else
126
193
  target << decl
127
194
  end
128
- else
129
- @decls << decl # steep:ignore
130
195
  end
131
196
  end
132
197
 
198
+ #: (String name, with: t) -> void
133
199
  def override(name, with:)
134
200
  map = decl_map
135
201
  return unless map.key?(name)
136
202
 
203
+ old = map[name]
204
+ # No way to explicitly clear a comment via override: an override without a
205
+ # comment always keeps the overridden one. Revisit if that's ever needed.
206
+ with = update(with, comment: old.comment) if with.comment.nil? && old.comment # steep:ignore
207
+
137
208
  sep = with.is_a?(::RBS::AST::Members::Base) ? "#" : "::"
138
209
  namespace, _, name = name.rpartition(sep)
139
210
 
@@ -151,6 +222,7 @@ module RBS
151
222
  with.annotations.delete_if { |a| process_annotations([a]) } # steep:ignore
152
223
  end
153
224
 
225
+ #: (String name) -> void
154
226
  def delete(name)
155
227
  map = decl_map
156
228
  return unless map.key?(name)
@@ -166,6 +238,11 @@ module RBS
166
238
  end
167
239
  end
168
240
 
241
+ # @rbs (Array[AST::Annotation] annotations) -> ([:override, nil]
242
+ # | [:delte, nil]
243
+ # | [:append_after, String]
244
+ # | [:prepend_before, String]
245
+ # | nil)
169
246
  def process_annotations(annotations) # steep:ignore
170
247
  if annotations.any? { |a| a.string == ANNOTATION_OVERRIDE }
171
248
  [:override, nil]
@@ -0,0 +1,59 @@
1
+ # Generated from lib/rbs/patch.rb with RBS::Inline
2
+
3
+ module RBS
4
+ class Patch
5
+ type t = ::RBS::AST::Declarations::t | ::RBS::AST::Members::t
6
+
7
+ ANNOTATION_OVERRIDE: ::String
8
+
9
+ ANNOTATION_DELETE: ::String
10
+
11
+ ANNOTATION_APPEND_AFTER: ::Regexp
12
+
13
+ ANNOTATION_PREPEND_BEFORE: ::Regexp
14
+
15
+ @decls: Array[::RBS::AST::Declarations::t]
16
+
17
+ # : -> void
18
+ def initialize: () -> void
19
+
20
+ # : -> String
21
+ def to_s: () -> String
22
+
23
+ # : (?untyped? String, ?path: Pathname?) -> void
24
+ def apply: (?untyped? String, ?path: Pathname?) -> void
25
+
26
+ private
27
+
28
+ # : (t decl) -> String
29
+ def extract_name: (t decl) -> String
30
+
31
+ # : (t decl) -> (Array[AST::Declarations::Class::member] | Array[AST::Declarations::Module::member] | nil)
32
+ def extract_members: (t decl) -> (Array[AST::Declarations::Class::member] | Array[AST::Declarations::Module::member] | nil)
33
+
34
+ # : (t decl, ?location: untyped, ?comment: untyped) -> t
35
+ def update: (t decl, ?location: untyped, ?comment: untyped) -> t
36
+
37
+ # : (Array[t] decls, ?Array[String] name_stack) { (t, String) -> void } -> void
38
+ def walk: (Array[t] decls, ?Array[String] name_stack) { (t, String) -> void } -> void
39
+
40
+ # : () -> Hash[String, t]
41
+ def decl_map: () -> Hash[String, t]
42
+
43
+ # : (t decl, to: String, ?after: String?, ?before: String?) -> void
44
+ def add: (t decl, to: String, ?after: String?, ?before: String?) -> void
45
+
46
+ # : (String name, with: t) -> void
47
+ def override: (String name, with: t) -> void
48
+
49
+ # : (String name) -> void
50
+ def delete: (String name) -> void
51
+
52
+ # @rbs (Array[AST::Annotation] annotations) -> ([:override, nil]
53
+ # | [:delte, nil]
54
+ # | [:append_after, String]
55
+ # | [:prepend_before, String]
56
+ # | nil)
57
+ def process_annotations: (Array[AST::Annotation] annotations) -> ([ :override, nil ] | [ :delte, nil ] | [ :append_after, String ] | [ :prepend_before, String ] | nil)
58
+ end
59
+ end
data/sig/rbs/patch.rbs CHANGED
@@ -1,41 +1,5 @@
1
1
  module RBS
2
2
  class Patch
3
3
  VERSION: String
4
-
5
- @decls: ::Array[::RBS::AST::Declarations::t]
6
-
7
- ANNOTATION_OVERRIDE: "patch:override"
8
-
9
- ANNOTATION_DELETE: "patch:delete"
10
-
11
- ANNOTATION_APPEND_AFTER: ::Regexp
12
-
13
- ANNOTATION_PREPEND_BEFORE: ::Regexp
14
-
15
- def initialize: () -> void
16
-
17
- def to_s: () -> String
18
-
19
- def apply: (?untyped? String, ?path: Pathname?) -> void
20
-
21
- type t = ::RBS::AST::Declarations::t | ::RBS::AST::Members::t
22
-
23
- private
24
-
25
- def extract_name: (t decl) -> String
26
-
27
- def extract_members: (t decl) -> (Array[::RBS::AST::Declarations::Class::member] | Array[::RBS::AST::Declarations::Module::member] | nil)
28
-
29
- def walk: (Array[t] decls, ?Array[String] name_stack) { (::RBS::AST::Declarations::t | ::RBS::AST::Members::t, String) -> void } -> void
30
-
31
- def decl_map: () -> Hash[String, t]
32
-
33
- def add: (t decl, to: String, ?after: String?, ?before: String?) -> void
34
-
35
- def override: (String name, with: t) -> void
36
-
37
- def delete: (String name) -> void
38
-
39
- def process_annotations: (Array[::RBS::AST::Annotation] annotations) -> ([:override, nil] | [:delte, nil] | [:append_after, String] | [:prepend_before, String] | nil)
40
4
  end
41
5
  end
@@ -0,0 +1,6 @@
1
+ {
2
+ "typeprof_version": "experimental",
3
+ "rbs_dir": "sig/",
4
+ "analysis_unit_dirs": ["lib"]
5
+ // "diagnostic_severity": "warning"
6
+ }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbs-patch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Koji NAKAMURA
@@ -13,16 +13,16 @@ dependencies:
13
13
  name: rbs
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
- - - "~>"
16
+ - - ">="
17
17
  - !ruby/object:Gem::Version
18
- version: '3.0'
18
+ version: '0'
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
- - - "~>"
23
+ - - ">="
24
24
  - !ruby/object:Gem::Version
25
- version: '3.0'
25
+ version: '0'
26
26
  description: RBS::Patch manages RBS (Ruby Signature) type definitions through patches.
27
27
  It applies incremental changes to existing RBS signatures.
28
28
  email:
@@ -39,7 +39,9 @@ files:
39
39
  - exe/rbs-patch
40
40
  - lib/rbs/patch.rb
41
41
  - lib/rbs/patch/version.rb
42
+ - sig/generated/rbs/patch.rbs
42
43
  - sig/rbs/patch.rbs
44
+ - typeprof.conf.jsonc
43
45
  homepage: https://github.com/kozy4324/rbs-patch
44
46
  licenses:
45
47
  - MIT
@@ -63,7 +65,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
63
65
  - !ruby/object:Gem::Version
64
66
  version: '0'
65
67
  requirements: []
66
- rubygems_version: 4.0.3
68
+ rubygems_version: 4.0.14
67
69
  specification_version: 4
68
70
  summary: RBS::Patch manages RBS type definitions through patches.
69
71
  test_files: []