parlour 0.4.0 → 0.5.0

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: 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