parlour 5.0.0.beta.4 → 6.0.1

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: 28a746eeb5c6322d0dfbfc53336bde66a65a35462f8e7685098aadd8720d3ade
4
- data.tar.gz: 5cd5e9fe8cd248e1b7685134b3116f04c28e481d30ed6ac01b77b6f82aa7236b
3
+ metadata.gz: 55378d16bdfdd7b027be168f8ed8bc0e78a49ba2ec42150692ba4e864c1f12eb
4
+ data.tar.gz: 21a92ac404908f7c8ea99975ac3be11486d8335ce6b0b0d329b1d3eb70a9c906
5
5
  SHA512:
6
- metadata.gz: 51d1cdde17b3d84ae927343e7627efc2ef832440907b8f3ae40ec3cf20edcd20a8f7f76f3991933251a7542ccc7b6ac1269a98a268603e34eaaf043322e05625
7
- data.tar.gz: d84ae4f6260e82de62dafdc67a7715c9cd74f01a68bbce8f5e89d0aa1f00509bd4a5230ec0fa7c850898f57936e29aee07c8f607935dbc1c784f4212ff709246
6
+ metadata.gz: 0cf8085a865e7865b1291b1cfde385cd3d9aff648f06c8ab7ea47d85161cc988faba165bae14bb450a979f27ef6687482105abe9a875781aea41d84a8b3f164e
7
+ data.tar.gz: 0a660369feb37945261fa7720034d8c48721b03ee1b8b71eaa121fd6f9c72070a20e32360fcba8109cc8dcb10dbeb7f471b24c8d80900ca6938b411756128e61
@@ -0,0 +1,46 @@
1
+ name: Run tests
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ test:
7
+ strategy:
8
+ matrix:
9
+ ruby: [2.4, 2.5, 2.6, 2.7, 3.0]
10
+ continue-on-error: false
11
+
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v2
15
+ - name: Set up Ruby
16
+ uses: ruby/setup-ruby@v1
17
+ with:
18
+ ruby-version: ${{ matrix.ruby }}
19
+ - name: Install dependencies
20
+ run: bundle install
21
+ - name: Run tests
22
+ run: bundle exec rake
23
+ - name: Check RBI is up-to-date
24
+ run: ./ci/check_rbi.sh
25
+
26
+ # Deploy documentation to GitHub Pages, if this is a push to master and the tests passed
27
+ deploy-docs:
28
+ if: ${{ github.ref == 'refs/heads/master' }}
29
+
30
+ runs-on: ubuntu-latest
31
+ steps:
32
+ - uses: actions/checkout@v2
33
+ - name: Set up Ruby
34
+ uses: ruby/setup-ruby@v1
35
+ with:
36
+ ruby-version: 2.7
37
+ - name: Install dependencies
38
+ run: bundle install
39
+ - name: Build documentation
40
+ run: bundle exec yard
41
+ - name: Deploy to GitHub Actions
42
+ uses: JamesIves/github-pages-deploy-action@3.7.1
43
+ with:
44
+ github_token: ${{ secrets.GITHUB_TOKEN }}
45
+ branch: gh-pages
46
+ folder: doc
data/CHANGELOG.md CHANGED
@@ -3,34 +3,28 @@ 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
- ## [5.0.0.beta.4] - 2020-09-22
7
- ### Added
8
- - Added support for parsing type aliases from RBI
9
- - Added conversion from RBI to RBS type aliases
10
-
11
- ## [5.0.0.beta.3] - 2020-09-15
6
+ ## [6.0.1] - 2021-02-28
12
7
  ### Changed
13
- - Changed the RBS keyword warning to come from "RBS generation" rather than
14
- "Type generalization"
15
- - Added many more of RBS' keywords which are detected and prefixed with an
16
- underscore to avoid syntax errors
17
-
18
- ## [5.0.0.beta.2] - 2020-09-14
19
- ### Added
20
- - Added `Types::Type#describe` for simple text descriptions of types
21
- - Added `Types::Self` for RBI's `T.self_type` or RBS' `self`
8
+ - Disabled runtime type checking for `TypedObject#name`, resulting in a
9
+ significant decrease in the time taken to run the conflict resolver.
22
10
 
23
- ### Fixed
24
- - Fixed `RbiGenerator::Namespace#create_method`'s `returns:` kwarg only
25
- accepting String types
26
- - Fixed lack of spacing between argument lists and blocks in RBS
27
- - Fixed RBS attributes not having comments
28
-
29
- ## [5.0.0.beta.1] - 2020-09-13
11
+ ## [6.0.0] - 2021-02-28
12
+ ### Changed
13
+ - The RBI previously included with the Parlour gem has been removed,
14
+ as it was causing issues with Sorbet. **If you were relying on Parlour's
15
+ bundled RBI while type-checking your project, you will now need to use the
16
+ RBI from sorbet-typed or the Parlour repo.**
17
+ - `Namespace#path` will now work much more reliably for classes and
18
+ modules which replace methods from `Module` and `Class`, such as
19
+ `#name`.
20
+
21
+ ## [5.0.0] - 2020-12-26
30
22
  ### Added
31
23
  - Added RBS generation support! This includes:
32
24
  - The new `RbsGenerator` class
33
25
  - `RbsObject` and a set of subclasses representing different RBS components
26
+ - **Note:** RBS does not yet support Parlour plugins and some other features.
27
+ Refer to the README for a full breakdown!
34
28
  - Added the `Types` module, which is used to describe types agnostic of the
35
29
  underlying type system
36
30
  - Added `RbiGenerator::Namespace#generalize_from_rbi!` to convert RBI string
@@ -42,6 +36,66 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
42
36
  - `TypedObject`, which `RbiObject` and `RbsObject` both inherit from
43
37
  - `Generator`, which `RbiGenerator` and `RbsGenerator` both inherit from
44
38
  - Added RBI type aliases
39
+ - Added `sealed!` for RBI namespaces
40
+ - Added `abstract!` for RBI modules
41
+
42
+ ### Changed
43
+ - `Parlour::RbiGenerator::Options` is now `Parlour::Options`. An alias exists
44
+ for now, but **`Parlour::RbiGenerator::Options` is deprecated** and could be
45
+ removed in future versions.
46
+ - Updated README and gem metadata to refer to Parlour as a type information
47
+ generator, rather than just an RBI generator
48
+
49
+ <details>
50
+ <summary>5.0.0 pre-releases</summary>
51
+
52
+ ## [5.0.0.beta.6] - 2020-10-04
53
+ ### Fixed
54
+ - Fixed collection types sometimes generating as `T::::Array`
55
+
56
+ ## [5.0.0.beta.5] - 2020-10-03
57
+ ### Added
58
+ - Added `Types::Generic` for user-defined generic types
59
+
60
+ ## [5.0.0.beta.4] - 2020-09-22
61
+ ### Added
62
+ - Added support for parsing type aliases from RBI
63
+ - Added conversion from RBI to RBS type aliases
64
+
65
+ ## [5.0.0.beta.3] - 2020-09-15
66
+ ### Changed
67
+ - Changed the RBS keyword warning to come from "RBS generation" rather than
68
+ "Type generalization"
69
+ - Added many more of RBS' keywords which are detected and prefixed with an
70
+ underscore to avoid syntax errors
71
+
72
+ ## [5.0.0.beta.2] - 2020-09-14
73
+ ### Added
74
+ - Added `Types::Type#describe` for simple text descriptions of types
75
+ - Added `Types::Self` for RBI's `T.self_type` or RBS' `self`
76
+
77
+ ### Fixed
78
+ - Fixed `RbiGenerator::Namespace#create_method`'s `returns:` kwarg only
79
+ accepting String types
80
+ - Fixed lack of spacing between argument lists and blocks in RBS
81
+ - Fixed RBS attributes not having comments
82
+
83
+ ## [5.0.0.beta.1] - 2020-09-13
84
+ ### Added
85
+ - Added RBS generation support! This includes:
86
+ - The new `RbsGenerator` class
87
+ - `RbsObject` and a set of subclasses representing different RBS components
88
+ - Added the `Types` module, which is used to describe types agnostic of the
89
+ underlying type system
90
+ - Added `RbiGenerator::Namespace#generalize_from_rbi!` to convert RBI string
91
+ types into `Types` types
92
+ - **Specifying types as strings is still currently supported, but may be
93
+ phased out in future, and should be avoided in new projects**.
94
+ - Added conversion from RBI to RBS type trees
95
+ - Added a couple of classes to deduplicate functionality between type systems:
96
+ - `TypedObject`, which `RbiObject` and `RbsObject` both inherit from
97
+ - `Generator`, which `RbiGenerator` and `RbsGenerator` both inherit from
98
+ - Added RBI type aliases
45
99
 
46
100
  ### Changed
47
101
  - `Parlour::RbiGenerator::Options` is now `Parlour::Options`. An alias exists
@@ -49,6 +103,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
49
103
  removed in future versions.
50
104
  - Updated README and gem metadata to refer to Parlour as a type information
51
105
  generator, rather than just an RBI generator
106
+ </details>
52
107
 
53
108
  ## [4.0.1] - 2020-08-05
54
109
  ### Fixed
data/README.md CHANGED
@@ -407,6 +407,8 @@ srb rbi gems
407
407
  srb rbi sorbet-typed
408
408
  ```
409
409
 
410
+ You should also regenerate the parlour.rbi file by running `bundle exec parlour`. Don't edit this file manually, as your changes will be overwritten!
411
+
410
412
  ## License
411
413
 
412
414
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/ci/check_rbi.sh ADDED
@@ -0,0 +1,9 @@
1
+ #!/bin/bash
2
+ # Checks that the RBI in rbi/parlour.rbi is up-to-date with committed changes.
3
+ # This is done by generating a new RBI and comparing it with the committed RBI.
4
+ set -ev
5
+
6
+ bundle install
7
+ mv rbi/parlour.rbi rbi/parlour-committed.rbi
8
+ bundle exec parlour
9
+ cmp -s rbi/parlour.rbi rbi/parlour-committed.rbi
@@ -10,6 +10,7 @@ module Parlour
10
10
  generator: Generator,
11
11
  name: String,
12
12
  final: T::Boolean,
13
+ sealed: T::Boolean,
13
14
  superclass: T.nilable(String),
14
15
  abstract: T::Boolean,
15
16
  block: T.nilable(T.proc.params(x: ClassNamespace).void)
@@ -21,13 +22,14 @@ module Parlour
21
22
  # @param generator [RbiGenerator] The current RbiGenerator.
22
23
  # @param name [String] The name of this class.
23
24
  # @param final [Boolean] Whether this namespace is final.
25
+ # @param sealed [Boolean] Whether this namespace is sealed.
24
26
  # @param superclass [String, nil] The superclass of this class, or nil if it doesn't
25
27
  # have one.
26
28
  # @param abstract [Boolean] A boolean indicating whether this class is abstract.
27
29
  # @param block A block which the new instance yields itself to.
28
30
  # @return [void]
29
- def initialize(generator, name, final, superclass, abstract, &block)
30
- super(generator, name, final, &block)
31
+ def initialize(generator, name, final, sealed, superclass, abstract, &block)
32
+ super(generator, name, final, sealed, &block)
31
33
  @superclass = superclass
32
34
  @abstract = abstract
33
35
  end
@@ -10,6 +10,7 @@ module Parlour
10
10
  generator: Generator,
11
11
  name: String,
12
12
  final: T::Boolean,
13
+ sealed: T::Boolean,
13
14
  enums: T::Array[T.any([String, String], String)],
14
15
  abstract: T::Boolean,
15
16
  block: T.nilable(T.proc.params(x: EnumClassNamespace).void)
@@ -21,12 +22,13 @@ module Parlour
21
22
  # @param generator [RbiGenerator] The current RbiGenerator.
22
23
  # @param name [String] The name of this class.
23
24
  # @param final [Boolean] Whether this namespace is final.
25
+ # @param sealed [Boolean] Whether this namespace is sealed.
24
26
  # @param enums [Array<(String, String), String>] The values of the enumeration.
25
27
  # @param abstract [Boolean] A boolean indicating whether this class is abstract.
26
28
  # @param block A block which the new instance yields itself to.
27
29
  # @return [void]
28
- def initialize(generator, name, final, enums, abstract, &block)
29
- super(generator, name, final, 'T::Enum', abstract, &block)
30
+ def initialize(generator, name, final, sealed, enums, abstract, &block)
31
+ super(generator, name, final, sealed, 'T::Enum', abstract, &block)
30
32
  @enums = enums
31
33
  end
32
34
 
@@ -10,24 +10,29 @@ module Parlour
10
10
  generator: Generator,
11
11
  name: String,
12
12
  final: T::Boolean,
13
+ sealed: T::Boolean,
13
14
  interface: T::Boolean,
15
+ abstract: T::Boolean,
14
16
  block: T.nilable(T.proc.params(x: ClassNamespace).void)
15
17
  ).void
16
18
  end
17
19
  # Creates a new module definition.
18
20
  # @note You should use {Namespace#create_module} rather than this directly.
19
- #
21
+ #
20
22
  # @param generator [RbiGenerator] The current RbiGenerator.
21
23
  # @param name [String] The name of this module.
22
24
  # @param final [Boolean] Whether this namespace is final.
25
+ # @param sealed [Boolean] Whether this namespace is sealed.
23
26
  # @param interface [Boolean] A boolean indicating whether this module is an
24
27
  # interface.
28
+ # @param abstract [Boolean] A boolean indicating whether this module is abstract.
25
29
  # @param block A block which the new instance yields itself to.
26
30
  # @return [void]
27
- def initialize(generator, name, final, interface, &block)
28
- super(generator, name, final, &block)
31
+ def initialize(generator, name, final, sealed, interface, abstract, &block)
32
+ super(generator, name, final, sealed, &block)
29
33
  @name = name
30
34
  @interface = interface
35
+ @abstract = abstract
31
36
  end
32
37
 
33
38
  sig do
@@ -41,10 +46,11 @@ module Parlour
41
46
  # @param indent_level [Integer] The indentation level to generate the lines at.
42
47
  # @param options [Options] The formatting options to use.
43
48
  # @return [Array<String>] The RBI lines, formatted as specified.
44
- def generate_rbi(indent_level, options)
49
+ def generate_rbi(indent_level, options)
45
50
  lines = generate_comments(indent_level, options)
46
51
  lines << options.indented(indent_level, "module #{name}")
47
52
  lines += [options.indented(indent_level + 1, "interface!"), ""] if interface
53
+ lines += [options.indented(indent_level + 1, "abstract!"), ""] if abstract
48
54
  lines += generate_body(indent_level + 1, options)
49
55
  lines << options.indented(indent_level, "end")
50
56
  end
@@ -54,6 +60,11 @@ module Parlour
54
60
  # @return [Boolean]
55
61
  attr_reader :interface
56
62
 
63
+ sig { returns(T::Boolean) }
64
+ # A boolean indicating whether this module is abstract or not.
65
+ # @return [Boolean]
66
+ attr_reader :abstract
67
+
57
68
  sig do
58
69
  override.params(
59
70
  others: T::Array[RbiGenerator::RbiObject]
@@ -61,7 +72,7 @@ module Parlour
61
72
  end
62
73
  # Given an array of {Namespace} instances, returns true if they may
63
74
  # be merged into this instance using {merge_into_self}. For instances to
64
- # be mergeable, they must either all be interfaces or all not be
75
+ # be mergeable, they must either all be interfaces or all not be
65
76
  # interfaces.
66
77
  #
67
78
  # @param others [Array<RbiGenerator::RbiObject>] An array of other {Namespace} instances.
@@ -75,7 +86,7 @@ module Parlour
75
86
  all_modules.map(&:interface).uniq.length == 1
76
87
  end
77
88
 
78
- sig do
89
+ sig do
79
90
  override.params(
80
91
  others: T::Array[RbiGenerator::RbiObject]
81
92
  ).void
@@ -93,7 +104,8 @@ module Parlour
93
104
  # Returns a human-readable brief string description of this module.
94
105
  # @return [String]
95
106
  def describe
96
- "Module #{name} - #{"interface, " if interface}#{children.length} " +
107
+ "Module #{name} - #{"interface, " if interface}" +
108
+ "#{"abstract, " if abstract}#{children.length} " +
97
109
  "children, #{includes.length} includes, #{extends.length} extends"
98
110
  end
99
111
 
@@ -27,6 +27,7 @@ module Parlour
27
27
  generator: Generator,
28
28
  name: T.nilable(String),
29
29
  final: T::Boolean,
30
+ sealed: T::Boolean,
30
31
  block: T.nilable(T.proc.params(x: Namespace).void)
31
32
  ).void
32
33
  end
@@ -37,13 +38,15 @@ module Parlour
37
38
  # @param generator [RbiGenerator] The current RbiGenerator.
38
39
  # @param name [String, nil] The name of this module.
39
40
  # @param final [Boolean] Whether this namespace is final.
41
+ # @param final [Boolean] Whether this namespace is sealed.
40
42
  # @param block A block which the new instance yields itself to.
41
43
  # @return [void]
42
- def initialize(generator, name = nil, final = false, &block)
44
+ def initialize(generator, name = nil, final = false, sealed = false, &block)
43
45
  super(generator, name || '<anonymous namespace>')
44
46
  @children = []
45
47
  @next_comments = []
46
48
  @final = final
49
+ @sealed = sealed
47
50
  yield_self(&block) if block
48
51
  end
49
52
 
@@ -52,6 +55,11 @@ module Parlour
52
55
  # @return [Boolean]
53
56
  attr_reader :final
54
57
 
58
+ sig { returns(T::Boolean) }
59
+ # Whether this namespace is sealed.
60
+ # @return [Boolean]
61
+ attr_reader :sealed
62
+
55
63
  sig { returns(T::Array[RbiObject]) }
56
64
  # The child {RbiObject} instances inside this namespace.
57
65
  # @return [Array<RbiObject>]
@@ -98,28 +106,31 @@ module Parlour
98
106
  )
99
107
  end
100
108
 
101
- sig { params(object: T.untyped, block: T.proc.params(x: Namespace).void).void }
102
- # Given a Class or Module object, generates all classes and modules in the
103
- # path to that object, then executes the given block on the last
104
- # {Namespace}. This should only be executed on the root namespace.
105
- # @param [Class, Module] object
109
+ sig { params(constant: Module, block: T.proc.params(x: Namespace).void).void }
110
+ # Given a constant (i.e. a Module instance), generates all classes
111
+ # and modules in the path to that object, then executes the given
112
+ # block on the last {Namespace}. This should only be executed on
113
+ # the root namespace.
114
+ # @param [Module] constant
106
115
  # @param block A block which the new {Namespace} yields itself to.
107
- def path(object, &block)
116
+ def path(constant, &block)
108
117
  raise 'only call #path on root' if is_a?(ClassNamespace) || is_a?(ModuleNamespace)
109
118
 
110
- parts = object.to_s.split('::')
111
- parts_with_types = parts.size.times.map do |i|
112
- [parts[i], Module.const_get(parts[0..i].join('::')).class]
113
- end
119
+ constant_name = T.let(Module.instance_method(:name).bind(constant).call, T.nilable(String))
120
+ raise 'given constant does not have a name' unless constant_name
114
121
 
115
122
  current_part = self
116
- parts_with_types.each do |(name, type)|
117
- if type == Class
123
+ constant_name.split('::').each_with_object([]) do |name, namespace|
124
+ namespace << name
125
+ instance = Module.const_get(namespace.join("::"))
126
+
127
+ case instance
128
+ when Class
118
129
  current_part = current_part.create_class(name)
119
- elsif type == Module
130
+ when Module
120
131
  current_part = current_part.create_module(name)
121
132
  else
122
- raise "unexpected type: path part #{name} is a #{type}"
133
+ raise "unexpected type: path part #{name} is a #{instance.class}"
123
134
  end
124
135
  end
125
136
 
@@ -151,6 +162,7 @@ module Parlour
151
162
  params(
152
163
  name: String,
153
164
  final: T::Boolean,
165
+ sealed: T::Boolean,
154
166
  superclass: T.nilable(String),
155
167
  abstract: T::Boolean,
156
168
  block: T.nilable(T.proc.params(x: ClassNamespace).void)
@@ -168,13 +180,14 @@ module Parlour
168
180
  #
169
181
  # @param name [String] The name of this class.
170
182
  # @param final [Boolean] Whether this namespace is final.
183
+ # @param sealed [Boolean] Whether this namespace is sealed.
171
184
  # @param superclass [String, nil] The superclass of this class, or nil if it doesn't
172
185
  # have one.
173
186
  # @param abstract [Boolean] A boolean indicating whether this class is abstract.
174
187
  # @param block A block which the new instance yields itself to.
175
188
  # @return [ClassNamespace]
176
- def create_class(name, final: false, superclass: nil, abstract: false, &block)
177
- new_class = ClassNamespace.new(generator, name, final, superclass, abstract, &block)
189
+ def create_class(name, final: false, sealed: false, superclass: nil, abstract: false, &block)
190
+ new_class = ClassNamespace.new(generator, name, final, sealed, superclass, abstract, &block)
178
191
  move_next_comments(new_class)
179
192
  children << new_class
180
193
  new_class
@@ -184,6 +197,7 @@ module Parlour
184
197
  params(
185
198
  name: String,
186
199
  final: T::Boolean,
200
+ sealed: T::Boolean,
187
201
  enums: T.nilable(T::Array[T.any([String, String], String)]),
188
202
  abstract: T::Boolean,
189
203
  block: T.nilable(T.proc.params(x: EnumClassNamespace).void)
@@ -196,12 +210,13 @@ module Parlour
196
210
  #
197
211
  # @param name [String] The name of this class.
198
212
  # @param final [Boolean] Whether this namespace is final.
213
+ # @param sealed [Boolean] Whether this namespace is sealed.
199
214
  # @param enums [Array<(String, String), String>] The values of the enumeration.
200
215
  # @param abstract [Boolean] A boolean indicating whether this class is abstract.
201
216
  # @param block A block which the new instance yields itself to.
202
217
  # @return [EnumClassNamespace]
203
- def create_enum_class(name, final: false, enums: nil, abstract: false, &block)
204
- new_enum_class = EnumClassNamespace.new(generator, name, final, enums || [], abstract, &block)
218
+ def create_enum_class(name, final: false, sealed: false, enums: nil, abstract: false, &block)
219
+ new_enum_class = EnumClassNamespace.new(generator, name, final, sealed, enums || [], abstract, &block)
205
220
  move_next_comments(new_enum_class)
206
221
  children << new_enum_class
207
222
  new_enum_class
@@ -211,6 +226,7 @@ module Parlour
211
226
  params(
212
227
  name: String,
213
228
  final: T::Boolean,
229
+ sealed: T::Boolean,
214
230
  props: T.nilable(T::Array[StructProp]),
215
231
  abstract: T::Boolean,
216
232
  block: T.nilable(T.proc.params(x: StructClassNamespace).void)
@@ -225,12 +241,13 @@ module Parlour
225
241
  #
226
242
  # @param name [String] The name of this class.
227
243
  # @param final [Boolean] Whether this namespace is final.
244
+ # @param sealed [Boolean] Whether this namespace is sealed.
228
245
  # @param props [Array<StructProp>] The props of the struct.
229
246
  # @param abstract [Boolean] A boolean indicating whether this class is abstract.
230
247
  # @param block A block which the new instance yields itself to.
231
248
  # @return [EnumClassNamespace]
232
- def create_struct_class(name, final: false, props: nil, abstract: false, &block)
233
- new_struct_class = StructClassNamespace.new(generator, name, final, props || [], abstract, &block)
249
+ def create_struct_class(name, final: false, sealed: false, props: nil, abstract: false, &block)
250
+ new_struct_class = StructClassNamespace.new(generator, name, final, sealed, props || [], abstract, &block)
234
251
  move_next_comments(new_struct_class)
235
252
  children << new_struct_class
236
253
  new_struct_class
@@ -240,7 +257,9 @@ module Parlour
240
257
  params(
241
258
  name: String,
242
259
  final: T::Boolean,
260
+ sealed: T::Boolean,
243
261
  interface: T::Boolean,
262
+ abstract: T::Boolean,
244
263
  block: T.nilable(T.proc.params(x: ClassNamespace).void)
245
264
  ).returns(ModuleNamespace)
246
265
  end
@@ -256,12 +275,15 @@ module Parlour
256
275
  #
257
276
  # @param name [String] The name of this module.
258
277
  # @param final [Boolean] Whether this namespace is final.
278
+ # @param sealed [Boolean] Whether this namespace is sealed.
259
279
  # @param interface [Boolean] A boolean indicating whether this module is an
260
280
  # interface.
281
+ # @param abstract [Boolean] A boolean indicating whether this module is
282
+ # abstract.
261
283
  # @param block A block which the new instance yields itself to.
262
284
  # @return [ModuleNamespace]
263
- def create_module(name, final: false, interface: false, &block)
264
- new_module = ModuleNamespace.new(generator, name, final, interface, &block)
285
+ def create_module(name, final: false, sealed: false, interface: false, abstract: false, &block)
286
+ new_module = ModuleNamespace.new(generator, name, final, sealed, interface, abstract, &block)
265
287
  move_next_comments(new_module)
266
288
  children << new_module
267
289
  new_module
@@ -657,6 +679,7 @@ module Parlour
657
679
  result = []
658
680
 
659
681
  result += [options.indented(indent_level, 'final!'), ''] if final
682
+ result += [options.indented(indent_level, 'sealed!'), ''] if sealed
660
683
 
661
684
  # Split away the eigen constants; these need to be put in a
662
685
  # "class << self" block later