parlour 5.0.0 → 7.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +46 -0
- data/.parlour +4 -2
- data/CHANGELOG.md +33 -0
- data/exe/parlour +2 -3
- data/lib/parlour/conflict_resolver.rb +18 -14
- data/lib/parlour/debugging.rb +29 -16
- data/lib/parlour/mixin/searchable.rb +54 -0
- data/lib/parlour/rbi_generator/arbitrary.rb +3 -6
- data/lib/parlour/rbi_generator/attribute.rb +9 -0
- data/lib/parlour/rbi_generator/class_namespace.rb +6 -7
- data/lib/parlour/rbi_generator/constant.rb +3 -6
- data/lib/parlour/rbi_generator/enum_class_namespace.rb +7 -0
- data/lib/parlour/rbi_generator/extend.rb +5 -8
- data/lib/parlour/rbi_generator/include.rb +5 -8
- data/lib/parlour/rbi_generator/method.rb +15 -10
- data/lib/parlour/rbi_generator/module_namespace.rb +7 -9
- data/lib/parlour/rbi_generator/namespace.rb +27 -24
- data/lib/parlour/rbi_generator/parameter.rb +12 -0
- data/lib/parlour/rbi_generator/rbi_object.rb +0 -5
- data/lib/parlour/rbi_generator/struct_class_namespace.rb +7 -0
- data/lib/parlour/rbi_generator/type_alias.rb +5 -8
- data/lib/parlour/rbi_generator.rb +1 -16
- data/lib/parlour/rbs_generator/arbitrary.rb +3 -6
- data/lib/parlour/rbs_generator/attribute.rb +8 -0
- data/lib/parlour/rbs_generator/class_namespace.rb +5 -9
- data/lib/parlour/rbs_generator/constant.rb +3 -6
- data/lib/parlour/rbs_generator/extend.rb +3 -6
- data/lib/parlour/rbs_generator/include.rb +3 -6
- data/lib/parlour/rbs_generator/interface_namespace.rb +5 -5
- data/lib/parlour/rbs_generator/method.rb +6 -7
- data/lib/parlour/rbs_generator/method_signature.rb +13 -0
- data/lib/parlour/rbs_generator/module_namespace.rb +5 -6
- data/lib/parlour/rbs_generator/namespace.rb +8 -8
- data/lib/parlour/rbs_generator/rbs_object.rb +0 -5
- data/lib/parlour/rbs_generator/type_alias.rb +3 -6
- data/lib/parlour/type_loader.rb +6 -1
- data/lib/parlour/type_parser.rb +2 -2
- data/lib/parlour/typed_object.rb +90 -5
- data/lib/parlour/version.rb +1 -1
- data/lib/parlour.rb +2 -0
- data/parlour.gemspec +2 -1
- metadata +19 -5
- data/.travis.yml +0 -32
- data/rbi/parlour.rbi +0 -1896
@@ -5,6 +5,7 @@ module Parlour
|
|
5
5
|
# {RbiGenerator#root}.
|
6
6
|
class Namespace < RbiObject
|
7
7
|
extend T::Sig
|
8
|
+
extend T::Generic
|
8
9
|
|
9
10
|
sig do
|
10
11
|
override.overridable.params(
|
@@ -60,11 +61,14 @@ module Parlour
|
|
60
61
|
# @return [Boolean]
|
61
62
|
attr_reader :sealed
|
62
63
|
|
63
|
-
sig { returns(T::Array[RbiObject]) }
|
64
|
+
sig { override.returns(T::Array[RbiObject]).checked(:never) }
|
64
65
|
# The child {RbiObject} instances inside this namespace.
|
65
66
|
# @return [Array<RbiObject>]
|
66
67
|
attr_reader :children
|
67
68
|
|
69
|
+
include Mixin::Searchable
|
70
|
+
Child = type_member {{ fixed: RbiObject }}
|
71
|
+
|
68
72
|
sig { returns(T::Array[RbiGenerator::Extend]) }
|
69
73
|
# The {RbiGenerator::Extend} objects from {children}.
|
70
74
|
# @return [Array<RbiGenerator::Extend>]
|
@@ -106,28 +110,31 @@ module Parlour
|
|
106
110
|
)
|
107
111
|
end
|
108
112
|
|
109
|
-
sig { params(
|
110
|
-
# Given a
|
111
|
-
# path to that object, then executes the given
|
112
|
-
# {Namespace}. This should only be executed on
|
113
|
-
#
|
113
|
+
sig { params(constant: Module, block: T.proc.params(x: Namespace).void).void }
|
114
|
+
# Given a constant (i.e. a Module instance), generates all classes
|
115
|
+
# and modules in the path to that object, then executes the given
|
116
|
+
# block on the last {Namespace}. This should only be executed on
|
117
|
+
# the root namespace.
|
118
|
+
# @param [Module] constant
|
114
119
|
# @param block A block which the new {Namespace} yields itself to.
|
115
|
-
def path(
|
120
|
+
def path(constant, &block)
|
116
121
|
raise 'only call #path on root' if is_a?(ClassNamespace) || is_a?(ModuleNamespace)
|
117
122
|
|
118
|
-
|
119
|
-
|
120
|
-
[parts[i], Module.const_get(parts[0..i].join('::')).class]
|
121
|
-
end
|
123
|
+
constant_name = T.let(Module.instance_method(:name).bind(constant).call, T.nilable(String))
|
124
|
+
raise 'given constant does not have a name' unless constant_name
|
122
125
|
|
123
126
|
current_part = self
|
124
|
-
|
125
|
-
|
127
|
+
constant_name.split('::').each_with_object([]) do |name, namespace|
|
128
|
+
namespace << name
|
129
|
+
instance = Module.const_get(namespace.join("::"))
|
130
|
+
|
131
|
+
case instance
|
132
|
+
when Class
|
126
133
|
current_part = current_part.create_class(name)
|
127
|
-
|
134
|
+
when Module
|
128
135
|
current_part = current_part.create_module(name)
|
129
136
|
else
|
130
|
-
raise "unexpected type: path part #{name} is a #{
|
137
|
+
raise "unexpected type: path part #{name} is a #{instance.class}"
|
131
138
|
end
|
132
139
|
end
|
133
140
|
|
@@ -644,20 +651,16 @@ module Parlour
|
|
644
651
|
end
|
645
652
|
end
|
646
653
|
|
647
|
-
sig { override.overridable.returns(String) }
|
648
|
-
# Returns a human-readable brief string description of this namespace.
|
649
|
-
#
|
650
|
-
# @return [String]
|
651
|
-
def describe
|
652
|
-
"Namespace #{name} - #{children.length} children, #{includes.length} " +
|
653
|
-
"includes, #{extends.length} extends, #{constants.length} constants"
|
654
|
-
end
|
655
|
-
|
656
654
|
sig { override.void }
|
657
655
|
def generalize_from_rbi!
|
658
656
|
children.each(&:generalize_from_rbi!)
|
659
657
|
end
|
660
658
|
|
659
|
+
sig { override.returns(T::Array[T.any(Symbol, T::Hash[Symbol, String])]) }
|
660
|
+
def describe_attrs
|
661
|
+
[:children, :final, :sealed]
|
662
|
+
end
|
663
|
+
|
661
664
|
private
|
662
665
|
|
663
666
|
sig do
|
@@ -134,6 +134,18 @@ module Parlour
|
|
134
134
|
def generalize_from_rbi!
|
135
135
|
@type = TypeParser.parse_single_type(@type) if String === @type
|
136
136
|
end
|
137
|
+
|
138
|
+
sig { returns(String) }
|
139
|
+
def describe_in_method
|
140
|
+
t = type
|
141
|
+
t = t.is_a?(String) ? t : t.describe
|
142
|
+
|
143
|
+
if default
|
144
|
+
"#{name}: #{t} = #{default}"
|
145
|
+
else
|
146
|
+
"#{name}: #{t}"
|
147
|
+
end
|
148
|
+
end
|
137
149
|
end
|
138
150
|
end
|
139
151
|
end
|
@@ -69,11 +69,6 @@ module Parlour
|
|
69
69
|
# @return [void]
|
70
70
|
def merge_into_self(others); end
|
71
71
|
|
72
|
-
sig { override.overridable.returns(String) }
|
73
|
-
def describe
|
74
|
-
'RBI object'
|
75
|
-
end
|
76
|
-
|
77
72
|
sig { abstract.void }
|
78
73
|
# Assuming that the types throughout this object and its children have
|
79
74
|
# been specified as RBI-style types, generalises them into type instances
|
@@ -6,6 +6,8 @@ module Parlour
|
|
6
6
|
class StructClassNamespace < ClassNamespace
|
7
7
|
extend T::Sig
|
8
8
|
|
9
|
+
Child = type_member {{ fixed: RbiObject }}
|
10
|
+
|
9
11
|
sig do
|
10
12
|
params(
|
11
13
|
generator: Generator,
|
@@ -107,6 +109,11 @@ module Parlour
|
|
107
109
|
|
108
110
|
props.each(&:generalize_from_rbi!)
|
109
111
|
end
|
112
|
+
|
113
|
+
sig { override.returns(T::Array[T.any(Symbol, T::Hash[Symbol, String])]) }
|
114
|
+
def describe_attrs
|
115
|
+
super + [{props: "(#{props.map(&:name)})"}]
|
116
|
+
end
|
110
117
|
end
|
111
118
|
end
|
112
119
|
end
|
@@ -84,18 +84,15 @@ module Parlour
|
|
84
84
|
# We don't need to change anything! We only merge identical type alias
|
85
85
|
end
|
86
86
|
|
87
|
-
sig { override.returns(String) }
|
88
|
-
# Returns a human-readable brief string description of this code.
|
89
|
-
#
|
90
|
-
# @return [String]
|
91
|
-
def describe
|
92
|
-
"Type Alias (#{name} = #{type})"
|
93
|
-
end
|
94
|
-
|
95
87
|
sig { override.void }
|
96
88
|
def generalize_from_rbi!
|
97
89
|
@type = TypeParser.parse_single_type(@type) if String === @type
|
98
90
|
end
|
91
|
+
|
92
|
+
sig { override.returns(T::Array[T.any(Symbol, T::Hash[Symbol, String])]) }
|
93
|
+
def describe_attrs
|
94
|
+
[{type: type}] # avoid quotes
|
95
|
+
end
|
99
96
|
end
|
100
97
|
end
|
101
98
|
end
|
@@ -21,22 +21,7 @@ module Parlour
|
|
21
21
|
#
|
22
22
|
# @return [String] The generated RBI file
|
23
23
|
def rbi(strictness = 'strong')
|
24
|
-
#
|
25
|
-
# Absolutely remove this later on
|
26
|
-
if ENV['PARLOUR_CONVERT_TO_RBS']
|
27
|
-
# Perform conversion
|
28
|
-
root.generalize_from_rbi!
|
29
|
-
rbs_gen = Parlour::RbsGenerator.new
|
30
|
-
converter = Parlour::Conversion::RbiToRbs.new(rbs_gen)
|
31
|
-
root.children.each do |child|
|
32
|
-
converter.convert_object(child, rbs_gen.root)
|
33
|
-
end
|
34
|
-
|
35
|
-
# Write the final RBS
|
36
|
-
rbs_gen.rbs
|
37
|
-
else
|
38
|
-
"# typed: #{strictness}\n" + root.generate_rbi(0, options).join("\n") + "\n"
|
39
|
-
end
|
24
|
+
"# typed: #{strictness}\n" + root.generate_rbi(0, options).join("\n") + "\n"
|
40
25
|
end
|
41
26
|
end
|
42
27
|
end
|
@@ -80,12 +80,9 @@ module Parlour
|
|
80
80
|
raise 'arbitrary code is never mergeable'
|
81
81
|
end
|
82
82
|
|
83
|
-
sig { override.returns(String) }
|
84
|
-
|
85
|
-
|
86
|
-
# @return [String]
|
87
|
-
def describe
|
88
|
-
"Arbitrary code (#{code})"
|
83
|
+
sig { override.returns(T::Array[T.any(Symbol, T::Hash[Symbol, String])]) }
|
84
|
+
def describe_attrs
|
85
|
+
[:code]
|
89
86
|
end
|
90
87
|
end
|
91
88
|
end
|
@@ -77,6 +77,14 @@ module Parlour
|
|
77
77
|
super(other) && Attribute === other && kind == other.kind
|
78
78
|
)
|
79
79
|
end
|
80
|
+
|
81
|
+
sig { override.returns(T::Array[T.any(Symbol, T::Hash[Symbol, String])]) }
|
82
|
+
def describe_attrs
|
83
|
+
[
|
84
|
+
:kind,
|
85
|
+
:class_attribute
|
86
|
+
]
|
87
|
+
end
|
80
88
|
end
|
81
89
|
end
|
82
90
|
end
|
@@ -5,6 +5,8 @@ module Parlour
|
|
5
5
|
class ClassNamespace < Namespace
|
6
6
|
extend T::Sig
|
7
7
|
|
8
|
+
Child = type_member {{ fixed: RbsObject }}
|
9
|
+
|
8
10
|
sig do
|
9
11
|
params(
|
10
12
|
generator: Generator,
|
@@ -18,10 +20,8 @@ module Parlour
|
|
18
20
|
#
|
19
21
|
# @param generator [RbsGenerator] The current RbsGenerator.
|
20
22
|
# @param name [String] The name of this class.
|
21
|
-
# @param final [Boolean] Whether this namespace is final.
|
22
23
|
# @param superclass [String, nil] The superclass of this class, or nil if it doesn't
|
23
24
|
# have one.
|
24
|
-
# @param abstract [Boolean] A boolean indicating whether this class is abstract.
|
25
25
|
# @param block A block which the new instance yields itself to.
|
26
26
|
# @return [void]
|
27
27
|
def initialize(generator, name, superclass, &block)
|
@@ -93,13 +93,9 @@ module Parlour
|
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
96
|
-
sig { override.returns(String) }
|
97
|
-
|
98
|
-
|
99
|
-
def describe
|
100
|
-
"Class #{name} - #{"superclass #{superclass}, " if superclass}" +
|
101
|
-
"#{children.length} children, " +
|
102
|
-
"#{includes.length} includes, #{extends.length} extends"
|
96
|
+
sig { override.returns(T::Array[T.any(Symbol, T::Hash[Symbol, String])]) }
|
97
|
+
def describe_attrs
|
98
|
+
(superclass ? [:superclass] : []) + [:children]
|
103
99
|
end
|
104
100
|
end
|
105
101
|
end
|
@@ -83,12 +83,9 @@ module Parlour
|
|
83
83
|
# We don't need to change anything! We only merge identical constants
|
84
84
|
end
|
85
85
|
|
86
|
-
sig { override.returns(String) }
|
87
|
-
|
88
|
-
|
89
|
-
# @return [String]
|
90
|
-
def describe
|
91
|
-
"Constant (#{name} = #{type})"
|
86
|
+
sig { override.returns(T::Array[T.any(Symbol, T::Hash[Symbol, String])]) }
|
87
|
+
def describe_attrs
|
88
|
+
[{type: type}] # avoid quotes
|
92
89
|
end
|
93
90
|
end
|
94
91
|
end
|
@@ -80,12 +80,9 @@ module Parlour
|
|
80
80
|
# We don't need to change anything! We only merge identical extends
|
81
81
|
end
|
82
82
|
|
83
|
-
sig { override.returns(String) }
|
84
|
-
|
85
|
-
|
86
|
-
# @return [String]
|
87
|
-
def describe
|
88
|
-
"Extend (#{@type})"
|
83
|
+
sig { override.returns(T::Array[T.any(Symbol, T::Hash[Symbol, String])]) }
|
84
|
+
def describe_attrs
|
85
|
+
[{type: type}] # avoid quotes
|
89
86
|
end
|
90
87
|
end
|
91
88
|
end
|
@@ -80,12 +80,9 @@ module Parlour
|
|
80
80
|
# We don't need to change anything! We only merge identical includes
|
81
81
|
end
|
82
82
|
|
83
|
-
sig { override.returns(String) }
|
84
|
-
|
85
|
-
|
86
|
-
# @return [String]
|
87
|
-
def describe
|
88
|
-
"Include (#{@type})"
|
83
|
+
sig { override.returns(T::Array[T.any(Symbol, T::Hash[Symbol, String])]) }
|
84
|
+
def describe_attrs
|
85
|
+
[{type: type}] # avoid quotes
|
89
86
|
end
|
90
87
|
end
|
91
88
|
end
|
@@ -5,6 +5,8 @@ module Parlour
|
|
5
5
|
class InterfaceNamespace < Namespace
|
6
6
|
extend T::Sig
|
7
7
|
|
8
|
+
Child = type_member {{ fixed: RbsObject }}
|
9
|
+
|
8
10
|
sig do
|
9
11
|
override.params(
|
10
12
|
indent_level: Integer,
|
@@ -23,11 +25,9 @@ module Parlour
|
|
23
25
|
lines << options.indented(indent_level, "end")
|
24
26
|
end
|
25
27
|
|
26
|
-
sig { override.returns(String) }
|
27
|
-
|
28
|
-
|
29
|
-
def describe
|
30
|
-
"Interface #{name} - #{children.length}"
|
28
|
+
sig { override.returns(T::Array[T.any(Symbol, T::Hash[Symbol, String])]) }
|
29
|
+
def describe_attrs
|
30
|
+
[:children]
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
@@ -133,13 +133,12 @@ module Parlour
|
|
133
133
|
# TODO: merge signatures of different definitions
|
134
134
|
end
|
135
135
|
|
136
|
-
sig { override.returns(String) }
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
"Method #{name} - #{signatures.length} signatures"
|
136
|
+
sig { override.returns(T::Array[T.any(Symbol, T::Hash[Symbol, String])]) }
|
137
|
+
def describe_attrs
|
138
|
+
[
|
139
|
+
{signatures: "(#{signatures.map(&:describe_in_method).join(", ")})"},
|
140
|
+
:class_method,
|
141
|
+
]
|
143
142
|
end
|
144
143
|
end
|
145
144
|
end
|
@@ -99,6 +99,19 @@ module Parlour
|
|
99
99
|
|
100
100
|
generated_params
|
101
101
|
end
|
102
|
+
|
103
|
+
sig { returns(String) }
|
104
|
+
def describe_in_method
|
105
|
+
# RBS is terse enough that just describing using the RBS is probably
|
106
|
+
# fine. (Unfortunately, this doesn't allow any differentiation between
|
107
|
+
# string types and Parlour::Types types.)
|
108
|
+
# (#describe is supposed to be one line, but this will break if you
|
109
|
+
# have than 10000 parameters. Honestly, if you do have more than 10000
|
110
|
+
# parameters, you deserve this...)
|
111
|
+
generate_rbs(Parlour::Options.new(
|
112
|
+
break_params: 10000, tab_size: 2, sort_namespaces: false
|
113
|
+
)).join("\n")
|
114
|
+
end
|
102
115
|
end
|
103
116
|
end
|
104
117
|
end
|
@@ -5,6 +5,8 @@ module Parlour
|
|
5
5
|
class ModuleNamespace < Namespace
|
6
6
|
extend T::Sig
|
7
7
|
|
8
|
+
Child = type_member {{ fixed: RbsObject }}
|
9
|
+
|
8
10
|
sig do
|
9
11
|
override.params(
|
10
12
|
indent_level: Integer,
|
@@ -23,12 +25,9 @@ module Parlour
|
|
23
25
|
lines << options.indented(indent_level, "end")
|
24
26
|
end
|
25
27
|
|
26
|
-
sig { override.returns(String) }
|
27
|
-
|
28
|
-
|
29
|
-
def describe
|
30
|
-
"Module #{name} - #{children.length} " +
|
31
|
-
"children, #{includes.length} includes, #{extends.length} extends"
|
28
|
+
sig { override.returns(T::Array[T.any(Symbol, T::Hash[Symbol, String])]) }
|
29
|
+
def describe_attrs
|
30
|
+
[:children]
|
32
31
|
end
|
33
32
|
end
|
34
33
|
end
|
@@ -5,6 +5,7 @@ module Parlour
|
|
5
5
|
# {RbsGenerator#root}.
|
6
6
|
class Namespace < RbsObject
|
7
7
|
extend T::Sig
|
8
|
+
extend T::Generic
|
8
9
|
|
9
10
|
sig do
|
10
11
|
override.overridable.params(
|
@@ -45,11 +46,14 @@ module Parlour
|
|
45
46
|
yield_self(&block) if block
|
46
47
|
end
|
47
48
|
|
48
|
-
sig { returns(T::Array[RbsObject]) }
|
49
|
+
sig { override.returns(T::Array[RbsObject]).checked(:never) }
|
49
50
|
# The child {RbsObject} instances inside this namespace.
|
50
51
|
# @return [Array<RbsObject>]
|
51
52
|
attr_reader :children
|
52
53
|
|
54
|
+
include Mixin::Searchable
|
55
|
+
Child = type_member {{ fixed: RbsObject }}
|
56
|
+
|
53
57
|
sig { returns(T::Array[RbsGenerator::Extend]) }
|
54
58
|
# The {RbsGenerator::Extend} objects from {children}.
|
55
59
|
# @return [Array<RbsGenerator::Extend>]
|
@@ -517,13 +521,9 @@ module Parlour
|
|
517
521
|
end
|
518
522
|
end
|
519
523
|
|
520
|
-
sig { override.
|
521
|
-
|
522
|
-
|
523
|
-
# @return [String]
|
524
|
-
def describe
|
525
|
-
"Namespace #{name} - #{children.length} children, #{includes.length} " +
|
526
|
-
"includes, #{extends.length} extends, #{constants.length} constants"
|
524
|
+
sig { override.returns(T::Array[T.any(Symbol, T::Hash[Symbol, String])]) }
|
525
|
+
def describe_attrs
|
526
|
+
[:children]
|
527
527
|
end
|
528
528
|
|
529
529
|
private
|
@@ -68,11 +68,6 @@ module Parlour
|
|
68
68
|
# @param others [Array<RbsGenerator::RbsObject>] An array of other {RbsObject} instances.
|
69
69
|
# @return [void]
|
70
70
|
def merge_into_self(others); end
|
71
|
-
|
72
|
-
sig { overridable.override.returns(String) }
|
73
|
-
def describe
|
74
|
-
'RBS object'
|
75
|
-
end
|
76
71
|
end
|
77
72
|
end
|
78
73
|
end
|
@@ -84,12 +84,9 @@ module Parlour
|
|
84
84
|
# We don't need to change anything! We only merge identical type alias
|
85
85
|
end
|
86
86
|
|
87
|
-
sig { override.returns(String) }
|
88
|
-
|
89
|
-
|
90
|
-
# @return [String]
|
91
|
-
def describe
|
92
|
-
"Type Alias (#{name} = #{type})"
|
87
|
+
sig { override.returns(T::Array[T.any(Symbol, T::Hash[Symbol, String])]) }
|
88
|
+
def describe_attrs
|
89
|
+
[{type: type}] # avoid quotes
|
93
90
|
end
|
94
91
|
end
|
95
92
|
end
|
data/lib/parlour/type_loader.rb
CHANGED
@@ -60,7 +60,12 @@ module Parlour
|
|
60
60
|
chdir: root
|
61
61
|
)
|
62
62
|
|
63
|
-
|
63
|
+
stdout = T.must(stdout.read)
|
64
|
+
if stdout == ''
|
65
|
+
raise 'unable to get Sorbet file table; the project may be empty or not have Sorbet initialised'
|
66
|
+
end
|
67
|
+
|
68
|
+
file_table_hash = JSON.parse(stdout)
|
64
69
|
file_table_entries = file_table_hash['files']
|
65
70
|
|
66
71
|
namespaces = T.let([], T::Array[Parlour::RbiGenerator::Namespace])
|
data/lib/parlour/type_parser.rb
CHANGED
@@ -361,8 +361,8 @@ module Parlour
|
|
361
361
|
# (block (send (const nil :T) :type_alias) (args) (type_to_alias))
|
362
362
|
if body.type == :block &&
|
363
363
|
body.to_a[0].type == :send &&
|
364
|
-
body.to_a[0].to_a[0]
|
365
|
-
body.to_a[0].to_a[0]
|
364
|
+
body.to_a[0].to_a[0]&.type == :const &&
|
365
|
+
body.to_a[0].to_a[0]&.to_a == [nil, :T] &&
|
366
366
|
body.to_a[0].to_a[1] == :type_alias
|
367
367
|
|
368
368
|
[Parlour::RbiGenerator::TypeAlias.new(
|
data/lib/parlour/typed_object.rb
CHANGED
@@ -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
|
@@ -57,16 +57,101 @@ module Parlour
|
|
57
57
|
|
58
58
|
alias_method :add_comments, :add_comment
|
59
59
|
|
60
|
-
sig {
|
60
|
+
sig { returns(String) }
|
61
61
|
# Returns a human-readable brief string description of this object. This
|
62
62
|
# is displayed during manual conflict resolution with the +parlour+ CLI.
|
63
63
|
#
|
64
|
-
# @abstract
|
65
64
|
# @return [String]
|
66
|
-
def describe
|
65
|
+
def describe
|
66
|
+
if is_a?(RbiGenerator::RbiObject)
|
67
|
+
type_system = 'RBI'
|
68
|
+
elsif is_a?(RbsGenerator::RbsObject)
|
69
|
+
type_system = 'RBS'
|
70
|
+
else
|
71
|
+
raise 'unknown type system'
|
72
|
+
end
|
73
|
+
|
74
|
+
attr_strings = describe_attrs.map do |a|
|
75
|
+
case a
|
76
|
+
when Symbol
|
77
|
+
key = a
|
78
|
+
value = send(a)
|
79
|
+
|
80
|
+
case value
|
81
|
+
when Array, Hash
|
82
|
+
value = value.length
|
83
|
+
next nil if value == 0
|
84
|
+
when String
|
85
|
+
value = value.inspect
|
86
|
+
when Parlour::Types::Type
|
87
|
+
value = value.describe
|
88
|
+
when true
|
89
|
+
next key
|
90
|
+
when false
|
91
|
+
next nil
|
92
|
+
end
|
93
|
+
when Hash
|
94
|
+
raise 'describe_attrs Hash must have one key' unless a.length == 1
|
95
|
+
|
96
|
+
key = a.keys[0]
|
97
|
+
value = a.values[0]
|
98
|
+
end
|
99
|
+
|
100
|
+
"#{key}=#{value}"
|
101
|
+
end.compact
|
102
|
+
|
103
|
+
class_name = T.must(self.class.name).split('::').last
|
104
|
+
if attr_strings.empty?
|
105
|
+
"<#{type_system}:#{class_name}:#{name}>"
|
106
|
+
else
|
107
|
+
"<#{type_system}:#{class_name}:#{name} #{attr_strings.join(" ")}>"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
sig { params(tree: T.nilable(Debugging::Tree)).returns(String) }
|
112
|
+
# Returns a human-readable multi-line string description of this object and
|
113
|
+
# its children recursively.
|
114
|
+
#
|
115
|
+
# @return [String]
|
116
|
+
def describe_tree(tree: nil)
|
117
|
+
if tree.nil?
|
118
|
+
tree = Debugging::Tree.new
|
119
|
+
result = "#{describe}\n"
|
120
|
+
else
|
121
|
+
result = ""
|
122
|
+
end
|
123
|
+
|
124
|
+
if is_a?(RbiGenerator::Namespace) || is_a?(RbsGenerator::Namespace)
|
125
|
+
children.each do |child|
|
126
|
+
result += "#{tree.begin(child.describe)}\n"
|
127
|
+
result += child.describe_tree(tree: tree)
|
128
|
+
tree.indent!(-1)
|
129
|
+
end
|
130
|
+
else
|
131
|
+
"#{describe}\n"
|
132
|
+
end
|
133
|
+
|
134
|
+
result
|
135
|
+
end
|
136
|
+
|
137
|
+
alias inspect describe
|
138
|
+
alias to_s describe
|
67
139
|
|
68
140
|
protected
|
69
141
|
|
142
|
+
sig { abstract.returns(T::Array[T.any(Symbol, T::Hash[Symbol, String])]) }
|
143
|
+
# The attributes for an instance of this object which should be included in
|
144
|
+
# its string form generated by +#describe+.
|
145
|
+
# For each element in the returned array:
|
146
|
+
# - If it is a symbol, this symbol will be called on +self+ and the
|
147
|
+
# returned object will be dynamically converted into a string.
|
148
|
+
# - If it is a hash, it must be of the format { Symbol => String }. The
|
149
|
+
# given string will be used instead of calling the symbol.
|
150
|
+
#
|
151
|
+
# @abstract
|
152
|
+
# @return [<Symbol, String>]
|
153
|
+
def describe_attrs; end
|
154
|
+
|
70
155
|
sig do
|
71
156
|
params(
|
72
157
|
indent_level: Integer,
|
@@ -84,4 +169,4 @@ module Parlour
|
|
84
169
|
: []
|
85
170
|
end
|
86
171
|
end
|
87
|
-
end
|
172
|
+
end
|
data/lib/parlour/version.rb
CHANGED
data/lib/parlour.rb
CHANGED
@@ -14,6 +14,8 @@ require 'parlour/types'
|
|
14
14
|
require 'parlour/options'
|
15
15
|
require 'parlour/typed_object'
|
16
16
|
require 'parlour/generator'
|
17
|
+
require 'parlour/mixin/searchable'
|
18
|
+
|
17
19
|
require 'parlour/rbi_generator/parameter'
|
18
20
|
require 'parlour/rbi_generator/rbi_object'
|
19
21
|
require 'parlour/rbi_generator/type_alias'
|
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
|