parlour 9.0.0 → 9.1.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8988bf8b6435625031d284916803461e688cc3b28a755da9918cd3d83189f260
4
- data.tar.gz: ff851e34b9f7a85fdfb11db892a0d7ef692337157125ad0bab14856e7e67ced2
3
+ metadata.gz: 906222c4fcb94c3f3596055c6b1468b1eeea54ef5931632a2645f14bf9742bfc
4
+ data.tar.gz: 609ec24f2ff46cec34d42def81ef5149e550c7f4bf2297fb0a909699e37b0e6c
5
5
  SHA512:
6
- metadata.gz: 2e173ea6f2d50139c1fbd143d2eedafc1e7ed8eb9c757b4f1cc177033c08676b9feca6c3f5bbf04a37e3a41b51abb0d52414aeab5957f42649d21a41d471bcb3
7
- data.tar.gz: a17dbc4f7731d531b3603e2f57cab06636ded32fbe187902e930c786ba263d2be4405ad3de92c7e286f6a06c17c1968230d3e2f0ec26d1d7ba24242623a6bbea
6
+ metadata.gz: e0088a07cdaa2bdd29111122b15c4631e7b50ffc909bfb001d043943ddb9eb7ced94ee330e87256a418aa81f11c737daf3b2eee121946c7b5393d4e990b2fcd8
7
+ data.tar.gz: cbdac77bdc86e9037456b98394ea0127214f049e6fe01bae8117eaa3d80eaad1fcfbbf96586a86a10fbccc236b1125fd2ee46bd7d7c950f64bc5ea4af5bff146
@@ -37,14 +37,16 @@ jobs:
37
37
  - name: Set up Ruby
38
38
  uses: ruby/setup-ruby@v1
39
39
  with:
40
- ruby-version: 2.7
40
+ ruby-version: 3.0
41
41
  - name: Install dependencies
42
42
  run: bundle install
43
43
  - name: Build documentation
44
44
  run: bundle exec yard
45
45
  - name: Deploy to GitHub Actions
46
- uses: JamesIves/github-pages-deploy-action@3.7.1
46
+ uses: JamesIves/github-pages-deploy-action@v4
47
47
  with:
48
- github_token: ${{ secrets.GITHUB_TOKEN }}
48
+ token: ${{ secrets.BOT_PAT }}
49
+ git-config-name: Aaron Christiansen
50
+ git-config-email: aaronc20000+bot@gmail.com
49
51
  branch: gh-pages
50
52
  folder: doc
data/CHANGELOG.md CHANGED
@@ -3,6 +3,19 @@ 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
+ ## [9.1.1] - 2025-05-28
7
+ ### Fixed
8
+ - Replaced YARD `@abstract` directives, as they now conflict with Sorbet's `abstract!` directives
9
+ when using Tapioca
10
+
11
+ ## [9.1.0] - 2025-03-03
12
+ ### Added
13
+ - Constants can now be generated or parsed with heredoc strings. (Thanks @apiology)
14
+
15
+ ### Fixed
16
+ - `T.proc` types with no parameters are now emitted correctly. Previously, they emitted an invalid
17
+ call to `params()` - now they emit no usage of `params`. (Thanks @apiology)
18
+
6
19
  ## [9.0.0] - 2024-06-04
7
20
  ### Changed
8
21
  - Updated Commander dependency to 5.0, to remove `abbrev` deprecation warning.
@@ -1,7 +1,8 @@
1
1
  # typed: true
2
2
  module Parlour
3
3
  # The base class for user-defined RBI generation plugins.
4
- # @abstract
4
+ #
5
+ # This class is *abstract*.
5
6
  class Plugin
6
7
  extend T::Sig
7
8
  extend T::Helpers
@@ -57,7 +58,8 @@ module Parlour
57
58
  # Plugin subclasses should redefine this method and do their RBI generation
58
59
  # inside it.
59
60
  #
60
- # @abstract
61
+ # This method is *abstract*.
62
+ #
61
63
  # @param root [RbiGenerator::Namespace] The root {RbiGenerator::Namespace}.
62
64
  # @return [void]
63
65
  def generate(root); end
@@ -9,6 +9,7 @@ module Parlour
9
9
  name: String,
10
10
  value: Types::TypeLike,
11
11
  eigen_constant: T::Boolean,
12
+ heredocs: T.nilable(String),
12
13
  block: T.nilable(T.proc.params(x: Constant).void)
13
14
  ).void
14
15
  end
@@ -18,9 +19,11 @@ module Parlour
18
19
  # @param value [String] The value of the constant, as a Ruby code string.
19
20
  # @param eigen_constant [Boolean] Whether this constant is defined on the
20
21
  # eigenclass of the current namespace.
21
- def initialize(generator, name: '', value: '', eigen_constant: false, &block)
22
+ # @param heredocs [String,nil] Definitions of the heredocs used in the value, if any
23
+ def initialize(generator, name: '', value: '', eigen_constant: false, heredocs: nil, &block)
22
24
  super(generator, name)
23
25
  @value = value
26
+ @heredocs = heredocs
24
27
  @eigen_constant = eigen_constant
25
28
  yield_self(&block) if block
26
29
  end
@@ -33,6 +36,9 @@ module Parlour
33
36
  # of the current namespace.
34
37
  attr_reader :eigen_constant
35
38
 
39
+ # @return [String,nil] Definitions of the heredocs used in the value, if any
40
+ attr_reader :heredocs
41
+
36
42
  sig { params(other: Object).returns(T::Boolean) }
37
43
  # Returns true if this instance is equal to another extend.
38
44
  #
@@ -41,7 +47,7 @@ module Parlour
41
47
  # @return [Boolean]
42
48
  def ==(other)
43
49
  Constant === other && name == other.name && value == other.value \
44
- && eigen_constant == other.eigen_constant
50
+ && eigen_constant == other.eigen_constant && heredocs == other.heredocs
45
51
  end
46
52
 
47
53
  sig do
@@ -57,9 +63,13 @@ module Parlour
57
63
  # @return [Array<String>] The RBI lines, formatted as specified.
58
64
  def generate_rbi(indent_level, options)
59
65
  if String === @value
60
- [options.indented(indent_level, "#{name} = #{@value}")]
66
+ [
67
+ options.indented(indent_level, "#{name} = #{@value}"),
68
+ ] + [heredocs].compact
61
69
  else
62
- [options.indented(indent_level, "#{name} = T.let(nil, #{@value.generate_rbi})")]
70
+ [
71
+ options.indented(indent_level, "#{name} = T.let(nil, #{@value.generate_rbi})"),
72
+ ] + [heredocs].compact
63
73
  end
64
74
  end
65
75
 
@@ -68,7 +78,7 @@ module Parlour
68
78
  others: T::Array[RbiGenerator::RbiObject]
69
79
  ).returns(T::Boolean)
70
80
  end
71
- # Given an array of {Constant} instances, returns true if they may be
81
+ # Given an array of {Constant} instances, returns true if they may be
72
82
  # merged into this instance using {merge_into_self}. This is always false.
73
83
  #
74
84
  # @param others [Array<RbiGenerator::RbiObject>] An array of other
@@ -97,14 +107,16 @@ module Parlour
97
107
 
98
108
  sig { override.returns(T::Array[T.any(Symbol, T::Hash[Symbol, String])]) }
99
109
  def describe_attrs
100
- [:value, :eigen_constant]
110
+ [:value, :eigen_constant, :heredocs]
101
111
  end
102
112
 
103
113
  sig { override.void }
104
114
  def generalize_from_rbi!
105
- # There's a good change this is an untyped constant, so rescue
106
- # ParseError and use untyped
107
- @value = (TypeParser.parse_single_type(@value) if String === @value) rescue Types::Untyped.new
115
+ if @value.is_a?(String)
116
+ # There's a good chance this is an untyped constant, so rescue
117
+ # ParseError and use untyped
118
+ @value = TypeParser.parse_single_type(@value) rescue Types::Untyped.new
119
+ end
108
120
  end
109
121
  end
110
122
  end
@@ -564,7 +564,7 @@ module Parlour
564
564
  returned_includables
565
565
  end
566
566
 
567
- sig { params(name: String, value: String, eigen_constant: T::Boolean, block: T.nilable(T.proc.params(x: Constant).void)).returns(Constant) }
567
+ sig { params(name: String, value: String, eigen_constant: T::Boolean, heredocs: T.nilable(String), block: T.nilable(T.proc.params(x: Constant).void)).returns(Constant) }
568
568
  # Adds a new constant definition to this namespace.
569
569
  #
570
570
  # @example Add an +Elem+ constant to the class.
@@ -574,14 +574,16 @@ module Parlour
574
574
  # @param value [String] The value of the constant, as a Ruby code string.
575
575
  # @param eigen_constant [Boolean] Whether this constant is defined on the
576
576
  # eigenclass of the current namespace.
577
+ # @param heredocs [String,nil] Values of the heredocs used, in order
577
578
  # @param block A block which the new instance yields itself to.
578
579
  # @return [RbiGenerator::Constant]
579
- def create_constant(name, value:, eigen_constant: false, &block)
580
+ def create_constant(name, value:, eigen_constant: false, heredocs: nil, &block)
580
581
  new_constant = RbiGenerator::Constant.new(
581
582
  generator,
582
583
  name: name,
583
584
  value: value,
584
585
  eigen_constant: eigen_constant,
586
+ heredocs: heredocs,
585
587
  &block
586
588
  )
587
589
  move_next_comments(new_constant)
@@ -5,7 +5,8 @@ module Parlour
5
5
  # entire lines of an RBI, such as {Namespace} and {Method}. (As an example,
6
6
  # {Parameter} is _not_ a subclass because it does not generate lines, only
7
7
  # segments of definition and signature lines.)
8
- # @abstract
8
+ #
9
+ # This class is *abstract*.
9
10
  class RbiObject < TypedObject
10
11
  abstract!
11
12
 
@@ -35,7 +36,8 @@ module Parlour
35
36
  end
36
37
  # Generates the RBI lines for this object.
37
38
  #
38
- # @abstract
39
+ # This method is *abstract*.
40
+ #
39
41
  # @param indent_level [Integer] The indentation level to generate the lines at.
40
42
  # @param options [Options] The formatting options to use.
41
43
  # @return [Array<String>] The RBI lines, formatted as specified.
@@ -50,7 +52,8 @@ module Parlour
50
52
  # into this instance using {merge_into_self}. Each subclass will have its
51
53
  # own criteria on what allows objects to be mergeable.
52
54
  #
53
- # @abstract
55
+ # This method is *abstract*.
56
+ #
54
57
  # @param others [Array<RbiGenerator::RbiObject>] An array of other {RbiObject} instances.
55
58
  # @return [Boolean] Whether this instance may be merged with them.
56
59
  def mergeable?(others); end
@@ -64,7 +67,8 @@ module Parlour
64
67
  # subclass will do this differently.
65
68
  # You MUST ensure that {mergeable?} is true for those instances.
66
69
  #
67
- # @abstract
70
+ # This method is *abstract*.
71
+ #
68
72
  # @param others [Array<RbiGenerator::RbiObject>] An array of other {RbiObject} instances.
69
73
  # @return [void]
70
74
  def merge_into_self(others); end
@@ -74,7 +78,8 @@ module Parlour
74
78
  # been specified as RBI-style types, generalises them into type instances
75
79
  # from the {Parlour::Types} module.
76
80
  #
77
- # @abstract
81
+ # This method is *abstract*.
82
+ #
78
83
  # @return [void]
79
84
  def generalize_from_rbi!; end
80
85
  end
@@ -90,7 +90,7 @@ module Parlour
90
90
  # Merge the first signature line, and indent & concat the rest
91
91
  first_line, *rest_lines = *partial_sig_lines
92
92
  this_sig_lines[0] = T.unsafe(this_sig_lines[0]) + first_line
93
- rest_lines&.each do |line|
93
+ rest_lines.each do |line|
94
94
  this_sig_lines << ' ' * definition.length + options.indented(indent_level, line)
95
95
  end
96
96
 
@@ -5,7 +5,8 @@ module Parlour
5
5
  # entire lines of an RBS, such as {Namespace} and {Method}. (As an example,
6
6
  # {Parameter} is _not_ a subclass because it does not generate lines, only
7
7
  # segments of definition lines.)
8
- # @abstract
8
+ #
9
+ # This class is *abstract*.
9
10
  class RbsObject < TypedObject
10
11
  abstract!
11
12
 
@@ -35,7 +36,8 @@ module Parlour
35
36
  end
36
37
  # Generates the RBS lines for this object.
37
38
  #
38
- # @abstract
39
+ # This method is *abstract*.
40
+ #
39
41
  # @param indent_level [Integer] The indentation level to generate the lines at.
40
42
  # @param options [Options] The formatting options to use.
41
43
  # @return [Array<String>] The RBS lines, formatted as specified.
@@ -50,7 +52,8 @@ module Parlour
50
52
  # into this instance using {merge_into_self}. Each subclass will have its
51
53
  # own criteria on what allows objects to be mergeable.
52
54
  #
53
- # @abstract
55
+ # This method is *abstract*.
56
+ #
54
57
  # @param others [Array<RbsGenerator::RbsObject>] An array of other {RbsObject} instances.
55
58
  # @return [Boolean] Whether this instance may be merged with them.
56
59
  def mergeable?(others); end
@@ -64,7 +67,8 @@ module Parlour
64
67
  # subclass will do this differently.
65
68
  # You MUST ensure that {mergeable?} is true for those instances.
66
69
  #
67
- # @abstract
70
+ # This method is *abstract*.
71
+ #
68
72
  # @param others [Array<RbsGenerator::RbsObject>] An array of other {RbsObject} instances.
69
73
  # @return [void]
70
74
  def merge_into_self(others); end
@@ -380,10 +380,12 @@ module Parlour
380
380
  type: T.must(node_to_s(body.to_a[2])),
381
381
  )]
382
382
  else
383
+ heredocs = find_heredocs(body)
383
384
  [Parlour::RbiGenerator::Constant.new(
384
385
  generator,
385
386
  name: T.must(name).to_s,
386
387
  value: T.must(node_to_s(body)),
388
+ heredocs: heredocs
387
389
  )]
388
390
  end
389
391
  else
@@ -406,6 +408,43 @@ module Parlour
406
408
  prop :params, T.nilable(T::Array[Parser::AST::Node])
407
409
  end
408
410
 
411
+ sig { params(body: T.nilable(Parser::AST::Node)).returns(T.nilable(String)) }
412
+ # Given a node in the AST, finds all heredoc definitions within it
413
+ # and return them as a String
414
+ #
415
+ # e.g., for the AST for following code:
416
+ #
417
+ # foo = <<~HEREDOC
418
+ # bar
419
+ # HEREDOC
420
+ #
421
+ # this method would return " bar\nHEREDOC\n"
422
+ def find_heredocs(body)
423
+ heredocs = T.let(nil, T.nilable(String))
424
+
425
+ return heredocs if body.nil?
426
+
427
+ loc = body.loc
428
+
429
+ if loc.instance_of?(Parser::Source::Map::Heredoc)
430
+ return body.loc.expression.source_buffer.source[loc.heredoc_body.begin_pos...loc.heredoc_end.end_pos]
431
+ end
432
+
433
+ body.children.map do |child|
434
+ next unless child.instance_of?(Parser::AST::Node)
435
+
436
+ child_heredocs = find_heredocs(child)
437
+
438
+ next if child_heredocs.nil?
439
+
440
+ heredocs ||= ''
441
+ heredocs += child_heredocs
442
+ heredocs += "\n"
443
+ end
444
+
445
+ heredocs
446
+ end
447
+
409
448
  sig { params(path: NodePath).returns(IntermediateSig) }
410
449
  # Given a path to a sig in the AST, parses that sig into an intermediate
411
450
  # sig object.
@@ -148,7 +148,8 @@ module Parlour
148
148
  # - If it is a hash, it must be of the format { Symbol => String }. The
149
149
  # given string will be used instead of calling the symbol.
150
150
  #
151
- # @abstract
151
+ # This method is *abstract*.
152
+ #
152
153
  # @return [<Symbol, String>]
153
154
  def describe_attrs; end
154
155
 
data/lib/parlour/types.rb CHANGED
@@ -551,9 +551,9 @@ module Parlour
551
551
  rbi_params = parameters.map do |param|
552
552
  RbiGenerator::Parameter.new(param.name, type: param.type, default: param.default)
553
553
  end
554
- "T.proc.params(#{rbi_params.map(&:to_sig_param).join(', ')}).#{
555
- @return_type ? "returns(#{@return_type.generate_rbi})" : 'void'
556
- }"
554
+ "T.proc." +
555
+ (rbi_params.empty? ? "" : "params(#{rbi_params.map(&:to_sig_param).join(', ')}).") +
556
+ (@return_type ? "returns(#{@return_type.generate_rbi})" : 'void')
557
557
  end
558
558
 
559
559
  sig { override.returns(String) }
@@ -575,4 +575,3 @@ module Parlour
575
575
  end
576
576
  end
577
577
  end
578
-
@@ -1,5 +1,5 @@
1
1
  # typed: strong
2
2
  module Parlour
3
3
  # The library version.
4
- VERSION = '9.0.0'
4
+ VERSION = '9.1.1'
5
5
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parlour
3
3
  version: !ruby/object:Gem::Version
4
- version: 9.0.0
4
+ version: 9.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Christiansen
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2024-06-04 00:00:00.000000000 Z
10
+ date: 2025-05-28 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: sorbet-runtime
@@ -150,7 +149,6 @@ dependencies:
150
149
  - - ">="
151
150
  - !ruby/object:Gem::Version
152
151
  version: '0'
153
- description:
154
152
  email:
155
153
  - hello@aaronc.cc
156
154
  executables:
@@ -228,7 +226,6 @@ homepage: https://github.com/AaronC81/parlour
228
226
  licenses:
229
227
  - MIT
230
228
  metadata: {}
231
- post_install_message:
232
229
  rdoc_options: []
233
230
  require_paths:
234
231
  - lib
@@ -243,8 +240,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
243
240
  - !ruby/object:Gem::Version
244
241
  version: '0'
245
242
  requirements: []
246
- rubygems_version: 3.5.9
247
- signing_key:
243
+ rubygems_version: 3.6.2
248
244
  specification_version: 4
249
245
  summary: A type information generator, merger and parser for Sorbet and Ruby 3/Steep
250
246
  test_files: []