rbi 0.0.1 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
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