parlour 5.0.0.beta.4 → 5.0.0.beta.5
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 +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/parlour/type_parser.rb +17 -9
- data/lib/parlour/types.rb +44 -5
- data/lib/parlour/version.rb +1 -1
- data/rbi/parlour.rbi +23 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 954aae86deb14e48d6fd3e1491bfc90e511e06f2339697b41f06bb137f93ae84
|
4
|
+
data.tar.gz: 5720e034546be195412725a2c5cb58dc14325485eb9720491db4b29b49e83026
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c2ff5915c768f8fa5432b0fcb7f0ae89fb3385c6a500ab9f46dedab301f44084620203219e7bac044b48ec2659b9ca729b2d5f2ce0b15e6222c9d3ddec4ca2a2
|
7
|
+
data.tar.gz: e0edbaf4e923f7b80956072ebc82e1ef1075e6791e8ef7e147da0b533709b62e421e786a0dbd36b8bd11473c59b5f302972deb91d7590d4acae69caebcac1887
|
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,10 @@ 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.5] - 2020-10-03
|
7
|
+
### Added
|
8
|
+
- Added `Types::Generic` for user-defined generic types
|
9
|
+
|
6
10
|
## [5.0.0.beta.4] - 2020-09-22
|
7
11
|
### Added
|
8
12
|
- Added support for parsing type aliases from RBI
|
data/lib/parlour/type_parser.rb
CHANGED
@@ -721,7 +721,7 @@ module Parlour
|
|
721
721
|
end
|
722
722
|
|
723
723
|
sig { params(node: Parser::AST::Node).returns(Types::Type) }
|
724
|
-
# Given an AST node representing an RBI type (such as 'T::Array[String]'),
|
724
|
+
# Given an AST node representing an RBI type (such as 'T::Array[String]'),
|
725
725
|
# parses it into a generic type.
|
726
726
|
#
|
727
727
|
# @param [Parser::AST::Node] node
|
@@ -736,9 +736,9 @@ module Parlour
|
|
736
736
|
names = constant_names(target)
|
737
737
|
known_single_element_collections = [:Array, :Set, :Range, :Enumerator, :Enumerable]
|
738
738
|
|
739
|
-
if names.length == 2 && names[0] == :T &&
|
739
|
+
if names.length == 2 && names[0] == :T &&
|
740
740
|
known_single_element_collections.include?(names[1])
|
741
|
-
|
741
|
+
|
742
742
|
parse_err "no type in T::#{names[1]}[...]", node if args.nil? || args.empty?
|
743
743
|
parse_err "too many types in T::#{names[1]}[...]", node unless args.length == 1
|
744
744
|
return T.must(Types.const_get(T.must(names[1]))).new(parse_node_to_type(T.must(args.first)))
|
@@ -749,9 +749,17 @@ module Parlour
|
|
749
749
|
parse_node_to_type(args[0]), parse_node_to_type(args[1])
|
750
750
|
)
|
751
751
|
else
|
752
|
-
|
753
|
-
|
754
|
-
|
752
|
+
type = names.join('::')
|
753
|
+
if args.nil?
|
754
|
+
parse_err(
|
755
|
+
"user defined generic '#{type}' requires at least one type parameter",
|
756
|
+
node
|
757
|
+
)
|
758
|
+
end
|
759
|
+
return Types::Generic.new(
|
760
|
+
type,
|
761
|
+
args.map { |arg| parse_node_to_type(arg) }
|
762
|
+
)
|
755
763
|
end
|
756
764
|
end
|
757
765
|
|
@@ -760,7 +768,7 @@ module Parlour
|
|
760
768
|
# something pretty cursed with procs to break this
|
761
769
|
# This checks for (send (send (send (const nil :T) :proc) ...) ...)
|
762
770
|
# That's the right amount of nesting for T.proc.params(...).returns(...)
|
763
|
-
if node.to_a[0].type == :send &&
|
771
|
+
if node.to_a[0].type == :send &&
|
764
772
|
node.to_a[0].to_a[0].type == :send &&
|
765
773
|
node.to_a[0].to_a[0].to_a[1] == :proc &&
|
766
774
|
node.to_a[0].to_a[0].to_a[0].type == :const &&
|
@@ -797,7 +805,7 @@ module Parlour
|
|
797
805
|
# The other options for a valid call are all "T.something" methods
|
798
806
|
parse_err "unexpected call #{node_to_s(node).inspect} in type", node \
|
799
807
|
unless target.type == :const && target.to_a == [nil, :T]
|
800
|
-
|
808
|
+
|
801
809
|
case message
|
802
810
|
when :nilable
|
803
811
|
parse_err 'no argument to T.nilable', node if args.nil? || args.empty?
|
@@ -828,7 +836,7 @@ module Parlour
|
|
828
836
|
else
|
829
837
|
warning "unknown method T.#{message}, treating as untyped", node
|
830
838
|
Types::Untyped.new
|
831
|
-
end
|
839
|
+
end
|
832
840
|
when :const
|
833
841
|
# Special case: T::Boolean
|
834
842
|
if constant_names(node) == [:T, :Boolean]
|
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
|
|
@@ -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
|
+
|
data/lib/parlour/version.rb
CHANGED
data/rbi/parlour.rbi
CHANGED
@@ -427,6 +427,29 @@ module Parlour
|
|
427
427
|
def describe; end
|
428
428
|
end
|
429
429
|
|
430
|
+
class Generic < Type
|
431
|
+
sig { params(type: TypeLike, type_params: T::Array[TypeLike]).void }
|
432
|
+
def initialize(type, type_params); end
|
433
|
+
|
434
|
+
sig { params(other: Object).returns(T::Boolean) }
|
435
|
+
def ==(other); end
|
436
|
+
|
437
|
+
sig { returns(Type) }
|
438
|
+
attr_reader :type
|
439
|
+
|
440
|
+
sig { returns(T::Array[Type]) }
|
441
|
+
attr_reader :type_params
|
442
|
+
|
443
|
+
sig { override.returns(String) }
|
444
|
+
def generate_rbi; end
|
445
|
+
|
446
|
+
sig { override.returns(String) }
|
447
|
+
def generate_rbs; end
|
448
|
+
|
449
|
+
sig { override.returns(String) }
|
450
|
+
def describe; end
|
451
|
+
end
|
452
|
+
|
430
453
|
class SingleElementCollection < Type
|
431
454
|
abstract!
|
432
455
|
|
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
|
+
version: 5.0.0.beta.5
|
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-
|
11
|
+
date: 2020-10-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sorbet-runtime
|