rbs-patch 0.1.2 → 0.1.3
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/Rakefile +7 -1
- data/Steepfile +8 -0
- data/exe/rbs-patch +2 -0
- data/lib/rbs/patch/version.rb +1 -1
- data/lib/rbs/patch.rb +128 -64
- data/sig/rbs/patch.rbs +27 -3
- metadata +6 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3a45288c145d3c26618712866de56ebeebabc1034e29960877834d5fc0518c58
|
|
4
|
+
data.tar.gz: 12ae5d9f8fcd5721f05bac232b9dd10b8de6a23c47c73eba19801e65b3b33143
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b939dc31112ba51d86e88c66b0000ac3abcf7baa9d5b57db79af3ee8003dc2cafbb90e2d6c4d08ffb53c3aebd8bb3c1d2b1bec7609911d03f7ed12105621a2b4
|
|
7
|
+
data.tar.gz: '00998b3ec8d70b87cf45177244ed9dc0e8bdb572f95eb33e07f422a137a67922a6add9ddb06a00777de1eb00aa69eb787930b2e6b33704b890064e4c1b2683c5'
|
data/Rakefile
CHANGED
data/Steepfile
ADDED
data/exe/rbs-patch
CHANGED
data/lib/rbs/patch/version.rb
CHANGED
data/lib/rbs/patch.rb
CHANGED
|
@@ -12,7 +12,14 @@ module RBS
|
|
|
12
12
|
ANNOTATION_PREPEND_BEFORE = /\Apatch:prepend_before:(.*)\Z/
|
|
13
13
|
|
|
14
14
|
def initialize
|
|
15
|
-
@
|
|
15
|
+
@decls = []
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def to_s
|
|
19
|
+
io = ::StringIO.new
|
|
20
|
+
::RBS::Writer.new(out: io).write(@decls)
|
|
21
|
+
io.rewind
|
|
22
|
+
io.read || ""
|
|
16
23
|
end
|
|
17
24
|
|
|
18
25
|
def apply(source = nil, path: nil)
|
|
@@ -22,83 +29,140 @@ module RBS
|
|
|
22
29
|
next if files.include?(path)
|
|
23
30
|
|
|
24
31
|
files << path
|
|
25
|
-
apply Buffer.new(name: path, content: path.read(encoding: "UTF-8"))
|
|
32
|
+
apply ::RBS::Buffer.new(name: path, content: path.read(encoding: "UTF-8"))
|
|
26
33
|
end
|
|
27
34
|
return
|
|
28
35
|
end
|
|
29
36
|
|
|
30
|
-
_,
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
next unless ope
|
|
46
|
-
|
|
47
|
-
case ope
|
|
48
|
-
when :override
|
|
49
|
-
index = decl_a.members.find_index { |member_a| member_a.name == member_b.name }
|
|
50
|
-
if index
|
|
51
|
-
decl_a.members[index] = decl_a.members[index].update(overloads: member_b.overloads)
|
|
52
|
-
true
|
|
53
|
-
else
|
|
54
|
-
false
|
|
55
|
-
end
|
|
56
|
-
when :delete
|
|
57
|
-
decl_a.members.reject! { |member_a| member_a.name == member_b.name }
|
|
58
|
-
when :append_after, :prepend_before
|
|
59
|
-
target_name = arg.to_sym
|
|
60
|
-
index = decl_a.members.find_index { |member_a| member_a.name == target_name }
|
|
61
|
-
if index
|
|
62
|
-
if ope == :append_after
|
|
63
|
-
offset = 1
|
|
64
|
-
annotations = member_b.annotations.reject { |a| a.string.match(ANNOTATION_APPEND_AFTER) }
|
|
65
|
-
else
|
|
66
|
-
offset = 0
|
|
67
|
-
annotations = member_b.annotations.reject { |a| a.string.match(ANNOTATION_PREPEND_BEFORE) }
|
|
68
|
-
end
|
|
69
|
-
decl_a.members.insert(index + offset, member_b.update(annotations:))
|
|
70
|
-
true
|
|
71
|
-
else
|
|
72
|
-
false
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
decl_a
|
|
37
|
+
_, _, decls = ::RBS::Parser.parse_signature(source)
|
|
38
|
+
walk(decls) do |decl, name|
|
|
39
|
+
ope, arg = process_annotations(decl.annotations) if decl.respond_to?(:annotations) # steep:ignore
|
|
40
|
+
|
|
41
|
+
case ope
|
|
42
|
+
when :override
|
|
43
|
+
override(name, with: decl)
|
|
44
|
+
when :delete
|
|
45
|
+
delete(name)
|
|
46
|
+
when :append_after
|
|
47
|
+
add(decl, to: name, after: arg)
|
|
48
|
+
when :prepend_before
|
|
49
|
+
add(decl, to: name, before: arg)
|
|
50
|
+
else
|
|
51
|
+
add(decl, to: name)
|
|
77
52
|
end
|
|
78
53
|
end
|
|
79
54
|
end
|
|
80
55
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
56
|
+
private
|
|
57
|
+
|
|
58
|
+
def walk(decls, name_stack = [], &block)
|
|
59
|
+
decls.each do |decl|
|
|
60
|
+
name = if decl.is_a?(::RBS::AST::Declarations::AliasDecl) # rubocop:disable Style/CaseLikeIf
|
|
61
|
+
decl.new_name.to_s
|
|
62
|
+
elsif decl.is_a?(::RBS::AST::Declarations::Base)
|
|
63
|
+
decl.name.to_s
|
|
64
|
+
elsif decl.is_a?(::RBS::AST::Members::LocationOnly)
|
|
65
|
+
""
|
|
66
|
+
elsif decl.is_a?(::RBS::AST::Members::Alias) # rubocop:disable Lint/DuplicateBranch
|
|
67
|
+
decl.new_name.to_s
|
|
68
|
+
else # rubocop:disable Lint/DuplicateBranch
|
|
69
|
+
# ::RBS::AST::Members::t
|
|
70
|
+
decl.name.to_s
|
|
71
|
+
end
|
|
72
|
+
name_stack << name
|
|
73
|
+
if decl.is_a?(::RBS::AST::Members::Base)
|
|
74
|
+
yield decl, "#{name_stack[..-2]&.join("::")}##{name_stack[-1]}"
|
|
75
|
+
else
|
|
76
|
+
yield decl, name_stack.join("::")
|
|
87
77
|
end
|
|
78
|
+
walk(decl.members, name_stack, &block) if decl.is_a?(::RBS::AST::Declarations::NestedDeclarationHelper)
|
|
79
|
+
name_stack.pop
|
|
88
80
|
end
|
|
81
|
+
end
|
|
89
82
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
83
|
+
def decl_map
|
|
84
|
+
# @type var map: Hash[String, ::RBS::Patch::t]
|
|
85
|
+
map = {}
|
|
86
|
+
walk(@decls) { |decl, name| map[name] = decl }
|
|
87
|
+
map
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def add(decl, to:, after: nil, before: nil)
|
|
91
|
+
map = decl_map
|
|
92
|
+
return if map.key?(to)
|
|
93
|
+
|
|
94
|
+
sep = decl.is_a?(::RBS::AST::Members::Base) ? "#" : "::"
|
|
95
|
+
namespace, = to.rpartition(sep)
|
|
96
|
+
|
|
97
|
+
target = namespace.empty? ? @decls : map[namespace]&.members # steep:ignore
|
|
98
|
+
|
|
99
|
+
# steep:ignore:start
|
|
100
|
+
if target
|
|
101
|
+
if after
|
|
102
|
+
index = target.find_index { |m| m.name.to_s == after }
|
|
103
|
+
target.insert(index + 1, decl) if index
|
|
104
|
+
elsif before
|
|
105
|
+
index = target.find_index { |m| m.name.to_s == before }
|
|
106
|
+
target.insert(index, decl) if index
|
|
107
|
+
else
|
|
108
|
+
target << decl
|
|
94
109
|
end
|
|
110
|
+
decl.annotations.delete_if { |a| process_annotations([a]) }
|
|
111
|
+
else
|
|
112
|
+
@decls << decl
|
|
95
113
|
end
|
|
96
|
-
|
|
114
|
+
# steep:ignore:end
|
|
115
|
+
end
|
|
97
116
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
117
|
+
def override(name, with:)
|
|
118
|
+
map = decl_map
|
|
119
|
+
return unless map.key?(name)
|
|
120
|
+
|
|
121
|
+
sep = with.is_a?(::RBS::AST::Members::Base) ? "#" : "::"
|
|
122
|
+
namespace, _, name = name.rpartition(sep)
|
|
123
|
+
|
|
124
|
+
# steep:ignore:start
|
|
125
|
+
if namespace.empty?
|
|
126
|
+
# top level decl
|
|
127
|
+
index = @decls.find_index { |d| d.name.to_s == name }
|
|
128
|
+
@decls[index] = with
|
|
129
|
+
else
|
|
130
|
+
index = map[namespace].members.find_index do |m|
|
|
131
|
+
m.name.to_s == name
|
|
132
|
+
end
|
|
133
|
+
map[namespace].members[index] = with
|
|
134
|
+
end
|
|
135
|
+
with.annotations.delete_if { |a| process_annotations([a]) }
|
|
136
|
+
# steep:ignore:end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def delete(name)
|
|
140
|
+
map = decl_map
|
|
141
|
+
return unless map.key?(name)
|
|
142
|
+
|
|
143
|
+
sep = name.index("#") ? "#" : "::"
|
|
144
|
+
namespace, _, name = name.rpartition(sep)
|
|
145
|
+
|
|
146
|
+
# steep:ignore:start
|
|
147
|
+
if namespace.empty?
|
|
148
|
+
# top level decl
|
|
149
|
+
@decls.delete_if { |d| d.name.to_s == name }
|
|
150
|
+
else
|
|
151
|
+
map[namespace].members.delete_if { |m| m.name.to_s == name }
|
|
152
|
+
end
|
|
153
|
+
# steep:ignore:end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def process_annotations(annotations) # steep:ignore
|
|
157
|
+
if annotations.any? { |a| a.string == ANNOTATION_OVERRIDE }
|
|
158
|
+
[:override, nil]
|
|
159
|
+
elsif annotations.any? { |a| a.string == ANNOTATION_DELETE }
|
|
160
|
+
[:delete, nil]
|
|
161
|
+
elsif (anno = annotations.find { |a| a.string.match(ANNOTATION_APPEND_AFTER) })
|
|
162
|
+
[:append_after, anno.string.match(ANNOTATION_APPEND_AFTER)&.[](1) || ""]
|
|
163
|
+
elsif (anno = annotations.find { |a| a.string.match(ANNOTATION_PREPEND_BEFORE) })
|
|
164
|
+
[:prepend_before, anno.string.match(ANNOTATION_PREPEND_BEFORE)&.[](1) || ""]
|
|
165
|
+
end
|
|
102
166
|
end
|
|
103
167
|
end
|
|
104
168
|
end
|
data/sig/rbs/patch.rbs
CHANGED
|
@@ -2,12 +2,36 @@ module RBS
|
|
|
2
2
|
class Patch
|
|
3
3
|
VERSION: String
|
|
4
4
|
|
|
5
|
-
@
|
|
5
|
+
@decls: ::Array[::RBS::AST::Declarations::t]
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
ANNOTATION_OVERRIDE: "patch:override"
|
|
8
|
+
|
|
9
|
+
ANNOTATION_DELETE: "patch:delete"
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
ANNOTATION_APPEND_AFTER: ::Regexp
|
|
12
|
+
|
|
13
|
+
ANNOTATION_PREPEND_BEFORE: ::Regexp
|
|
14
|
+
|
|
15
|
+
def initialize: () -> void
|
|
10
16
|
|
|
11
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 walk: (Array[t] decls, ?Array[String] name_stack) { (::RBS::AST::Declarations::t | ::RBS::AST::Members::t, String) -> void } -> void
|
|
26
|
+
|
|
27
|
+
def decl_map: () -> Hash[String, t]
|
|
28
|
+
|
|
29
|
+
def add: (t decl, to: String, ?after: String?, ?before: String?) -> void
|
|
30
|
+
|
|
31
|
+
def override: (String name, with: t) -> void
|
|
32
|
+
|
|
33
|
+
def delete: (String name) -> void
|
|
34
|
+
|
|
35
|
+
def process_annotations: (Array[::RBS::AST::Annotation] annotations) -> ([:override, nil] | [:delte, nil] | [:append_after, String] | [:prepend_before, String] | nil)
|
|
12
36
|
end
|
|
13
37
|
end
|
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
|
+
version: 0.1.3
|
|
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:
|
|
18
|
+
version: '3.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:
|
|
25
|
+
version: '3.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:
|
|
@@ -35,6 +35,7 @@ files:
|
|
|
35
35
|
- LICENSE.txt
|
|
36
36
|
- README.md
|
|
37
37
|
- Rakefile
|
|
38
|
+
- Steepfile
|
|
38
39
|
- exe/rbs-patch
|
|
39
40
|
- lib/rbs/patch.rb
|
|
40
41
|
- lib/rbs/patch/version.rb
|