parlour 8.1.0 → 9.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f3849a9995ec5ce41eeee0c180ac14d76d6e5ee2c7c7f9ecd61760d4279fc887
4
- data.tar.gz: bd5ee90c62e2c55eebd233fec2bff3a0974e24204d79cecc627bce48e413dd64
3
+ metadata.gz: 4f18ccd38395c2840b06304074efe58ed6b0f72b6c12bf727234b182adce886d
4
+ data.tar.gz: afea2a669210749f9ad5bd8eb59eba9a02dfbbc4ef8069905a0c7fcfaef28f1a
5
5
  SHA512:
6
- metadata.gz: 2de0e9b4aa6cd1c52a55453b7bf03da1247815a090de02ae0b105057c16e1aad0ed1ddf32d20dffc0727510321fb69b902b07a7e0bd03f268cb7331c0449b8cc
7
- data.tar.gz: af13b87ff52638b9cefb29356dd7dec277667ef36ff656b4ced99c348cb9252828345c3de7f20d443594a7c09757ecd273e33d704df00109e5e4d2eafd5d3b0d
6
+ metadata.gz: 20da270743193873e21be0422e6d834b3aa4fa042ad4e1e44eab1ec5abcf5a70ef1a67178cb4946155ed7776354d1e7ad918511d3fa8aec44b79150212764dfa
7
+ data.tar.gz: c751ab8c92da95ddf0450c1ab5259a87e8c88b9443cb2628d53a8dbec85830f0b5016271f56d0c0300250bde212dff361f9b46c5b29e5df1f8eb732970a8adf9
@@ -10,7 +10,7 @@ jobs:
10
10
  test:
11
11
  strategy:
12
12
  matrix:
13
- ruby: [2.4, 2.5, 2.6, 2.7, 3.0, 3.1, 3.2]
13
+ ruby: [3.0, 3.1, 3.2]
14
14
  continue-on-error: false
15
15
 
16
16
  runs-on: ubuntu-latest
@@ -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.0] - 2025-03-03
7
+ ### Added
8
+ - Constants can now be generated or parsed with heredoc strings. (Thanks @apiology)
9
+
10
+ ### Fixed
11
+ - `T.proc` types with no parameters are now emitted correctly. Previously, they emitted an invalid
12
+ call to `params()` - now they emit no usage of `params`. (Thanks @apiology)
13
+
14
+ ## [9.0.0] - 2024-06-04
15
+ ### Changed
16
+ - Updated Commander dependency to 5.0, to remove `abbrev` deprecation warning.
17
+ **As a result, the minimum supported Ruby version is now 3.0.**
18
+
6
19
  ## [8.1.0] - 2023-01-01
7
20
  ### Added
8
21
  - Parsed method definitions can now have a modifier before the `def` keyword.
@@ -36,11 +36,11 @@ module Parlour
36
36
  @class_attribute = class_attribute
37
37
  case kind
38
38
  when :accessor, :reader
39
- super(generator, name, [], type, &block)
39
+ super(generator, name, [], type, &T.cast(block, T.nilable(T.proc.params(x: Method).void)))
40
40
  when :writer
41
41
  super(generator, name, [
42
42
  Parameter.new(name, type: type)
43
- ], type, &block)
43
+ ], type, &T.cast(block, T.nilable(T.proc.params(x: Method).void)))
44
44
  else
45
45
  raise 'unknown kind'
46
46
  end
@@ -31,7 +31,7 @@ module Parlour
31
31
  # @param block A block which the new instance yields itself to.
32
32
  # @return [void]
33
33
  def initialize(generator, name, final, sealed, superclass, abstract, &block)
34
- super(generator, name, final, sealed, &block)
34
+ super(generator, name, final, sealed, &T.cast(block, T.nilable(T.proc.params(x: Namespace).void)))
35
35
  @superclass = superclass
36
36
  @abstract = abstract
37
37
  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
@@ -30,7 +30,7 @@ module Parlour
30
30
  # @param block A block which the new instance yields itself to.
31
31
  # @return [void]
32
32
  def initialize(generator, name, final, sealed, enums, abstract, &block)
33
- super(generator, name, final, sealed, 'T::Enum', abstract, &block)
33
+ super(generator, name, final, sealed, 'T::Enum', abstract, &T.cast(block, T.nilable(T.proc.params(x: Namespace).void)))
34
34
  @enums = enums
35
35
  end
36
36
 
@@ -31,7 +31,7 @@ module Parlour
31
31
  # @param block A block which the new instance yields itself to.
32
32
  # @return [void]
33
33
  def initialize(generator, name, final, sealed, interface, abstract, &block)
34
- super(generator, name, final, sealed, &block)
34
+ super(generator, name, final, sealed, &T.cast(block, T.nilable(T.proc.params(x: Namespace).void)))
35
35
  @name = name
36
36
  @interface = interface
37
37
  @abstract = abstract
@@ -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)
@@ -31,7 +31,7 @@ module Parlour
31
31
  # @param block A block which the new instance yields itself to.
32
32
  # @return [void]
33
33
  def initialize(generator, name, final, sealed, props, abstract, &block)
34
- super(generator, name, final, sealed, 'T::Struct', abstract, &block)
34
+ super(generator, name, final, sealed, 'T::Struct', abstract, &T.cast(block, T.nilable(T.proc.params(x: Namespace).void)))
35
35
  @props = props
36
36
  end
37
37
 
@@ -29,11 +29,11 @@ module Parlour
29
29
  @kind = kind
30
30
  case kind
31
31
  when :accessor, :reader
32
- super(generator, name, [MethodSignature.new([], type)], &block)
32
+ super(generator, name, [MethodSignature.new([], type)], &T.cast(block, T.nilable(T.proc.params(x: Method).void)))
33
33
  when :writer
34
34
  super(generator, name, [MethodSignature.new([
35
35
  Parameter.new(name, type: type)
36
- ], type)], &block)
36
+ ], type)], &T.cast(block, T.nilable(T.proc.params(x: Method).void)))
37
37
  else
38
38
  raise 'unknown kind'
39
39
  end
@@ -25,7 +25,7 @@ module Parlour
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)
28
- super(generator, name, &block)
28
+ super(generator, name, &T.cast(block, T.nilable(T.proc.params(x: Namespace).void)))
29
29
  @superclass = superclass
30
30
  end
31
31
 
@@ -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
 
@@ -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.
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 = '8.1.0'
4
+ VERSION = '9.1.0'
5
5
  end
data/parlour.gemspec CHANGED
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
24
24
 
25
25
  spec.add_dependency "sorbet-runtime", ">= 0.5"
26
26
  spec.add_dependency "rainbow", "~> 3.0"
27
- spec.add_dependency "commander", "~> 4.5"
27
+ spec.add_dependency "commander", "~> 5.0"
28
28
  spec.add_dependency "parser"
29
29
 
30
30
  spec.add_development_dependency "bundler", "~> 2.0"
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: 8.1.0
4
+ version: 9.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Christiansen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-01-01 00:00:00.000000000 Z
11
+ date: 2025-03-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sorbet-runtime
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '4.5'
47
+ version: '5.0'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '4.5'
54
+ version: '5.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: parser
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -243,7 +243,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
243
243
  - !ruby/object:Gem::Version
244
244
  version: '0'
245
245
  requirements: []
246
- rubygems_version: 3.4.1
246
+ rubygems_version: 3.5.9
247
247
  signing_key:
248
248
  specification_version: 4
249
249
  summary: A type information generator, merger and parser for Sorbet and Ruby 3/Steep