parlour 0.4.0 → 0.5.0

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: 74fcc1898cf62ffe8cd5300bb14409c02b9d3a1fd3f323a07606ef399de2f9c7
4
- data.tar.gz: 111bb1a4d35a610797e4d845388f6cf7dc2815b8b7732b885bc91eb281fc0408
3
+ metadata.gz: 9cfa95875716d50b33a4d3557fd6b60d6d477bed3e933c6c369d148399193cff
4
+ data.tar.gz: 2c9f22571d96d3d592353807c3b40e96e1e567968b761a1ba1174cfeb3a5ecca
5
5
  SHA512:
6
- metadata.gz: c44c7ca71ffa19834234533348c340c341df6332f8f7ff15708e4d46c4016ef8dd5fbee5012e333338b79746bb8360aef68ea83bf50f651d6fc1b5636567895d
7
- data.tar.gz: cc64f14e22f32a6952b896cb51eca120a0a5a94ccbd0aca41147af9d0dcb90d9ba6748771a1a17324a9c7ba5ecf1b6615963a174ce90b5b5a8e2d48ec8de5c91
6
+ metadata.gz: a40ddab81583e19e1552c1b4e35257a8f99cf8d862221eb4c5b8641097d299a07b0290ab8d6ecedacfc94b0881cd95ab709bf9596446d1e41fceaebd823bc720
7
+ data.tar.gz: 4de8a3ac91b6c17ebc99d5659f2af8f4cf52083963f60a5851809b05e7237797af6ea81126d35e716b9c46ebe90ace4c0d561d0d582f8ae16a973a159957218a
@@ -1,5 +1,17 @@
1
1
  language: ruby
2
+ dist: trusty
2
3
  before_install:
3
4
  - gem install bundler
5
+ - gem install yard
4
6
  rvm:
5
- - 2.6
7
+ - 2.6
8
+ after_success:
9
+ - yard
10
+ deploy:
11
+ provider: pages
12
+ local_dir: doc
13
+ skip_cleanup: true
14
+ github_token: $GITHUB_TOKEN
15
+ keep_history: true
16
+ on:
17
+ branch: master
@@ -3,6 +3,16 @@ All notable changes to this project will be documented in this file.
3
3
 
4
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
5
5
 
6
+ ## [0.5.0] - 2019-07-20
7
+ ### Added
8
+ - Added the `create_arbitrary` method for inserting arbitrary code into the
9
+ generated RBI file. This is intended for using constructs which Parlour does
10
+ not yet support.
11
+
12
+ ### Changed
13
+ - Breaking change: `add_constant`, `add_include` and `add_extend` have been
14
+ replaced with `create_constant`, `create_include` and `create_extend`.
15
+
6
16
  ## [0.4.0] - 2019-07-10
7
17
  ### Changed
8
18
  - Breaking change: The Parlour CLI tool no longer takes command-line arguments, and instead uses a `.parlour` configuration file. See the README!
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # Parlour
2
2
 
3
3
  [![Build Status](https://travis-ci.org/AaronC81/parlour.svg?branch=master)](https://travis-ci.org/AaronC81/parlour)
4
+ ![Gem](https://img.shields.io/gem/v/parlour.svg)
4
5
 
5
6
  Parlour is an RBI generator and merger for Sorbet. It consists of two key parts:
6
7
 
@@ -20,10 +21,11 @@ Parlour is an RBI generator and merger for Sorbet. It consists of two key parts:
20
21
  single command and consolidating all of their definitions into a single
21
22
  RBI output file.
22
23
 
23
- ## Usage
24
24
 
25
- There aren't really any docs currently, so have a look around the code to find
26
- any extra options you may need.
25
+ Please [**read the wiki**](https://github.com/AaronC81/parlour/wiki) to get
26
+ started!
27
+
28
+ ## Creating RBIs
27
29
 
28
30
  ### Using just the generator
29
31
 
@@ -150,69 +152,6 @@ _Have you written an awesome Parlour plugin? Please submit a PR to add it to thi
150
152
 
151
153
  - [Sord](https://github.com/AaronC81/sord) - Generate RBIs from YARD documentation
152
154
 
153
- ## Parlour's Code Structure
154
-
155
- ### Overall Flow
156
- ```
157
- STEP 1
158
- All plugins mutate the
159
- instance of RbiGenerator
160
- They generate a tree
161
- structure of RbiObjects
162
-
163
- +--------+ +--------+
164
- |Plugin 1| |Plugin 2|
165
- +----+---+ +----+---+ STEP 2
166
- ^ ^ ConflictResolver
167
- | | mutates the structure
168
- +-------------------+ | | to fix conflicts
169
- | | | |
170
- | One instance of +-------------+ +----------------+
171
- | RbiGenerator +--------------------->+ConflictResolver|
172
- | | +----------------+
173
- +---------+---------+
174
- |
175
- |
176
- | +-------+ STEP 3
177
- +--------->+ File | The final RBI is written
178
- +-------+ to a file
179
- ```
180
-
181
- ### Generation
182
- Everything that can generate lines of the RBI implements the
183
- `RbiGenerator::RbiObject` abstract class. The function `generate_rbi`
184
- accepts the current indentation level and a set of formatting options.
185
- (Each object is responsible for generating its own indentation; that is, the
186
- lines generated by a child object should not then be indented by its parent.)
187
-
188
- ### Plugins
189
- Plugins are automatically detected when they subclass `Plugin`. Plugins can then
190
- be run by passing an array of them, along with an `RbiGenerator`, to
191
- `Plugin.run_plugins`. Once done, the generator will be populated with a tree of
192
- (possibly conflicting) `RbiObjects` - the conflict resolver (detailed below)
193
- will clear up any conflicts.
194
-
195
- ### Conflict Resolution
196
- This is a key part of the plugin/build system. The `ConflictResolver` takes
197
- a namespace from the `RbiGenerator` and merges duplicate items in it together.
198
- This means that many plugins can generate their own signatures which are all
199
- bundled into one, conflict-free output RBI.
200
-
201
- It is able to do the following merges automatically:
202
-
203
- - If many methods are identical, delete all but one.
204
- - If many classes are defined with the same name, merge their methods,
205
- includes and extends. (But only if they are all abstract or all not,
206
- and only if they don't define more than one superclass together.)
207
- - If many modules are defined with the same name, merge their methods,
208
- includes and extends. (But only if they are all interfaces or all not.)
209
-
210
- If a merge can't be performed automatically, then the `#resolve_conflicts`
211
- method takes a block. This block is passed all the conflicting objects, and one
212
- should be selected and returned - all others will be deleted. (Alternatively,
213
- the block can return nil, and all will be deleted.) This allows the CLI to
214
- prompt the user asking them what they'd like to do, in the case of conflicts
215
- between each plugin's signatures which can't automatically be resolved.
216
155
 
217
156
  ## Contributing
218
157
 
@@ -9,7 +9,11 @@ require 'parlour/rbi_generator/parameter'
9
9
  require 'parlour/rbi_generator/rbi_object'
10
10
  require 'parlour/rbi_generator/method'
11
11
  require 'parlour/rbi_generator/attribute'
12
+ require 'parlour/rbi_generator/arbitrary'
12
13
  require 'parlour/rbi_generator/options'
14
+ require 'parlour/rbi_generator/include'
15
+ require 'parlour/rbi_generator/extend'
16
+ require 'parlour/rbi_generator/constant'
13
17
  require 'parlour/rbi_generator/namespace'
14
18
  require 'parlour/rbi_generator/module_namespace'
15
19
  require 'parlour/rbi_generator/class_namespace'
@@ -0,0 +1,92 @@
1
+ # typed: true
2
+ module Parlour
3
+ class RbiGenerator
4
+ # Represents miscellaneous Ruby code.
5
+ class Arbitrary < RbiObject
6
+ sig do
7
+ params(
8
+ generator: RbiGenerator,
9
+ code: String,
10
+ block: T.nilable(T.proc.params(x: Arbitrary).void)
11
+ ).void
12
+ end
13
+ # Creates new arbitrary code.
14
+ #
15
+ # @param code [String] The arbitrary code string. Indentation is added to
16
+ # the beginning of each line.
17
+ def initialize(generator, code: '', &block)
18
+ super(generator, '')
19
+ @code = code
20
+ yield_self(&block)
21
+ end
22
+
23
+ sig { returns(String) }
24
+ # Returns arbitrary code string.
25
+ attr_accessor :code
26
+
27
+ sig { params(other: Object).returns(T::Boolean) }
28
+ # Returns true if this instance is equal to another arbitrary code line.
29
+ #
30
+ # @param other [Object] The other instance. If this is not a {Arbitrary} (or a
31
+ # subclass of it), this will always return false.
32
+ # @return [Boolean]
33
+ def ==(other)
34
+ Arbitrary === other && code == other.code
35
+ end
36
+
37
+ sig do
38
+ implementation.params(
39
+ indent_level: Integer,
40
+ options: Options
41
+ ).returns(T::Array[String])
42
+ end
43
+ # Generates the RBI lines for this arbitrary code.
44
+ #
45
+ # @param indent_level [Integer] The indentation level to generate the lines at.
46
+ # @param options [Options] The formatting options to use.
47
+ # @return [Array<String>] The RBI lines, formatted as specified.
48
+ def generate_rbi(indent_level, options)
49
+ code.split("\n").map { |l| options.indented(indent_level, l) }
50
+ end
51
+
52
+ sig do
53
+ implementation.params(
54
+ others: T::Array[RbiGenerator::RbiObject]
55
+ ).returns(T::Boolean)
56
+ end
57
+ # Given an array of {Arbitrary} instances, returns true if they may be
58
+ # merged into this instance using {merge_into_self}. This is always false.
59
+ #
60
+ # @param others [Array<RbiGenerator::RbiObject>] An array of other
61
+ # {Arbitrary} instances.
62
+ # @return [Boolean] Whether this instance may be merged with them.
63
+ def mergeable?(others)
64
+ false
65
+ end
66
+
67
+ sig do
68
+ implementation.params(
69
+ others: T::Array[RbiGenerator::RbiObject]
70
+ ).void
71
+ end
72
+ # Given an array of {Arbitrary} instances, merges them into this one.
73
+ # This particular implementation always throws an exception, because
74
+ # {mergeable?} is always false.
75
+ #
76
+ # @param others [Array<RbiGenerator::RbiObject>] An array of other
77
+ # {Arbitrary} instances.
78
+ # @return [void]
79
+ def merge_into_self(others)
80
+ raise 'arbitrary code is never mergeable'
81
+ end
82
+
83
+ sig { override.returns(String) }
84
+ # Returns a human-readable brief string description of this code.
85
+ #
86
+ # @return [String]
87
+ def describe
88
+ "Arbitrary code (#{code})"
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,94 @@
1
+ # typed: true
2
+ module Parlour
3
+ class RbiGenerator
4
+ # Represents a constant definition.
5
+ class Constant < RbiObject
6
+ sig do
7
+ params(
8
+ generator: RbiGenerator,
9
+ name: String,
10
+ value: String,
11
+ block: T.nilable(T.proc.params(x: Constant).void)
12
+ ).void
13
+ end
14
+ # Creates a new constant definition.
15
+ #
16
+ # @param name [String] The name of the constant.
17
+ # @param value [String] The value of the constant, as a Ruby code string.
18
+ def initialize(generator, name: '', value: '', &block)
19
+ super(generator, name)
20
+ @value = value
21
+ yield_self(&block)
22
+ end
23
+
24
+ # @return [String] The value of the constant, as a Ruby code string.
25
+ sig { returns(String) }
26
+ attr_reader :value
27
+
28
+ sig { params(other: Object).returns(T::Boolean) }
29
+ # Returns true if this instance is equal to another extend.
30
+ #
31
+ # @param other [Object] The other instance. If this is not a {Extend} (or a
32
+ # subclass of it), this will always return false.
33
+ # @return [Boolean]
34
+ def ==(other)
35
+ Constant === other && name == other.name && value == other.value
36
+ end
37
+
38
+ sig do
39
+ implementation.params(
40
+ indent_level: Integer,
41
+ options: Options
42
+ ).returns(T::Array[String])
43
+ end
44
+ # Generates the RBI lines for this constant.
45
+ #
46
+ # @param indent_level [Integer] The indentation level to generate the lines at.
47
+ # @param options [Options] The formatting options to use.
48
+ # @return [Array<String>] The RBI lines, formatted as specified.
49
+ def generate_rbi(indent_level, options)
50
+ [options.indented(indent_level, "#{name} = #{value}")]
51
+ end
52
+
53
+ sig do
54
+ implementation.params(
55
+ others: T::Array[RbiGenerator::RbiObject]
56
+ ).returns(T::Boolean)
57
+ end
58
+ # Given an array of {Constant} instances, returns true if they may be
59
+ # merged into this instance using {merge_into_self}. This is always false.
60
+ #
61
+ # @param others [Array<RbiGenerator::RbiObject>] An array of other
62
+ # {Constant} instances.
63
+ # @return [Boolean] Whether this instance may be merged with them.
64
+ def mergeable?(others)
65
+ others.all? { |other| self == other }
66
+ end
67
+
68
+ sig do
69
+ implementation.params(
70
+ others: T::Array[RbiGenerator::RbiObject]
71
+ ).void
72
+ end
73
+ # Given an array of {Constant} instances, merges them into this one.
74
+ # This particular implementation will simply do nothing, as instances
75
+ # are only mergeable if they are indentical.
76
+ # You MUST ensure that {mergeable?} is true for those instances.
77
+ #
78
+ # @param others [Array<RbiGenerator::RbiObject>] An array of other
79
+ # {Extend} instances.
80
+ # @return [void]
81
+ def merge_into_self(others)
82
+ # We don't need to change anything! We only merge identical constants
83
+ end
84
+
85
+ sig { implementation.returns(String) }
86
+ # Returns a human-readable brief string description of this code.
87
+ #
88
+ # @return [String]
89
+ def describe
90
+ "Constant (#{name} = #{value})"
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,87 @@
1
+ # typed: true
2
+ module Parlour
3
+ class RbiGenerator
4
+ # Represents an +extend+ call.
5
+ class Extend < RbiObject
6
+ sig do
7
+ params(
8
+ generator: RbiGenerator,
9
+ name: String,
10
+ block: T.nilable(T.proc.params(x: Extend).void)
11
+ ).void
12
+ end
13
+ # Creates a new +extend+ call.
14
+ #
15
+ # @param name [String] The name of the object to be extended.
16
+ def initialize(generator, name: '', &block)
17
+ super(generator, name)
18
+ yield_self(&block)
19
+ end
20
+
21
+ sig { params(other: Object).returns(T::Boolean) }
22
+ # Returns true if this instance is equal to another extend.
23
+ #
24
+ # @param other [Object] The other instance. If this is not a {Extend} (or a
25
+ # subclass of it), this will always return false.
26
+ # @return [Boolean]
27
+ def ==(other)
28
+ Extend === other && name == other.name
29
+ end
30
+
31
+ sig do
32
+ implementation.params(
33
+ indent_level: Integer,
34
+ options: Options
35
+ ).returns(T::Array[String])
36
+ end
37
+ # Generates the RBI lines for this extend.
38
+ #
39
+ # @param indent_level [Integer] The indentation level to generate the lines at.
40
+ # @param options [Options] The formatting options to use.
41
+ # @return [Array<String>] The RBI lines, formatted as specified.
42
+ def generate_rbi(indent_level, options)
43
+ [options.indented(indent_level, "extend #{name}")]
44
+ end
45
+
46
+ sig do
47
+ implementation.params(
48
+ others: T::Array[RbiGenerator::RbiObject]
49
+ ).returns(T::Boolean)
50
+ end
51
+ # Given an array of {Extend} instances, returns true if they may be
52
+ # merged into this instance using {merge_into_self}. This is always false.
53
+ #
54
+ # @param others [Array<RbiGenerator::RbiObject>] An array of other
55
+ # {Extend} instances.
56
+ # @return [Boolean] Whether this instance may be merged with them.
57
+ def mergeable?(others)
58
+ others.all? { |other| self == other }
59
+ end
60
+
61
+ sig do
62
+ implementation.params(
63
+ others: T::Array[RbiGenerator::RbiObject]
64
+ ).void
65
+ end
66
+ # Given an array of {Extend} instances, merges them into this one.
67
+ # This particular implementation will simply do nothing, as instances
68
+ # are only mergeable if they are indentical.
69
+ # You MUST ensure that {mergeable?} is true for those instances.
70
+ #
71
+ # @param others [Array<RbiGenerator::RbiObject>] An array of other
72
+ # {Extend} instances.
73
+ # @return [void]
74
+ def merge_into_self(others)
75
+ # We don't need to change anything! We only merge identical extends
76
+ end
77
+
78
+ sig { implementation.returns(String) }
79
+ # Returns a human-readable brief string description of this code.
80
+ #
81
+ # @return [String]
82
+ def describe
83
+ "Extend (#{name})"
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,87 @@
1
+ # typed: true
2
+ module Parlour
3
+ class RbiGenerator
4
+ # Represents an +include+ call.
5
+ class Include < RbiObject
6
+ sig do
7
+ params(
8
+ generator: RbiGenerator,
9
+ name: String,
10
+ block: T.nilable(T.proc.params(x: Include).void)
11
+ ).void
12
+ end
13
+ # Creates a new +include+ call.
14
+ #
15
+ # @param name [String] The name of the object to be included.
16
+ def initialize(generator, name: '', &block)
17
+ super(generator, name)
18
+ yield_self(&block)
19
+ end
20
+
21
+ sig { params(other: Object).returns(T::Boolean) }
22
+ # Returns true if this instance is equal to another include.
23
+ #
24
+ # @param other [Object] The other instance. If this is not a {Include} (or a
25
+ # subclass of it), this will always return false.
26
+ # @return [Boolean]
27
+ def ==(other)
28
+ Include === other && name == other.name
29
+ end
30
+
31
+ sig do
32
+ implementation.params(
33
+ indent_level: Integer,
34
+ options: Options
35
+ ).returns(T::Array[String])
36
+ end
37
+ # Generates the RBI lines for this include.
38
+ #
39
+ # @param indent_level [Integer] The indentation level to generate the lines at.
40
+ # @param options [Options] The formatting options to use.
41
+ # @return [Array<String>] The RBI lines, formatted as specified.
42
+ def generate_rbi(indent_level, options)
43
+ [options.indented(indent_level, "include #{name}")]
44
+ end
45
+
46
+ sig do
47
+ implementation.params(
48
+ others: T::Array[RbiGenerator::RbiObject]
49
+ ).returns(T::Boolean)
50
+ end
51
+ # Given an array of {Include} instances, returns true if they may be
52
+ # merged into this instance using {merge_into_self}. This is always false.
53
+ #
54
+ # @param others [Array<RbiGenerator::RbiObject>] An array of other
55
+ # {Include} instances.
56
+ # @return [Boolean] Whether this instance may be merged with them.
57
+ def mergeable?(others)
58
+ others.all? { |other| self == other }
59
+ end
60
+
61
+ sig do
62
+ implementation.params(
63
+ others: T::Array[RbiGenerator::RbiObject]
64
+ ).void
65
+ end
66
+ # Given an array of {Include} instances, merges them into this one.
67
+ # This particular implementation will simply do nothing, as instances
68
+ # are only mergeable if they are indentical.
69
+ # You MUST ensure that {mergeable?} is true for those instances.
70
+ #
71
+ # @param others [Array<RbiGenerator::RbiObject>] An array of other
72
+ # {Include} instances.
73
+ # @return [void]
74
+ def merge_into_self(others)
75
+ # We don't need to change anything! We only merge identical includes
76
+ end
77
+
78
+ sig { implementation.returns(String) }
79
+ # Returns a human-readable brief string description of this code.
80
+ #
81
+ # @return [String]
82
+ def describe
83
+ "Include (#{name})"
84
+ end
85
+ end
86
+ end
87
+ end
@@ -18,7 +18,7 @@ module Parlour
18
18
  # @param options [Options] The formatting options to use.
19
19
  # @return [Array<String>] The RBI lines, formatted as specified.
20
20
  def generate_rbi(indent_level, options)
21
- generate_comments(indent_level, options) +
21
+ generate_comments(indent_level, options) +
22
22
  generate_body(indent_level, options)
23
23
  end
24
24
 
@@ -40,9 +40,6 @@ module Parlour
40
40
  def initialize(generator, name = nil, &block)
41
41
  super(generator, name || '<anonymous namespace>')
42
42
  @children = []
43
- @extends = []
44
- @includes = []
45
- @constants = []
46
43
  @next_comments = []
47
44
  yield_self(&block)
48
45
  end
@@ -52,23 +49,35 @@ module Parlour
52
49
  # @return [Array<RbiObject>]
53
50
  attr_reader :children
54
51
 
55
- sig { returns(T::Array[String]) }
56
- # A list of strings which are each used in an +extend+ statement in this
57
- # namespace.
58
- # @return [Array<String>]
59
- attr_reader :extends
52
+ sig { returns(T::Array[RbiGenerator::Extend]) }
53
+ # The {RbiGenerator::Extend} objects from {children}.
54
+ # @return [Array<RbiGenerator::Extend>]
55
+ def extends
56
+ T.cast(
57
+ children.select { |c| c.is_a?(RbiGenerator::Extend) },
58
+ T::Array[RbiGenerator::Extend]
59
+ )
60
+ end
60
61
 
61
- sig { returns(T::Array[String]) }
62
- # A list of strings which are each used in an +include+ statement in this
63
- # namespace.
64
- # @return [Array<String>]
65
- attr_reader :includes
62
+ sig { returns(T::Array[RbiGenerator::Include]) }
63
+ # The {RbiGenerator::Include} objects from {children}.
64
+ # @return [Array<RbiGenerator::Include>]
65
+ def includes
66
+ T.cast(
67
+ children.select { |c| c.is_a?(RbiGenerator::Include) },
68
+ T::Array[RbiGenerator::Include]
69
+ )
70
+ end
66
71
 
67
- sig { returns(T::Array[[String, String]]) }
68
- # A list of constants which are defined in this namespace, in the form of
69
- # pairs [name, value].
70
- # @return [Array<(String, String)>]
71
- attr_reader :constants
72
+ sig { returns(T::Array[RbiGenerator::Constant]) }
73
+ # The {RbiGenerator::Constant} objects from {children}.
74
+ # @return [Array<RbiGenerator::Constant>]
75
+ def constants
76
+ T.cast(
77
+ children.select { |c| c.is_a?(RbiGenerator::Constant) },
78
+ T::Array[RbiGenerator::Constant]
79
+ )
80
+ end
72
81
 
73
82
  sig { params(comment: T.any(String, T::Array[String])).void }
74
83
  # Adds one or more comments to the next child RBI object to be created.
@@ -282,41 +291,90 @@ module Parlour
282
291
  create_attribute(name: name, kind: :accessor, type: type, &block)
283
292
  end
284
293
 
285
- sig { params(name: String).void }
294
+ # Creates a new arbitrary code section.
295
+ # You should rarely have to use this!
296
+ #
297
+ # @param code [String] The code to insert.
298
+ # @param block A block which the new instance yields itself to.
299
+ # @return [RbiGenerator::Arbitrary]
300
+ def create_arbitrary(code: nil, &block)
301
+ code = T.must(code)
302
+ new_arbitrary = RbiGenerator::Arbitrary.new(
303
+ generator,
304
+ code: code,
305
+ &block
306
+ )
307
+ move_next_comments(new_arbitrary)
308
+ children << new_arbitrary
309
+ new_arbitrary
310
+ end
311
+
312
+ sig { params(name: String, block: T.nilable(T.proc.params(x: Extend).void)).returns(RbiGenerator::Extend) }
286
313
  # Adds a new +extend+ to this namespace.
287
314
  #
288
315
  # @example Add an +extend+ to a class.
289
- # class.add_extend('ExtendableClass') #=> extend ExtendableClass
316
+ # class.create_extend(name: 'ExtendableClass') #=> extend ExtendableClass
290
317
  #
291
- # @param name [String] A code string for what is extended, for example
318
+ # @param object [String] A code string for what is extended, for example
292
319
  # +"MyModule"+.
293
- # @return [void]
294
- def add_extend(name)
295
- extends << name
320
+ # @param block A block which the new instance yields itself to.
321
+ # @return [RbiGenerator::Extend]
322
+ def create_extend(name: nil, &block)
323
+ name = T.must(name)
324
+ new_extend = RbiGenerator::Extend.new(
325
+ generator,
326
+ name: name,
327
+ &block
328
+ )
329
+ move_next_comments(new_extend)
330
+ children << new_extend
331
+ new_extend
296
332
  end
297
333
 
298
- sig { params(name: String).void }
334
+ sig { params(name: String, block: T.nilable(T.proc.params(x: Include).void)).returns(Include) }
299
335
  # Adds a new +include+ to this namespace.
300
336
  #
301
337
  # @example Add an +include+ to a class.
302
- # class.add_include('IncludableClass') #=> include IncludableClass
338
+ # class.create_include(name: 'IncludableClass') #=> include IncludableClass
303
339
  #
304
- # @param name [String] A code string for what is included, for example
340
+ # @param object [String] A code string for what is included, for example
305
341
  # +"Enumerable"+.
306
- # @return [void]
307
- def add_include(name)
308
- includes << name
342
+ # @param block A block which the new instance yields itself to.
343
+ # @return [RbiGenerator::Include]
344
+ def create_include(name: nil, &block)
345
+ name = T.must(name)
346
+ new_include = RbiGenerator::Include.new(
347
+ generator,
348
+ name: name,
349
+ &block
350
+ )
351
+ move_next_comments(new_include)
352
+ children << new_include
353
+ new_include
309
354
  end
310
355
 
311
- sig { params(name: String, value: String).void }
356
+ sig { params(name: String, value: String, block: T.nilable(T.proc.params(x: Constant).void)).returns(Constant) }
312
357
  # Adds a new constant definition to this namespace.
313
358
  #
359
+ # @example Add an +Elem+ constant to the class.
360
+ # class.create_include(name: 'IncludableClass') #=> Elem = String
361
+ #
314
362
  # @param name [String] The name of the constant.
315
- # @param value [String] A Ruby code string for this constant's value, for
316
- # example +"3.14"+ or +"T.type_alias(X)"+
317
- # @return [void]
318
- def add_constant(name, value)
319
- constants << [name, value]
363
+ # @param value [String] The value of the constant, as a Ruby code string.
364
+ # @param block A block which the new instance yields itself to.
365
+ # @return [RbiGenerator::Constant]
366
+ def create_constant(name: nil, value: nil, &block)
367
+ name = T.must(name)
368
+ value = T.must(value)
369
+ new_constant = RbiGenerator::Constant.new(
370
+ generator,
371
+ name: name,
372
+ value: value,
373
+ &block
374
+ )
375
+ move_next_comments(new_constant)
376
+ children << new_constant
377
+ new_constant
320
378
  end
321
379
 
322
380
  sig do
@@ -352,9 +410,6 @@ module Parlour
352
410
  other = T.cast(other, Namespace)
353
411
 
354
412
  other.children.each { |c| children << c }
355
- other.extends.each { |e| extends << e }
356
- other.includes.each { |i| includes << i }
357
- other.constants.each { |i| constants << i }
358
413
  end
359
414
  end
360
415
 
@@ -385,20 +440,22 @@ module Parlour
385
440
  result = []
386
441
 
387
442
  if includes.any? || extends.any? || constants.any?
388
- result += includes.map do |i|
389
- options.indented(indent_level, "include #{i}")
390
- end
391
- result += extends.map do |e|
392
- options.indented(indent_level, "extend #{e}")
393
- end
394
- result += constants.map do |c|
395
- name, value = c
396
- options.indented(indent_level, "#{name} = #{value}")
397
- end
443
+ result += includes
444
+ .flat_map { |x| x.generate_rbi(indent_level, options) }
445
+ .reject { |x| x.strip == '' }
446
+ result += extends
447
+ .flat_map { |x| x.generate_rbi(indent_level, options) }
448
+ .reject { |x| x.strip == '' }
449
+ result += constants
450
+ .flat_map { |x| x.generate_rbi(indent_level, options) }
451
+ .reject { |x| x.strip == '' }
398
452
  result << ""
399
453
  end
400
454
 
401
- first, *rest = children
455
+ first, *rest = children.reject do |child|
456
+ # We already processed these kinds of children
457
+ child.is_a?(Include) || child.is_a?(Extend) || child.is_a?(Constant)
458
+ end
402
459
  unless first
403
460
  # Remove any trailing whitespace due to includes
404
461
  result.pop if result.last == ''
@@ -1,5 +1,5 @@
1
1
  # typed: strong
2
2
  module Parlour
3
3
  # The library version.
4
- VERSION = '0.4.0'
4
+ VERSION = '0.5.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parlour
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Christiansen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-07-10 00:00:00.000000000 Z
11
+ date: 2019-07-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sorbet-runtime
@@ -132,8 +132,12 @@ files:
132
132
  - lib/parlour/conflict_resolver.rb
133
133
  - lib/parlour/plugin.rb
134
134
  - lib/parlour/rbi_generator.rb
135
+ - lib/parlour/rbi_generator/arbitrary.rb
135
136
  - lib/parlour/rbi_generator/attribute.rb
136
137
  - lib/parlour/rbi_generator/class_namespace.rb
138
+ - lib/parlour/rbi_generator/constant.rb
139
+ - lib/parlour/rbi_generator/extend.rb
140
+ - lib/parlour/rbi_generator/include.rb
137
141
  - lib/parlour/rbi_generator/method.rb
138
142
  - lib/parlour/rbi_generator/module_namespace.rb
139
143
  - lib/parlour/rbi_generator/namespace.rb