parlour 5.0.0 → 7.0.0

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.
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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cb1e682fc74b2ccd30ac9055caf652889e898e2632347bf6cf0898f218bd5562
4
- data.tar.gz: fcca5ca04676cbeed657add051e344fd9b5fa0a7efc757339847310300aa4d42
3
+ metadata.gz: cc5c6c8baabe95bbc999a4143264b1dad8b84260bdc156d2a35526244322db2f
4
+ data.tar.gz: 580430b0cfe37f80b60f9dd47f8673f4d1d973e6ef6abca44efa299355d19fed
5
5
  SHA512:
6
- metadata.gz: cef41723b922734b49f8377dc3b5c60cf0071d2a9723326299872fea4789f8e6ea1cb280fcd21161d48bd5dbb074b416e60668138116e56caf1c8334cce8e535
7
- data.tar.gz: b9ea0db060c8789e1324460cde4a69b1c20b829920e660024f53834e48cef536b5423736e6fce4859c2e2fea5339e3f26bdd7513947bafcc82bd239db57cc68a
6
+ metadata.gz: ae2fd0263a3d955ff7904a28e69bf16eb21b413bda3e71be42636e0829e730a33ee0eb477712fc45dffbce948de3a4c3d6ae6e19147e21b114cd58fe93679676
7
+ data.tar.gz: 549cd5f91736b8aa5c1f5e1ebaa69fd2d8e4e9f905f1d4aa9ed799677e2d2367a573548d6a9ea220f3c6c6dbf268cc2679c8d0e26516c52224574563974070b6
@@ -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/.parlour CHANGED
@@ -1,5 +1,7 @@
1
- excluded_paths:
2
- - lib/parlour/kernel_hack.rb
1
+ parser:
2
+ excluded_paths:
3
+ - lib/parlour/kernel_hack.rb
3
4
 
4
5
  excluded_modules:
5
6
  - Parlour::DetachedRbiGenerator
7
+ - Parlour::DetachedRbsGenerator
data/CHANGELOG.md CHANGED
@@ -3,6 +3,39 @@ 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
+ ## [7.0.0] - 2022-04-18
7
+ ### Added
8
+ - `#describe` now uses a new, clearer format.
9
+ - Added `#describe_tree`, which produces `#describe` output for a node and all
10
+ of its children.
11
+ - Added `#find` and `#find_all` for retrieving a node's children based on
12
+ criteria.
13
+
14
+ ### Changed
15
+ - Parlour now uses the new block-based `type_member` syntax internally.
16
+ **Potentially breaking** if you pin an older version of Sorbet which doesn't
17
+ support this syntax!
18
+ - Improved error message when unable to retrieve the file table from Sorbet.
19
+ - `#inspect` and `#to_s` now call `#describe`.
20
+
21
+ ## Fixed
22
+ - Fixed some incorrect YARD documentation tags.
23
+
24
+ ## [6.0.1] - 2021-02-28
25
+ ### Changed
26
+ - Disabled runtime type checking for `TypedObject#name`, resulting in a
27
+ significant decrease in the time taken to run the conflict resolver.
28
+
29
+ ## [6.0.0] - 2021-02-28
30
+ ### Changed
31
+ - The RBI previously included with the Parlour gem has been removed,
32
+ as it was causing issues with Sorbet. **If you were relying on Parlour's
33
+ bundled RBI while type-checking your project, you will now need to use the
34
+ RBI from sorbet-typed or the Parlour repo.**
35
+ - `Namespace#path` will now work much more reliably for classes and
36
+ modules which replace methods from `Module` and `Class`, such as
37
+ `#name`.
38
+
6
39
  ## [5.0.0] - 2020-12-26
7
40
  ### Added
8
41
  - Added RBS generation support! This includes:
data/exe/parlour CHANGED
@@ -11,9 +11,8 @@ program :description, 'An RBI generator and plugin system'
11
11
 
12
12
  default_command :run
13
13
  command :run do |c|
14
- # TODO: re-add support for flags and figure out how to merge them with .parlour
15
- c.syntax = 'parlour run <plugins...> <output-file> [options]'
16
- c.description = 'Generates an RBI file from your .parlour file'
14
+ c.syntax = 'parlour run'
15
+ c.description = 'Generates a signature file from your .parlour file'
17
16
 
18
17
  c.action do |args, options|
19
18
  working_dir = Dir.pwd
@@ -7,6 +7,10 @@ module Parlour
7
7
  class ConflictResolver
8
8
  extend T::Sig
9
9
 
10
+ def initialize
11
+ @debugging_tree = Debugging::Tree.new(colour: true)
12
+ end
13
+
10
14
  sig do
11
15
  params(
12
16
  namespace: RbiGenerator::Namespace,
@@ -41,7 +45,7 @@ module Parlour
41
45
  # will be kept, or nil to keep none of them.
42
46
  # @return [void]
43
47
  def resolve_conflicts(namespace, &resolver)
44
- Debugging.debug_puts(self, Debugging::Tree.begin("Resolving conflicts for #{namespace.name}..."))
48
+ Debugging.debug_puts(self, @debugging_tree.begin("Resolving conflicts for #{namespace.name}..."))
45
49
 
46
50
  # Check for multiple definitions with the same name
47
51
  # (Special case here: writer attributes get an "=" appended to their name)
@@ -54,10 +58,10 @@ module Parlour
54
58
  end
55
59
 
56
60
  grouped_by_name_children.each do |name, children|
57
- Debugging.debug_puts(self, Debugging::Tree.begin("Checking children named #{name}..."))
61
+ Debugging.debug_puts(self, @debugging_tree.begin("Checking children named #{name}..."))
58
62
 
59
63
  if children.length > 1
60
- Debugging.debug_puts(self, Debugging::Tree.here("Possible conflict between #{children.length} objects"))
64
+ Debugging.debug_puts(self, @debugging_tree.here("Possible conflict between #{children.length} objects"))
61
65
 
62
66
  # Special case: do we have two methods, one of which is a class method
63
67
  # and the other isn't? If so, do nothing - this is fine
@@ -65,7 +69,7 @@ module Parlour
65
69
  children.all? { |c| c.is_a?(RbiGenerator::Method) } &&
66
70
  children.count { |c| T.cast(c, RbiGenerator::Method).class_method } == 1
67
71
 
68
- Debugging.debug_puts(self, Debugging::Tree.end("One is an instance method and one is a class method; no resolution required"))
72
+ Debugging.debug_puts(self, @debugging_tree.end("One is an instance method and one is a class method; no resolution required"))
69
73
  next
70
74
  end
71
75
 
@@ -80,7 +84,7 @@ module Parlour
80
84
  end
81
85
  deduplicate_mixins_of_name(namespace, name)
82
86
 
83
- Debugging.debug_puts(self, Debugging::Tree.end("Includes/extends do not conflict with namespaces; no resolution required"))
87
+ Debugging.debug_puts(self, @debugging_tree.end("Includes/extends do not conflict with namespaces; no resolution required"))
84
88
  next
85
89
  end
86
90
 
@@ -90,13 +94,13 @@ module Parlour
90
94
  children.all? { |c| c.is_a?(RbiGenerator::Attribute) } &&
91
95
  children.count { |c| T.cast(c, RbiGenerator::Attribute).class_attribute } == 1
92
96
 
93
- Debugging.debug_puts(self, Debugging::Tree.end("One is an instance attribute and one is a class attribute; no resolution required"))
97
+ Debugging.debug_puts(self, @debugging_tree.end("One is an instance attribute and one is a class attribute; no resolution required"))
94
98
  next
95
99
  end
96
100
 
97
101
  # Optimization for Special case: are they all clearly equal? If so, remove all but one
98
102
  if all_eql?(children)
99
- Debugging.debug_puts(self, Debugging::Tree.end("All children are identical"))
103
+ Debugging.debug_puts(self, @debugging_tree.end("All children are identical"))
100
104
 
101
105
  # All of the children are the same, so this deletes all of them
102
106
  namespace.children.delete(T.must(children.first))
@@ -116,7 +120,7 @@ module Parlour
116
120
  # and get the strategy to use
117
121
  strategy = merge_strategy(children)
118
122
  unless strategy
119
- Debugging.debug_puts(self, Debugging::Tree.end("Children are unmergeable types; requesting manual resolution"))
123
+ Debugging.debug_puts(self, @debugging_tree.end("Children are unmergeable types; requesting manual resolution"))
120
124
  # The types aren't the same, so ask the resolver what to do, and
121
125
  # insert that (if not nil)
122
126
  choice = resolver.call("Different kinds of definition for the same name", children)
@@ -135,7 +139,7 @@ module Parlour
135
139
  # a single method
136
140
  if non_namespaces.length != 0
137
141
  unless non_namespaces.length == 1 && RbiGenerator::Method === non_namespaces.first
138
- Debugging.debug_puts(self, Debugging::Tree.end("Non-namespace item in a differing namespace conflict is not a single method; requesting manual resolution"))
142
+ Debugging.debug_puts(self, @debugging_tree.end("Non-namespace item in a differing namespace conflict is not a single method; requesting manual resolution"))
139
143
  # The types aren't the same, so ask the resolver what to do, and
140
144
  # insert that (if not nil)
141
145
  choice = resolver.call("Non-namespace item in a differing namespace conflict is not a single method", non_namespaces)
@@ -167,29 +171,29 @@ module Parlour
167
171
  # Can the children merge themselves automatically? If so, let them
168
172
  first, rest = T.must(first), T.must(rest)
169
173
  if T.must(first).mergeable?(T.must(rest))
170
- Debugging.debug_puts(self, Debugging::Tree.end("Children are all mergeable; resolving automatically"))
174
+ Debugging.debug_puts(self, @debugging_tree.end("Children are all mergeable; resolving automatically"))
171
175
  first.merge_into_self(rest)
172
176
  namespace.children << first
173
177
  next
174
178
  end
175
179
 
176
180
  # I give up! Let it be resolved manually somehow
177
- Debugging.debug_puts(self, Debugging::Tree.end("Unable to resolve automatically; requesting manual resolution"))
181
+ Debugging.debug_puts(self, @debugging_tree.end("Unable to resolve automatically; requesting manual resolution"))
178
182
  choice = resolver.call("Can't automatically resolve", children)
179
183
  namespace.children << choice if choice
180
184
  else
181
- Debugging.debug_puts(self, Debugging::Tree.end("No conflicts"))
185
+ Debugging.debug_puts(self, @debugging_tree.end("No conflicts"))
182
186
  end
183
187
  end
184
188
 
185
- Debugging.debug_puts(self, Debugging::Tree.here("Resolving children..."))
189
+ Debugging.debug_puts(self, @debugging_tree.here("Resolving children..."))
186
190
 
187
191
  # Recurse to child namespaces
188
192
  namespace.children.each do |child|
189
193
  resolve_conflicts(child, &resolver) if RbiGenerator::Namespace === child
190
194
  end
191
195
 
192
- Debugging.debug_puts(self, Debugging::Tree.end("All children done"))
196
+ Debugging.debug_puts(self, @debugging_tree.end("All children done"))
193
197
  end
194
198
 
195
199
  private
@@ -17,7 +17,7 @@ module Parlour
17
17
  @debug_mode = value
18
18
  end
19
19
 
20
- # Whether debug messages sent by {#debug_puts} should be printed.
20
+ # Whether debug messages sent by {.debug_puts} should be printed.
21
21
  # Defaults to true if the PARLOUR_DEBUG environment variable is set.
22
22
  # @return [Boolean] True if debug messages will be printed, false otherwise.
23
23
  sig { returns(T::Boolean) }
@@ -25,11 +25,11 @@ module Parlour
25
25
  @debug_mode
26
26
  end
27
27
 
28
- # Prints a message with a debugging prefix to STDOUT if {#debug_mode?} is
28
+ # Prints a message with a debugging prefix to STDOUT if {.debug_mode?} is
29
29
  # true.
30
- # @params [Object] object The object which is printing this debug message.
30
+ # @param [Object] object The object which is printing this debug message.
31
31
  # Callers should pass +self+.
32
- # @params [String] message The message to print. It should not contain
32
+ # @param [String] message The message to print. It should not contain
33
33
  # newlines.
34
34
  # @return [void]
35
35
  sig { params(object: T.untyped, message: String).void }
@@ -45,7 +45,7 @@ module Parlour
45
45
  # "conflict resolver". If the object type is unknown, this returns its class
46
46
  # name.
47
47
  # @param [Object] object The object to convert.
48
- # @return [String] A string describing the object for {#debug_puts}.
48
+ # @return [String] A string describing the object for {.debug_puts}.
49
49
  sig { params(object: T.untyped).returns(String) }
50
50
  def self.name_for_debug_caller(object)
51
51
  case object
@@ -63,24 +63,32 @@ module Parlour
63
63
 
64
64
  # A module for generating a globally-consistent, nicely-formatted tree of
65
65
  # output using Unicode block characters.
66
- module Tree
66
+ class Tree
67
67
  extend T::Sig
68
68
 
69
69
  # The number of spaces to indent each layer of the tree by. Should be at
70
70
  # least 1.
71
71
  INDENT_SPACES = 2
72
72
 
73
- # The current indent level of the tree.
74
- @indent_level = 0
73
+ # Whether to colour output or not.
74
+ sig { returns(T::Boolean) }
75
+ attr_reader :colour
76
+
77
+ sig { params(colour: T::Boolean).void }
78
+ def initialize(colour: false)
79
+ @colour = colour
80
+ @indent_level = 0
81
+ end
75
82
 
76
83
  # Returns a new heading, and then decents the tree one level into it.
77
84
  # (That is, future output will go under the new heading.)
78
85
  # @param [String] message The heading.
79
86
  # @return [String] The line of this tree which should be printed.
80
87
  sig { params(message: String).returns(String) }
81
- def self.begin(message)
82
- result = line_prefix + '├' + text_prefix + Rainbow(message).green.bright.bold
83
- @indent_level += 1
88
+ def begin(message)
89
+ result = line_prefix + '├' + text_prefix +
90
+ (colour ? Rainbow(message).green.bright.bold : message)
91
+ indent!(1)
84
92
  result
85
93
  end
86
94
 
@@ -88,7 +96,7 @@ module Parlour
88
96
  # @param [String] message The element.
89
97
  # @return [String] The line of this tree which should be printed.
90
98
  sig { params(message: String).returns(String) }
91
- def self.here(message)
99
+ def here(message)
92
100
  line_prefix + '├' + text_prefix + message
93
101
  end
94
102
 
@@ -97,16 +105,16 @@ module Parlour
97
105
  # @param [String] message The element.
98
106
  # @return [String] The line of this tree which should be printed.
99
107
  sig { params(message: String).returns(String) }
100
- def self.end(message)
108
+ def end(message)
101
109
  result = line_prefix + '└' + text_prefix + message
102
- @indent_level = [0, @indent_level - 1].max
110
+ indent!(-1)
103
111
  result
104
112
  end
105
113
 
106
114
  # The prefix which should be printed before anything else on this line of
107
115
  # the tree, based on the current indent level.
108
116
  # @return [String]
109
- def self.line_prefix
117
+ def line_prefix
110
118
  @indent_level.times.map { '│' + ' ' * INDENT_SPACES }.join
111
119
  end
112
120
 
@@ -114,9 +122,14 @@ module Parlour
114
122
  # the current element and its text, based on the specified number of
115
123
  # spaces to use for indents.
116
124
  # @return [String]
117
- def self.text_prefix
125
+ def text_prefix
118
126
  '─' * (INDENT_SPACES - 1) + " "
119
127
  end
128
+
129
+ # Modifies the current indent level by the given offset.
130
+ def indent!(offset)
131
+ @indent_level = [0, @indent_level + offset].max
132
+ end
120
133
  end
121
134
  end
122
135
  end
@@ -0,0 +1,54 @@
1
+ # typed: true
2
+
3
+ module Parlour
4
+ module Mixin
5
+ # Extends a particular type system's Namespace class to provide searchable
6
+ # children.
7
+ module Searchable
8
+ extend T::Sig
9
+ extend T::Generic
10
+
11
+ Child = type_member
12
+
13
+ abstract!
14
+
15
+ sig { abstract.returns(T::Array[Child]) }
16
+ def children; end
17
+
18
+ sig { params(name: T.nilable(String), type: T.nilable(Class)).returns(Child) }
19
+ # Finds the first child matching the given predicates.
20
+ #
21
+ # @param [String, nil] name The name of the child to filter on, or nil.
22
+ # @param [Class, nil] type The type of the child to filter on, or nil. The
23
+ # type is compared using #is_a?.
24
+ def find(name: nil, type: nil)
25
+ T.unsafe(children).find { |c| searchable_child_matches(c, name, type) }
26
+ end
27
+
28
+ sig { params(name: T.nilable(String), type: T.nilable(Class)).returns(T::Array[Child]) }
29
+ # Finds the first child matching the given predicates.
30
+ #
31
+ # @param [String, nil] name The name of the child to filter on, or nil.
32
+ # @param [Class, nil] type The type of the child to filter on, or nil. The
33
+ # type is compared using #is_a?.
34
+ def find_all(name: nil, type: nil)
35
+ T.unsafe(children).select { |c| searchable_child_matches(c, name, type) }
36
+ end
37
+
38
+ private
39
+
40
+ sig do
41
+ params(
42
+ child: Child,
43
+ name: T.nilable(String),
44
+ type: T.nilable(Class)
45
+ )
46
+ .returns(T::Boolean)
47
+ end
48
+ def searchable_child_matches(child, name, type)
49
+ (name.nil? ? true : child.name == name) \
50
+ && (type.nil? ? true : child.is_a?(type))
51
+ end
52
+ end
53
+ end
54
+ 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
 
91
88
  sig { override.void }
@@ -78,6 +78,15 @@ module Parlour
78
78
  @type = TypeParser.parse_single_type(@type) if String === @type
79
79
  end
80
80
 
81
+ sig { override.returns(T::Array[T.any(Symbol, T::Hash[Symbol, String])]) }
82
+ def describe_attrs
83
+ [
84
+ :kind,
85
+ {type: type}, # avoid quotes
86
+ :class_attribute
87
+ ]
88
+ end
89
+
81
90
  private
82
91
 
83
92
  sig do
@@ -5,6 +5,8 @@ module Parlour
5
5
  class ClassNamespace < Namespace
6
6
  extend T::Sig
7
7
 
8
+ Child = type_member {{ fixed: RbiObject }}
9
+
8
10
  sig do
9
11
  params(
10
12
  generator: Generator,
@@ -110,13 +112,10 @@ module Parlour
110
112
  end
111
113
  end
112
114
 
113
- sig { override.returns(String) }
114
- # Returns a human-readable brief string description of this class.
115
- # @return [String]
116
- def describe
117
- "Class #{name} - #{"superclass #{superclass}, " if superclass}" +
118
- "#{"abstract, " if abstract}#{children.length} children, " +
119
- "#{includes.length} includes, #{extends.length} extends"
115
+ sig { override.returns(T::Array[T.any(Symbol, T::Hash[Symbol, String])]) }
116
+ def describe_attrs
117
+ (superclass ? [:superclass] : []) \
118
+ + [:children, :abstract, :final, :sealed]
120
119
  end
121
120
 
122
121
  sig { override.void }
@@ -95,12 +95,9 @@ module Parlour
95
95
  # We don't need to change anything! We only merge identical constants
96
96
  end
97
97
 
98
- sig { override.returns(String) }
99
- # Returns a human-readable brief string description of this code.
100
- #
101
- # @return [String]
102
- def describe
103
- "Constant (#{name} = #{value})"
98
+ sig { override.returns(T::Array[T.any(Symbol, T::Hash[Symbol, String])]) }
99
+ def describe_attrs
100
+ [:value, :eigen_constant]
104
101
  end
105
102
 
106
103
  sig { override.void }
@@ -5,6 +5,8 @@ module Parlour
5
5
  class EnumClassNamespace < ClassNamespace
6
6
  extend T::Sig
7
7
 
8
+ Child = type_member {{ fixed: RbiObject }}
9
+
8
10
  sig do
9
11
  params(
10
12
  generator: Generator,
@@ -114,6 +116,11 @@ module Parlour
114
116
  def generalize_from_rbi!
115
117
  super
116
118
  end
119
+
120
+ sig { override.returns(T::Array[T.any(Symbol, T::Hash[Symbol, String])]) }
121
+ def describe_attrs
122
+ super + [{enums: enums.inspect}]
123
+ end
117
124
  end
118
125
  end
119
126
  end
@@ -75,16 +75,13 @@ module Parlour
75
75
  # We don't need to change anything! We only merge identical extends
76
76
  end
77
77
 
78
- sig { override.returns(String) }
79
- # Returns a human-readable brief string description of this code.
80
- #
81
- # @return [String]
82
- def describe
83
- "Extend (#{name})"
84
- end
85
-
86
78
  sig { override.void }
87
79
  def generalize_from_rbi!; end # Nothing to do
80
+
81
+ sig { override.returns(T::Array[T.any(Symbol, T::Hash[Symbol, String])]) }
82
+ def describe_attrs
83
+ []
84
+ end
88
85
  end
89
86
  end
90
87
  end
@@ -75,16 +75,13 @@ module Parlour
75
75
  # We don't need to change anything! We only merge identical includes
76
76
  end
77
77
 
78
- sig { override.returns(String) }
79
- # Returns a human-readable brief string description of this code.
80
- #
81
- # @return [String]
82
- def describe
83
- "Include (#{name})"
84
- end
85
-
86
78
  sig { override.void }
87
79
  def generalize_from_rbi!; end # Nothing to do
80
+
81
+ sig { override.returns(T::Array[T.any(Symbol, T::Hash[Symbol, String])]) }
82
+ def describe_attrs
83
+ []
84
+ end
88
85
  end
89
86
  end
90
87
  end
@@ -206,16 +206,6 @@ module Parlour
206
206
  # We don't need to change anything! We only merge identical methods
207
207
  end
208
208
 
209
- sig { override.returns(String) }
210
- # Returns a human-readable brief string description of this method.
211
- #
212
- # @return [String]
213
- def describe
214
- # TODO: more info
215
- "Method #{name} - #{parameters.length} parameters, " +
216
- " returns #{return_type}"
217
- end
218
-
219
209
  sig { override.void }
220
210
  def generalize_from_rbi!
221
211
  @return_type = TypeParser.parse_single_type(@return_type) if String === @return_type
@@ -223,6 +213,21 @@ module Parlour
223
213
  parameters.each(&:generalize_from_rbi!)
224
214
  end
225
215
 
216
+ sig { override.returns(T::Array[T.any(Symbol, T::Hash[Symbol, String])]) }
217
+ def describe_attrs
218
+ (type_parameters.any? ? [{ type_parameters: type_parameters.join(", ")}] : []) \
219
+ + [
220
+ {parameters: "(#{parameters.map(&:describe_in_method).join(", ")})"},
221
+ {return_type: return_type || '(void)'}, # avoid quotes
222
+ :class_method,
223
+ :abstract,
224
+ :implementation,
225
+ :override,
226
+ :overridable,
227
+ :final,
228
+ ]
229
+ end
230
+
226
231
  private
227
232
 
228
233
  sig do
@@ -5,6 +5,8 @@ module Parlour
5
5
  class ModuleNamespace < Namespace
6
6
  extend T::Sig
7
7
 
8
+ Child = type_member {{ fixed: RbiObject }}
9
+
8
10
  sig do
9
11
  params(
10
12
  generator: Generator,
@@ -100,19 +102,15 @@ module Parlour
100
102
  super
101
103
  end
102
104
 
103
- sig { override.returns(String) }
104
- # Returns a human-readable brief string description of this module.
105
- # @return [String]
106
- def describe
107
- "Module #{name} - #{"interface, " if interface}" +
108
- "#{"abstract, " if abstract}#{children.length} " +
109
- "children, #{includes.length} includes, #{extends.length} extends"
110
- end
111
-
112
105
  sig { override.void }
113
106
  def generalize_from_rbi!
114
107
  super
115
108
  end
109
+
110
+ sig { override.returns(T::Array[T.any(Symbol, T::Hash[Symbol, String])]) }
111
+ def describe_attrs
112
+ [:children, :abstract, :interface, :final, :sealed]
113
+ end
116
114
  end
117
115
  end
118
116
  end