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.
@@ -39,7 +39,7 @@ module Parlour
39
39
  @name = name
40
40
 
41
41
  prefix = /^(\*\*|\*|\&)?/.match(name)&.captures&.first || ''
42
- @kind = PREFIXES.rassoc(prefix).first
42
+ @kind = T.must(PREFIXES.rassoc(prefix)).first
43
43
 
44
44
  @kind = :keyword if kind == :normal && name.end_with?(':')
45
45
 
@@ -123,12 +123,12 @@ module Parlour
123
123
  end
124
124
 
125
125
  # A mapping of {kind} values to the characteristic prefixes each kind has.
126
- PREFIXES = {
126
+ PREFIXES = T.let({
127
127
  normal: '',
128
128
  splat: '*',
129
129
  double_splat: '**',
130
130
  block: '&'
131
- }.freeze
131
+ }.freeze, T::Hash[Symbol, String])
132
132
 
133
133
  sig { void }
134
134
  def generalize_from_rbi!
@@ -11,6 +11,7 @@ module Parlour
11
11
  generator: Generator,
12
12
  name: String,
13
13
  final: T::Boolean,
14
+ sealed: T::Boolean,
14
15
  props: T::Array[StructProp],
15
16
  abstract: T::Boolean,
16
17
  block: T.nilable(T.proc.params(x: StructClassNamespace).void)
@@ -22,12 +23,13 @@ module Parlour
22
23
  # @param generator [RbiGenerator] The current RbiGenerator.
23
24
  # @param name [String] The name of this class.
24
25
  # @param final [Boolean] Whether this namespace is final.
26
+ # @param sealed [Boolean] Whether this namespace is sealed.
25
27
  # @param props [Array<StructProp>] The props of the struct.
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, props, abstract, &block)
30
- super(generator, name, final, 'T::Struct', abstract, &block)
31
+ def initialize(generator, name, final, sealed, props, abstract, &block)
32
+ super(generator, name, final, sealed, 'T::Struct', abstract, &block)
31
33
  @props = props
32
34
  end
33
35
 
@@ -112,9 +112,9 @@ module Parlour
112
112
  attr_reader :redaction
113
113
 
114
114
  # The optional properties available on instances of this class.
115
- EXTRA_PROPERTIES = %i{
115
+ EXTRA_PROPERTIES = T.let(%i{
116
116
  optional enum dont_store foreign default factory immutable array override redaction
117
- }
117
+ }, T::Array[Symbol])
118
118
 
119
119
  sig { returns(String) }
120
120
  # Returns the +prop+ call required to create this property.
@@ -89,7 +89,7 @@ module Parlour
89
89
 
90
90
  # Merge the first signature line, and indent & concat the rest
91
91
  first_line, *rest_lines = *partial_sig_lines
92
- this_sig_lines[0] += first_line
92
+ this_sig_lines[0] = T.unsafe(this_sig_lines[0]) + first_line
93
93
  rest_lines&.each do |line|
94
94
  this_sig_lines << ' ' * definition.length + options.indented(indent_level, line)
95
95
  end
@@ -158,6 +158,7 @@ module Parlour
158
158
 
159
159
  name, superclass, body = *node
160
160
  final = body_has_modifier?(body, :final!)
161
+ sealed = body_has_modifier?(body, :sealed!)
161
162
  abstract = body_has_modifier?(body, :abstract!)
162
163
  includes, extends = body ? body_includes_and_extends(body) : [[], []]
163
164
 
@@ -170,6 +171,7 @@ module Parlour
170
171
  generator,
171
172
  n.to_s,
172
173
  false,
174
+ false,
173
175
  )
174
176
  target.children << new_obj if target
175
177
  target = new_obj
@@ -233,6 +235,7 @@ module Parlour
233
235
  generator,
234
236
  this_name.to_s,
235
237
  final,
238
+ sealed,
236
239
  props,
237
240
  abstract,
238
241
  )
@@ -256,6 +259,7 @@ module Parlour
256
259
  generator,
257
260
  this_name.to_s,
258
261
  final,
262
+ sealed,
259
263
  enums,
260
264
  abstract,
261
265
  )
@@ -264,6 +268,7 @@ module Parlour
264
268
  generator,
265
269
  this_name.to_s,
266
270
  final,
271
+ sealed,
267
272
  node_to_s(superclass),
268
273
  abstract,
269
274
  )
@@ -275,7 +280,7 @@ module Parlour
275
280
 
276
281
  if target
277
282
  target.children << final_obj
278
- [top_level]
283
+ [T.must(top_level)]
279
284
  else
280
285
  [final_obj]
281
286
  end
@@ -283,7 +288,9 @@ module Parlour
283
288
  parse_err 'cannot declare modules in an eigenclass', node if is_within_eigenclass
284
289
 
285
290
  name, body = *node
291
+ abstract = body_has_modifier?(body, :abstract!)
286
292
  final = body_has_modifier?(body, :final!)
293
+ sealed = body_has_modifier?(body, :sealed!)
287
294
  interface = body_has_modifier?(body, :interface!)
288
295
  includes, extends = body ? body_includes_and_extends(body) : [[], []]
289
296
 
@@ -296,6 +303,7 @@ module Parlour
296
303
  generator,
297
304
  n.to_s,
298
305
  false,
306
+ false,
299
307
  )
300
308
  target.children << new_obj if target
301
309
  target = new_obj
@@ -306,7 +314,9 @@ module Parlour
306
314
  generator,
307
315
  this_name.to_s,
308
316
  final,
317
+ sealed,
309
318
  interface,
319
+ abstract,
310
320
  ) do |m|
311
321
  m.children.concat(parse_path_to_object(path.child(1))) if body
312
322
  m.create_includes(includes)
@@ -315,7 +325,7 @@ module Parlour
315
325
 
316
326
  if target
317
327
  target.children << final_obj
318
- [top_level]
328
+ [T.must(top_level)]
319
329
  else
320
330
  [final_obj]
321
331
  end
@@ -721,7 +731,7 @@ module Parlour
721
731
  end
722
732
 
723
733
  sig { params(node: Parser::AST::Node).returns(Types::Type) }
724
- # Given an AST node representing an RBI type (such as 'T::Array[String]'),
734
+ # Given an AST node representing an RBI type (such as 'T::Array[String]'),
725
735
  # parses it into a generic type.
726
736
  #
727
737
  # @param [Parser::AST::Node] node
@@ -736,9 +746,9 @@ module Parlour
736
746
  names = constant_names(target)
737
747
  known_single_element_collections = [:Array, :Set, :Range, :Enumerator, :Enumerable]
738
748
 
739
- if names.length == 2 && names[0] == :T &&
749
+ if names.length == 2 && names[0] == :T &&
740
750
  known_single_element_collections.include?(names[1])
741
-
751
+
742
752
  parse_err "no type in T::#{names[1]}[...]", node if args.nil? || args.empty?
743
753
  parse_err "too many types in T::#{names[1]}[...]", node unless args.length == 1
744
754
  return T.must(Types.const_get(T.must(names[1]))).new(parse_node_to_type(T.must(args.first)))
@@ -749,9 +759,17 @@ module Parlour
749
759
  parse_node_to_type(args[0]), parse_node_to_type(args[1])
750
760
  )
751
761
  else
752
- # TODO
753
- warning "user-defined generic types not implemented, treating #{names.last} as untyped", node
754
- return Types::Untyped.new
762
+ type = names.join('::')
763
+ if args.nil?
764
+ parse_err(
765
+ "user defined generic '#{type}' requires at least one type parameter",
766
+ node
767
+ )
768
+ end
769
+ return Types::Generic.new(
770
+ type,
771
+ args.map { |arg| parse_node_to_type(arg) }
772
+ )
755
773
  end
756
774
  end
757
775
 
@@ -760,7 +778,7 @@ module Parlour
760
778
  # something pretty cursed with procs to break this
761
779
  # This checks for (send (send (send (const nil :T) :proc) ...) ...)
762
780
  # That's the right amount of nesting for T.proc.params(...).returns(...)
763
- if node.to_a[0].type == :send &&
781
+ if node.to_a[0].type == :send &&
764
782
  node.to_a[0].to_a[0].type == :send &&
765
783
  node.to_a[0].to_a[0].to_a[1] == :proc &&
766
784
  node.to_a[0].to_a[0].to_a[0].type == :const &&
@@ -797,7 +815,7 @@ module Parlour
797
815
  # The other options for a valid call are all "T.something" methods
798
816
  parse_err "unexpected call #{node_to_s(node).inspect} in type", node \
799
817
  unless target.type == :const && target.to_a == [nil, :T]
800
-
818
+
801
819
  case message
802
820
  when :nilable
803
821
  parse_err 'no argument to T.nilable', node if args.nil? || args.empty?
@@ -828,7 +846,7 @@ module Parlour
828
846
  else
829
847
  warning "unknown method T.#{message}, treating as untyped", node
830
848
  Types::Untyped.new
831
- end
849
+ end
832
850
  when :const
833
851
  # Special case: T::Boolean
834
852
  if constant_names(node) == [:T, :Boolean]
@@ -20,7 +20,7 @@ module Parlour
20
20
  # @return [Plugin, nil]
21
21
  attr_reader :generated_by
22
22
 
23
- sig { returns(String) }
23
+ sig { returns(String).checked(:never) }
24
24
  # The name of this object.
25
25
  # @return [String]
26
26
  attr_reader :name
@@ -84,4 +84,4 @@ module Parlour
84
84
  : []
85
85
  end
86
86
  end
87
- end
87
+ end
data/lib/parlour/types.rb CHANGED
@@ -196,6 +196,45 @@ module Parlour
196
196
  end
197
197
  end
198
198
 
199
+ # A user-defined generic class with an arbitrary number of type
200
+ # parameters. This class assumes at least one type_param is
201
+ # provided, otherwise output will have empty type param lists.
202
+ class Generic < Type
203
+ sig { params(type: TypeLike, type_params: T::Array[TypeLike]).void }
204
+ def initialize(type, type_params)
205
+ @type = to_type(type)
206
+ @type_params = type_params.map { |p| to_type(p) }
207
+ end
208
+
209
+ sig { params(other: Object).returns(T::Boolean) }
210
+ def ==(other)
211
+ self.class === other &&
212
+ type == other.type &&
213
+ type_params == other.type_params
214
+ end
215
+
216
+ sig { returns(Type) }
217
+ attr_reader :type
218
+
219
+ sig { returns(T::Array[Type]) }
220
+ attr_reader :type_params
221
+
222
+ sig { override.returns(String) }
223
+ def generate_rbi
224
+ "#{type.generate_rbi}[#{type_params.map(&:generate_rbi).join(', ')}]"
225
+ end
226
+
227
+ sig { override.returns(String) }
228
+ def generate_rbs
229
+ "#{type.generate_rbs}[#{type_params.map(&:generate_rbs).join(', ')}]"
230
+ end
231
+
232
+ sig { override.returns(String) }
233
+ def describe
234
+ "#{type.describe}<#{type_params.map(&:describe).join(', ')}>"
235
+ end
236
+ end
237
+
199
238
  class SingleElementCollection < Type
200
239
  abstract!
201
240
 
@@ -217,7 +256,7 @@ module Parlour
217
256
 
218
257
  sig { override.returns(String) }
219
258
  def generate_rbs
220
- "#{collection_name}[#{element.generate_rbs}]"
259
+ "::#{collection_name}[#{element.generate_rbs}]"
221
260
  end
222
261
 
223
262
  sig { override.returns(String) }
@@ -230,7 +269,7 @@ module Parlour
230
269
  class Array < SingleElementCollection
231
270
  sig { override.returns(String) }
232
271
  def collection_name
233
- '::Array'
272
+ 'Array'
234
273
  end
235
274
 
236
275
  sig { params(other: Object).returns(T::Boolean) }
@@ -243,7 +282,7 @@ module Parlour
243
282
  class Set < SingleElementCollection
244
283
  sig { override.returns(String) }
245
284
  def collection_name
246
- '::Set'
285
+ 'Set'
247
286
  end
248
287
 
249
288
  sig { params(other: Object).returns(T::Boolean) }
@@ -256,7 +295,7 @@ module Parlour
256
295
  class Range < SingleElementCollection
257
296
  sig { override.returns(String) }
258
297
  def collection_name
259
- '::Range'
298
+ 'Range'
260
299
  end
261
300
 
262
301
  sig { params(other: Object).returns(T::Boolean) }
@@ -269,7 +308,7 @@ module Parlour
269
308
  class Enumerable < SingleElementCollection
270
309
  sig { override.returns(String) }
271
310
  def collection_name
272
- '::Enumerable'
311
+ 'Enumerable'
273
312
  end
274
313
 
275
314
  sig { params(other: Object).returns(T::Boolean) }
@@ -282,7 +321,7 @@ module Parlour
282
321
  class Enumerator < SingleElementCollection
283
322
  sig { override.returns(String) }
284
323
  def collection_name
285
- '::Enumerator'
324
+ 'Enumerator'
286
325
  end
287
326
 
288
327
  sig { params(other: Object).returns(T::Boolean) }
@@ -436,9 +475,9 @@ module Parlour
436
475
  def describe
437
476
  "self"
438
477
  end
439
- end
478
+ end
440
479
 
441
- # The explicit lack of a type.
480
+ # The explicit lack of a type.
442
481
  class Untyped < Type
443
482
  sig { params(other: Object).returns(T::Boolean) }
444
483
  def ==(other)
@@ -487,9 +526,9 @@ module Parlour
487
526
  def ==(other)
488
527
  Parameter === other && name == other.name && type == other.type &&
489
528
  default == other.default
490
- end
529
+ end
491
530
  end
492
-
531
+
493
532
  sig { params(parameters: T::Array[Parameter], return_type: T.nilable(TypeLike)).void }
494
533
  def initialize(parameters, return_type)
495
534
  @parameters = parameters
@@ -536,4 +575,4 @@ module Parlour
536
575
  end
537
576
  end
538
577
  end
539
-
578
+
@@ -1,5 +1,5 @@
1
1
  # typed: strong
2
2
  module Parlour
3
3
  # The library version.
4
- VERSION = '5.0.0.beta.4'
4
+ VERSION = '6.0.1'
5
5
  end
data/parlour.gemspec CHANGED
@@ -16,7 +16,7 @@ Gem::Specification.new do |spec|
16
16
  # Specify which files should be added to the gem when it is released.
17
17
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
18
18
  spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
19
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|sorbet)/}) }
19
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|sorbet|rbi)/}) }
20
20
  end
21
21
  spec.bindir = "exe"
22
22
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
@@ -32,4 +32,5 @@ Gem::Specification.new do |spec|
32
32
  spec.add_development_dependency "rspec", "~> 3.0"
33
33
  spec.add_development_dependency "sorbet"
34
34
  spec.add_development_dependency "simplecov"
35
+ spec.add_development_dependency "yard"
35
36
  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: 5.0.0.beta.4
4
+ version: 6.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Christiansen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-09-22 00:00:00.000000000 Z
11
+ date: 2021-07-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sorbet-runtime
@@ -136,6 +136,20 @@ dependencies:
136
136
  - - ">="
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: yard
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
139
153
  description:
140
154
  email:
141
155
  - hello@aaronc.cc
@@ -146,16 +160,17 @@ extra_rdoc_files: []
146
160
  files:
147
161
  - ".github/ISSUE_TEMPLATE/bug-report.md"
148
162
  - ".github/ISSUE_TEMPLATE/feature-request.md"
163
+ - ".github/workflows/ruby.yml"
149
164
  - ".gitignore"
150
165
  - ".parlour"
151
166
  - ".rspec"
152
- - ".travis.yml"
153
167
  - CHANGELOG.md
154
168
  - CODE_OF_CONDUCT.md
155
169
  - Gemfile
156
170
  - LICENSE.txt
157
171
  - README.md
158
172
  - Rakefile
173
+ - ci/check_rbi.sh
159
174
  - exe/parlour
160
175
  - lib/parlour.rb
161
176
  - lib/parlour/conflict_resolver.rb
@@ -208,7 +223,6 @@ files:
208
223
  - lib/parlour/version.rb
209
224
  - parlour.gemspec
210
225
  - plugin_examples/foobar_plugin.rb
211
- - rbi/parlour.rbi
212
226
  homepage: https://github.com/AaronC81/parlour
213
227
  licenses:
214
228
  - MIT
@@ -224,11 +238,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
224
238
  version: '0'
225
239
  required_rubygems_version: !ruby/object:Gem::Requirement
226
240
  requirements:
227
- - - ">"
241
+ - - ">="
228
242
  - !ruby/object:Gem::Version
229
- version: 1.3.1
243
+ version: '0'
230
244
  requirements: []
231
- rubygems_version: 3.0.3
245
+ rubygems_version: 3.2.0.rc.1
232
246
  signing_key:
233
247
  specification_version: 4
234
248
  summary: A type information generator, merger and parser for Sorbet and Ruby 3/Steep