parlour 5.0.0 → 7.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +46 -0
  3. data/.parlour +4 -2
  4. data/CHANGELOG.md +33 -0
  5. data/exe/parlour +2 -3
  6. data/lib/parlour/conflict_resolver.rb +18 -14
  7. data/lib/parlour/debugging.rb +29 -16
  8. data/lib/parlour/mixin/searchable.rb +54 -0
  9. data/lib/parlour/rbi_generator/arbitrary.rb +3 -6
  10. data/lib/parlour/rbi_generator/attribute.rb +9 -0
  11. data/lib/parlour/rbi_generator/class_namespace.rb +6 -7
  12. data/lib/parlour/rbi_generator/constant.rb +3 -6
  13. data/lib/parlour/rbi_generator/enum_class_namespace.rb +7 -0
  14. data/lib/parlour/rbi_generator/extend.rb +5 -8
  15. data/lib/parlour/rbi_generator/include.rb +5 -8
  16. data/lib/parlour/rbi_generator/method.rb +15 -10
  17. data/lib/parlour/rbi_generator/module_namespace.rb +7 -9
  18. data/lib/parlour/rbi_generator/namespace.rb +27 -24
  19. data/lib/parlour/rbi_generator/parameter.rb +12 -0
  20. data/lib/parlour/rbi_generator/rbi_object.rb +0 -5
  21. data/lib/parlour/rbi_generator/struct_class_namespace.rb +7 -0
  22. data/lib/parlour/rbi_generator/type_alias.rb +5 -8
  23. data/lib/parlour/rbi_generator.rb +1 -16
  24. data/lib/parlour/rbs_generator/arbitrary.rb +3 -6
  25. data/lib/parlour/rbs_generator/attribute.rb +8 -0
  26. data/lib/parlour/rbs_generator/class_namespace.rb +5 -9
  27. data/lib/parlour/rbs_generator/constant.rb +3 -6
  28. data/lib/parlour/rbs_generator/extend.rb +3 -6
  29. data/lib/parlour/rbs_generator/include.rb +3 -6
  30. data/lib/parlour/rbs_generator/interface_namespace.rb +5 -5
  31. data/lib/parlour/rbs_generator/method.rb +6 -7
  32. data/lib/parlour/rbs_generator/method_signature.rb +13 -0
  33. data/lib/parlour/rbs_generator/module_namespace.rb +5 -6
  34. data/lib/parlour/rbs_generator/namespace.rb +8 -8
  35. data/lib/parlour/rbs_generator/rbs_object.rb +0 -5
  36. data/lib/parlour/rbs_generator/type_alias.rb +3 -6
  37. data/lib/parlour/type_loader.rb +6 -1
  38. data/lib/parlour/type_parser.rb +2 -2
  39. data/lib/parlour/typed_object.rb +90 -5
  40. data/lib/parlour/version.rb +1 -1
  41. data/lib/parlour.rb +2 -0
  42. data/parlour.gemspec +2 -1
  43. metadata +19 -5
  44. data/.travis.yml +0 -32
  45. 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(object: T.untyped, block: T.proc.params(x: Namespace).void).void }
110
- # Given a Class or Module object, generates all classes and modules in the
111
- # path to that object, then executes the given block on the last
112
- # {Namespace}. This should only be executed on the root namespace.
113
- # @param [Class, Module] object
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(object, &block)
120
+ def path(constant, &block)
116
121
  raise 'only call #path on root' if is_a?(ClassNamespace) || is_a?(ModuleNamespace)
117
122
 
118
- parts = object.to_s.split('::')
119
- parts_with_types = parts.size.times.map do |i|
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
- parts_with_types.each do |(name, type)|
125
- if type == Class
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
- elsif type == Module
134
+ when Module
128
135
  current_part = current_part.create_module(name)
129
136
  else
130
- raise "unexpected type: path part #{name} is a #{type}"
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
- # TODO: Early test option - convert to RBS if requested
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
- # Returns a human-readable brief string description of this code.
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
- # Returns a human-readable brief string description of this class.
98
- # @return [String]
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
- # Returns a human-readable brief string description of this code.
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
- # Returns a human-readable brief string description of this code.
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
- # Returns a human-readable brief string description of this code.
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
- # Returns a human-readable brief string description of this interface.
28
- # @return [String]
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
- # Returns a human-readable brief string description of this method.
138
- #
139
- # @return [String]
140
- def describe
141
- # TODO: more info
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
- # Returns a human-readable brief string description of this module.
28
- # @return [String]
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.overridable.returns(String) }
521
- # Returns a human-readable brief string description of this namespace.
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
- # Returns a human-readable brief string description of this code.
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
@@ -60,7 +60,12 @@ module Parlour
60
60
  chdir: root
61
61
  )
62
62
 
63
- file_table_hash = JSON.parse(T.must(stdout.read))
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])
@@ -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].type == :const &&
365
- body.to_a[0].to_a[0].to_a == [nil, :T] &&
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(
@@ -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 { abstract.returns(String) }
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; end
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
@@ -1,5 +1,5 @@
1
1
  # typed: strong
2
2
  module Parlour
3
3
  # The library version.
4
- VERSION = '5.0.0'
4
+ VERSION = '7.0.0'
5
5
  end
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