rbi 0.0.1 → 0.0.5

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: a3ec679e5a50e9325d794c32a93ca12eb08aff102e12b21e6476a172b8001cba
4
- data.tar.gz: 5abffaaba601923ebe58dd49e5c59aba2faf41a73ee4571b15e157c5f220297f
3
+ metadata.gz: fb13c49bd19a95d439f7249770add05929979892daa3ba9c55de8241a596a8d2
4
+ data.tar.gz: bc772396cd7997b9443782775854993cb9e4b0d1241415020c258aa8f49186b2
5
5
  SHA512:
6
- metadata.gz: dfebab9782d4817841ec80c87d81ff9919df026de13614fe056bc4ca0cd9ab4546f861c230172023d8f3c185b60b1155e076c7ef22ef420421bd1203879f15b0
7
- data.tar.gz: bae1339fd94ad30d5d6997611b1ac14fc36d9119607a32f954ab2361112c5ec5c31181636409df223c190348477917cf2e27da3d2bae0551295836273e59fcbb
6
+ metadata.gz: 9990c9fd5fa2bc0925f06ce07f02079165f431e9535874d0204b0e2afbc6ad1919578e3ecd13a33b69ef575ec84911fadb34d3a71df917437fd46182bb07aa6e
7
+ data.tar.gz: 2818b3db38a03e58eb8bd6dd160ca50fac237242192620a6910dd73c451a3ee90e5dd483502e721870329724f0b4237899225d3c4e5f429b37abd667e0183c87
data/Gemfile CHANGED
@@ -5,9 +5,13 @@ source "https://rubygems.org"
5
5
 
6
6
  gemspec
7
7
 
8
- group(:development) do
9
- gem('rubocop-shopify', require: false)
10
- gem('rubocop-sorbet', require: false)
11
- gem('byebug')
12
- gem('pry-byebug')
8
+ group(:development, :test) do
9
+ gem("byebug")
10
+ gem("minitest")
11
+ gem("rake", "~> 13.0")
12
+ gem("rubocop", "~> 1.7", require: false)
13
+ gem("rubocop-shopify", require: false)
14
+ gem("rubocop-sorbet", require: false)
15
+ gem("sorbet", require: false)
16
+ gem("tapioca", require: false, github: "Shopify/tapioca", branch: "master")
13
17
  end
data/README.md CHANGED
@@ -1,8 +1,6 @@
1
- # Rbi
1
+ # RBI generation framework
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/rbi`. To experiment with that code, run `bin/console` for an interactive prompt.
4
-
5
- TODO: Delete this and the text above, and describe your gem
3
+ `RBI` provides a Ruby API to compose Ruby interface files consumed by Sorbet.
6
4
 
7
5
  ## Installation
8
6
 
@@ -14,7 +12,7 @@ gem 'rbi'
14
12
 
15
13
  And then execute:
16
14
 
17
- $ bundle
15
+ $ bundle install
18
16
 
19
17
  Or install it yourself as:
20
18
 
@@ -22,17 +20,47 @@ Or install it yourself as:
22
20
 
23
21
  ## Usage
24
22
 
25
- TODO: Write usage instructions here
23
+ ```rb
24
+ require "rbi"
25
+
26
+ rbi = RBI::File.new(strictness: "true") do |file|
27
+ file << RBI::Module.new("Foo") do |mod|
28
+ mod << RBI::Method.new("foo")
29
+ end
30
+ end
31
+
32
+ puts rbi.string
33
+ ```
34
+
35
+ will produce:
36
+
37
+ ```rb
38
+ # typed: true
39
+
40
+ module Foo
41
+ def foo; end
42
+ end
43
+ ```
44
+
45
+ ## Features
46
+
47
+ * RBI generation API
48
+ * RBI parsing with Whitequark
49
+ * RBI formatting
50
+ * RBI validation
51
+ * RBI merging
26
52
 
27
53
  ## Development
28
54
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
55
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
56
+
57
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
30
58
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
59
+ This repo uses itself (`rbi`) to retrieve and generate gem RBIs. You can run `dev rbi` to update local gem RBIs with RBIs from the central repo.
32
60
 
33
61
  ## Contributing
34
62
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/rbi. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
63
+ Bug reports and pull requests are welcome on GitHub at https://github.com/Shopify/rbi. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/Shopify/rbi/blob/master/CODE_OF_CONDUCT.md).
36
64
 
37
65
  ## License
38
66
 
@@ -40,4 +68,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
40
68
 
41
69
  ## Code of Conduct
42
70
 
43
- Everyone interacting in the Rbi projects codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/rbi/blob/master/CODE_OF_CONDUCT.md).
71
+ Everyone interacting in the Rbi project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/rbi/blob/master/CODE_OF_CONDUCT.md).
data/Rakefile CHANGED
@@ -1,7 +1,9 @@
1
1
  # typed: true
2
2
  # frozen_string_literal: true
3
+
3
4
  require "bundler/gem_tasks"
4
5
  require "rake/testtask"
6
+ require "rubocop/rake_task"
5
7
 
6
8
  Rake::TestTask.new(:test) do |t|
7
9
  t.libs << "test"
data/lib/rbi/index.rb ADDED
@@ -0,0 +1,186 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module RBI
5
+ class Index < Visitor
6
+ extend T::Sig
7
+ include T::Enumerable
8
+
9
+ sig { params(node: Node).returns(Index) }
10
+ def self.index(*node)
11
+ index = Index.new
12
+ index.visit_all(node)
13
+ index
14
+ end
15
+
16
+ sig { void }
17
+ def initialize
18
+ super()
19
+ @index = T.let({}, T::Hash[String, T::Array[Node]])
20
+ end
21
+
22
+ sig { returns(T::Array[String]) }
23
+ def keys
24
+ @index.keys
25
+ end
26
+
27
+ sig { params(id: String).returns(T::Array[Node]) }
28
+ def [](id)
29
+ @index[id] ||= []
30
+ end
31
+
32
+ sig { params(node: T.all(Indexable, Node)).void }
33
+ def index(node)
34
+ node.index_ids.each { |id| self[id] << node }
35
+ end
36
+
37
+ sig { override.params(node: T.nilable(Node)).void }
38
+ def visit(node)
39
+ return unless node
40
+
41
+ case node
42
+ when Scope
43
+ index(node)
44
+ visit_all(node.nodes)
45
+ when Tree
46
+ visit_all(node.nodes)
47
+ when Indexable
48
+ index(node)
49
+ end
50
+ end
51
+ end
52
+
53
+ class Tree
54
+ extend T::Sig
55
+
56
+ sig { returns(Index) }
57
+ def index
58
+ Index.index(self)
59
+ end
60
+ end
61
+
62
+ # A Node that can be refered to by a unique ID inside an index
63
+ module Indexable
64
+ extend T::Sig
65
+ extend T::Helpers
66
+
67
+ interface!
68
+
69
+ # Unique IDs that refer to this node.
70
+ #
71
+ # Some nodes can have multiple ids, for example an attribute accessor matches the ID of the
72
+ # getter and the setter.
73
+ sig { abstract.returns(T::Array[String]) }
74
+ def index_ids; end
75
+ end
76
+
77
+ class Scope
78
+ extend T::Sig
79
+ include Indexable
80
+
81
+ sig { override.returns(T::Array[String]) }
82
+ def index_ids
83
+ [fully_qualified_name]
84
+ end
85
+ end
86
+
87
+ class Const
88
+ extend T::Sig
89
+ include Indexable
90
+
91
+ sig { override.returns(T::Array[String]) }
92
+ def index_ids
93
+ [fully_qualified_name]
94
+ end
95
+ end
96
+
97
+ class Attr
98
+ extend T::Sig
99
+ include Indexable
100
+
101
+ sig { override.returns(T::Array[String]) }
102
+ def index_ids
103
+ fully_qualified_names
104
+ end
105
+ end
106
+
107
+ class Method
108
+ extend T::Sig
109
+ include Indexable
110
+
111
+ sig { override.returns(T::Array[String]) }
112
+ def index_ids
113
+ [fully_qualified_name]
114
+ end
115
+ end
116
+
117
+ class Include
118
+ extend T::Sig
119
+ include Indexable
120
+
121
+ sig { override.returns(T::Array[String]) }
122
+ def index_ids
123
+ names.map { |name| "#{parent_scope&.fully_qualified_name}.include(#{name})" }
124
+ end
125
+ end
126
+
127
+ class Extend
128
+ extend T::Sig
129
+ include Indexable
130
+
131
+ sig { override.returns(T::Array[String]) }
132
+ def index_ids
133
+ names.map { |name| "#{parent_scope&.fully_qualified_name}.extend(#{name})" }
134
+ end
135
+ end
136
+
137
+ class MixesInClassMethods
138
+ extend T::Sig
139
+ include Indexable
140
+
141
+ sig { override.returns(T::Array[String]) }
142
+ def index_ids
143
+ names.map { |name| "#{parent_scope&.fully_qualified_name}.mixes_in_class_method(#{name})" }
144
+ end
145
+ end
146
+
147
+ class Helper
148
+ extend T::Sig
149
+ include Indexable
150
+
151
+ sig { override.returns(T::Array[String]) }
152
+ def index_ids
153
+ [to_s]
154
+ end
155
+ end
156
+
157
+ class TStructConst
158
+ extend T::Sig
159
+ include Indexable
160
+
161
+ sig { override.returns(T::Array[String]) }
162
+ def index_ids
163
+ fully_qualified_names
164
+ end
165
+ end
166
+
167
+ class TStructProp
168
+ extend T::Sig
169
+ include Indexable
170
+
171
+ sig { override.returns(T::Array[String]) }
172
+ def index_ids
173
+ fully_qualified_names
174
+ end
175
+ end
176
+
177
+ class TEnumBlock
178
+ extend T::Sig
179
+ include Indexable
180
+
181
+ sig { override.returns(T::Array[String]) }
182
+ def index_ids
183
+ [to_s]
184
+ end
185
+ end
186
+ end
data/lib/rbi/loc.rb ADDED
@@ -0,0 +1,36 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module RBI
5
+ class Loc
6
+ extend T::Sig
7
+
8
+ sig { returns(T.nilable(String)) }
9
+ attr_reader :file
10
+
11
+ sig { returns(T.nilable(Integer)) }
12
+ attr_reader :begin_line, :end_line, :begin_column, :end_column
13
+
14
+ sig do
15
+ params(
16
+ file: T.nilable(String),
17
+ begin_line: T.nilable(Integer),
18
+ end_line: T.nilable(Integer),
19
+ begin_column: T.nilable(Integer),
20
+ end_column: T.nilable(Integer)
21
+ ).void
22
+ end
23
+ def initialize(file: nil, begin_line: nil, end_line: nil, begin_column: nil, end_column: nil)
24
+ @file = file
25
+ @begin_line = begin_line
26
+ @end_line = end_line
27
+ @begin_column = begin_column
28
+ @end_column = end_column
29
+ end
30
+
31
+ sig { returns(String) }
32
+ def to_s
33
+ "#{file}:#{begin_line}:#{begin_column}-#{end_line}:#{end_column}"
34
+ end
35
+ end
36
+ end