rbi 0.0.6 → 0.0.10
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/Gemfile +2 -1
- data/lib/rbi/index.rb +32 -5
- data/lib/rbi/model.rb +140 -3
- data/lib/rbi/parser.rb +112 -49
- data/lib/rbi/printer.rb +194 -83
- data/lib/rbi/rewriters/annotate.rb +57 -0
- data/lib/rbi/rewriters/deannotate.rb +45 -0
- data/lib/rbi/rewriters/group_nodes.rb +12 -0
- data/lib/rbi/rewriters/merge_trees.rb +39 -8
- data/lib/rbi/rewriters/remove_known_definitions.rb +143 -0
- data/lib/rbi/rewriters/sort_nodes.rb +45 -19
- data/lib/rbi/version.rb +1 -1
- data/lib/rbi.rb +3 -0
- metadata +5 -2
@@ -0,0 +1,143 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module RBI
|
5
|
+
module Rewriters
|
6
|
+
# Remove all definitions existing in the index from the current tree
|
7
|
+
#
|
8
|
+
# Let's create an `Index` from two different `Tree`s:
|
9
|
+
# ~~~rb
|
10
|
+
# tree1 = Parse.parse_string(<<~RBI)
|
11
|
+
# class Foo
|
12
|
+
# def foo; end
|
13
|
+
# end
|
14
|
+
# RBI
|
15
|
+
#
|
16
|
+
# tree2 = Parse.parse_string(<<~RBI)
|
17
|
+
# FOO = 10
|
18
|
+
# RBI
|
19
|
+
#
|
20
|
+
# index = Index.index(tree1, tree2)
|
21
|
+
# ~~~
|
22
|
+
#
|
23
|
+
# We can use `RemoveKnownDefinitions` to remove the definitions found in the `index` from the `Tree` to clean:
|
24
|
+
# ~~~rb
|
25
|
+
# tree_to_clean = Parser.parse_string(<<~RBI)
|
26
|
+
# class Foo
|
27
|
+
# def foo; end
|
28
|
+
# def bar; end
|
29
|
+
# end
|
30
|
+
# FOO = 10
|
31
|
+
# BAR = 42
|
32
|
+
# RBI
|
33
|
+
#
|
34
|
+
# cleaned_tree, operations = RemoveKnownDefinitions.remove(tree_to_clean, index)
|
35
|
+
#
|
36
|
+
# assert_equal(<<~RBI, cleaned_tree)
|
37
|
+
# class Foo
|
38
|
+
# def bar; end
|
39
|
+
# end
|
40
|
+
# BAR = 42
|
41
|
+
# RBI
|
42
|
+
#
|
43
|
+
# assert_equal(<<~OPERATIONS, operations.join("\n"))
|
44
|
+
# Deleted ::Foo#foo at -:2:2-2-16 (duplicate from -:2:2-2:16)
|
45
|
+
# Deleted ::FOO at -:5:0-5:8 (duplicate from -:1:0-1:8)
|
46
|
+
# OPERATIONS
|
47
|
+
# ~~~
|
48
|
+
class RemoveKnownDefinitions < Visitor
|
49
|
+
extend T::Sig
|
50
|
+
|
51
|
+
sig do
|
52
|
+
params(
|
53
|
+
tree: Tree,
|
54
|
+
index: Index
|
55
|
+
).returns([Tree, T::Array[Operation]])
|
56
|
+
end
|
57
|
+
def self.remove(tree, index)
|
58
|
+
v = RemoveKnownDefinitions.new(index)
|
59
|
+
v.visit(tree)
|
60
|
+
[tree, v.operations]
|
61
|
+
end
|
62
|
+
|
63
|
+
sig { returns(T::Array[Operation]) }
|
64
|
+
attr_reader :operations
|
65
|
+
|
66
|
+
sig { params(index: Index).void }
|
67
|
+
def initialize(index)
|
68
|
+
super()
|
69
|
+
@index = index
|
70
|
+
@operations = T.let([], T::Array[Operation])
|
71
|
+
end
|
72
|
+
|
73
|
+
sig { params(nodes: T::Array[Node]).void }
|
74
|
+
def visit_all(nodes)
|
75
|
+
nodes.dup.each { |node| visit(node) }
|
76
|
+
end
|
77
|
+
|
78
|
+
sig { override.params(node: T.nilable(Node)).void }
|
79
|
+
def visit(node)
|
80
|
+
return unless node
|
81
|
+
|
82
|
+
case node
|
83
|
+
when Scope
|
84
|
+
visit_all(node.nodes)
|
85
|
+
previous = previous_definition_for(node)
|
86
|
+
delete_node(node, previous) if previous && can_delete_node?(node, previous)
|
87
|
+
when Tree
|
88
|
+
visit_all(node.nodes)
|
89
|
+
when Indexable
|
90
|
+
previous = previous_definition_for(node)
|
91
|
+
delete_node(node, previous) if previous && can_delete_node?(node, previous)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
private
|
96
|
+
|
97
|
+
sig { params(node: Indexable).returns(T.nilable(Node)) }
|
98
|
+
def previous_definition_for(node)
|
99
|
+
node.index_ids.each do |id|
|
100
|
+
previous = @index[id].first
|
101
|
+
return previous if previous
|
102
|
+
end
|
103
|
+
nil
|
104
|
+
end
|
105
|
+
|
106
|
+
sig { params(node: Node, previous: Node).returns(T::Boolean) }
|
107
|
+
def can_delete_node?(node, previous)
|
108
|
+
return false unless node.class == previous.class
|
109
|
+
|
110
|
+
case node
|
111
|
+
when Scope
|
112
|
+
node.empty?
|
113
|
+
when Attr
|
114
|
+
previous = T.cast(previous, Attr)
|
115
|
+
node.names == previous.names && node.sigs == previous.sigs
|
116
|
+
when Method
|
117
|
+
previous = T.cast(previous, Method)
|
118
|
+
node.params == previous.params && node.sigs == previous.sigs
|
119
|
+
else
|
120
|
+
true
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
sig { params(node: Node, previous: Node).void }
|
125
|
+
def delete_node(node, previous)
|
126
|
+
node.detach
|
127
|
+
@operations << Operation.new(deleted_node: node, duplicate_of: previous)
|
128
|
+
end
|
129
|
+
|
130
|
+
class Operation < T::Struct
|
131
|
+
extend T::Sig
|
132
|
+
|
133
|
+
const :deleted_node, Node
|
134
|
+
const :duplicate_of, Node
|
135
|
+
|
136
|
+
sig { returns(String) }
|
137
|
+
def to_s
|
138
|
+
"Deleted #{duplicate_of} at #{deleted_node.loc} (duplicate from #{duplicate_of.loc})"
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
@@ -8,14 +8,22 @@ module RBI
|
|
8
8
|
|
9
9
|
sig { override.params(node: T.nilable(Node)).void }
|
10
10
|
def visit(node)
|
11
|
+
sort_node_names!(node) if node
|
12
|
+
|
11
13
|
return unless node.is_a?(Tree)
|
12
14
|
visit_all(node.nodes)
|
13
15
|
original_order = node.nodes.map.with_index.to_h
|
14
16
|
node.nodes.sort! do |a, b|
|
17
|
+
# First we try to compare the nodes by their node rank (based on the node type)
|
15
18
|
res = node_rank(a) <=> node_rank(b)
|
16
|
-
res
|
17
|
-
|
18
|
-
res
|
19
|
+
next res if res != 0 # we can sort the nodes by their rank, let's stop here
|
20
|
+
|
21
|
+
# Then, if the nodes ranks are the same (res == 0), we try to compare the nodes by their name
|
22
|
+
res = node_name(a) <=> node_name(b)
|
23
|
+
next res if res && res != 0 # we can sort the nodes by their name, let's stop here
|
24
|
+
|
25
|
+
# Finally, if the two nodes have the same rank and the same name or at least one node is anonymous then,
|
26
|
+
T.must(original_order[a]) <=> T.must(original_order[b]) # we keep the original order
|
19
27
|
end
|
20
28
|
end
|
21
29
|
|
@@ -26,22 +34,26 @@ module RBI
|
|
26
34
|
case node
|
27
35
|
when Group then group_rank(node.kind)
|
28
36
|
when Include, Extend then 10
|
37
|
+
when RequiresAncestor then 15
|
29
38
|
when Helper then 20
|
30
39
|
when TypeMember then 30
|
31
40
|
when MixesInClassMethods then 40
|
32
|
-
when
|
33
|
-
when
|
41
|
+
when Send then 50
|
42
|
+
when TStructField then 60
|
43
|
+
when TEnumBlock then 70
|
44
|
+
when Attr then 75
|
34
45
|
when Method
|
35
46
|
if node.name == "initialize"
|
36
|
-
|
47
|
+
81
|
37
48
|
elsif !node.is_singleton
|
38
|
-
|
49
|
+
82
|
39
50
|
else
|
40
|
-
|
51
|
+
83
|
41
52
|
end
|
42
|
-
when
|
53
|
+
when SingletonClass then 90
|
54
|
+
when Scope, Const then 100
|
43
55
|
else
|
44
|
-
|
56
|
+
110
|
45
57
|
end
|
46
58
|
end
|
47
59
|
|
@@ -49,14 +61,18 @@ module RBI
|
|
49
61
|
def group_rank(kind)
|
50
62
|
case kind
|
51
63
|
when Group::Kind::Mixins then 0
|
52
|
-
when Group::Kind::
|
53
|
-
when Group::Kind::
|
54
|
-
when Group::Kind::
|
55
|
-
when Group::Kind::
|
56
|
-
when Group::Kind::
|
57
|
-
when Group::Kind::
|
58
|
-
when Group::Kind::
|
59
|
-
when Group::Kind::
|
64
|
+
when Group::Kind::RequiredAncestors then 1
|
65
|
+
when Group::Kind::Helpers then 2
|
66
|
+
when Group::Kind::TypeMembers then 3
|
67
|
+
when Group::Kind::MixesInClassMethods then 4
|
68
|
+
when Group::Kind::Sends then 5
|
69
|
+
when Group::Kind::TStructFields then 6
|
70
|
+
when Group::Kind::TEnums then 7
|
71
|
+
when Group::Kind::Attrs then 8
|
72
|
+
when Group::Kind::Inits then 9
|
73
|
+
when Group::Kind::Methods then 10
|
74
|
+
when Group::Kind::SingletonClasses then 11
|
75
|
+
when Group::Kind::Consts then 12
|
60
76
|
else
|
61
77
|
T.absurd(kind)
|
62
78
|
end
|
@@ -65,8 +81,18 @@ module RBI
|
|
65
81
|
sig { params(node: Node).returns(T.nilable(String)) }
|
66
82
|
def node_name(node)
|
67
83
|
case node
|
68
|
-
when Module, Class, Struct, Const, Method, Helper, TStructField
|
84
|
+
when Module, Class, Struct, Const, Method, Helper, TStructField, RequiresAncestor
|
69
85
|
node.name
|
86
|
+
when Attr
|
87
|
+
node.names.first.to_s
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
sig { params(node: Node).void }
|
92
|
+
def sort_node_names!(node)
|
93
|
+
case node
|
94
|
+
when Attr
|
95
|
+
node.names.sort!
|
70
96
|
end
|
71
97
|
end
|
72
98
|
end
|
data/lib/rbi/version.rb
CHANGED
data/lib/rbi.rb
CHANGED
@@ -13,10 +13,13 @@ require "rbi/model"
|
|
13
13
|
require "rbi/visitor"
|
14
14
|
require "rbi/index"
|
15
15
|
require "rbi/rewriters/add_sig_templates"
|
16
|
+
require "rbi/rewriters/annotate"
|
17
|
+
require "rbi/rewriters/deannotate"
|
16
18
|
require "rbi/rewriters/merge_trees"
|
17
19
|
require "rbi/rewriters/nest_singleton_methods"
|
18
20
|
require "rbi/rewriters/nest_non_public_methods"
|
19
21
|
require "rbi/rewriters/group_nodes"
|
22
|
+
require "rbi/rewriters/remove_known_definitions"
|
20
23
|
require "rbi/rewriters/sort_nodes"
|
21
24
|
require "rbi/parser"
|
22
25
|
require "rbi/printer"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexandre Terrasa
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ast
|
@@ -83,10 +83,13 @@ files:
|
|
83
83
|
- lib/rbi/parser.rb
|
84
84
|
- lib/rbi/printer.rb
|
85
85
|
- lib/rbi/rewriters/add_sig_templates.rb
|
86
|
+
- lib/rbi/rewriters/annotate.rb
|
87
|
+
- lib/rbi/rewriters/deannotate.rb
|
86
88
|
- lib/rbi/rewriters/group_nodes.rb
|
87
89
|
- lib/rbi/rewriters/merge_trees.rb
|
88
90
|
- lib/rbi/rewriters/nest_non_public_methods.rb
|
89
91
|
- lib/rbi/rewriters/nest_singleton_methods.rb
|
92
|
+
- lib/rbi/rewriters/remove_known_definitions.rb
|
90
93
|
- lib/rbi/rewriters/sort_nodes.rb
|
91
94
|
- lib/rbi/version.rb
|
92
95
|
- lib/rbi/visitor.rb
|