parlour 2.0.0 → 5.0.0.beta.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.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug-report.md +0 -0
  3. data/.github/ISSUE_TEMPLATE/feature-request.md +0 -0
  4. data/.gitignore +1 -1
  5. data/.parlour +5 -0
  6. data/.rspec +0 -0
  7. data/.travis.yml +3 -3
  8. data/CHANGELOG.md +64 -0
  9. data/CODE_OF_CONDUCT.md +0 -0
  10. data/Gemfile +0 -0
  11. data/LICENSE.txt +0 -0
  12. data/README.md +233 -19
  13. data/Rakefile +0 -0
  14. data/exe/parlour +109 -4
  15. data/lib/parlour.rb +29 -1
  16. data/lib/parlour/conflict_resolver.rb +75 -27
  17. data/lib/parlour/conversion/converter.rb +34 -0
  18. data/lib/parlour/conversion/rbi_to_rbs.rb +223 -0
  19. data/lib/parlour/debugging.rb +0 -0
  20. data/lib/parlour/detached_rbi_generator.rb +1 -6
  21. data/lib/parlour/detached_rbs_generator.rb +25 -0
  22. data/lib/parlour/generator.rb +34 -0
  23. data/lib/parlour/kernel_hack.rb +0 -0
  24. data/lib/parlour/options.rb +71 -0
  25. data/lib/parlour/parse_error.rb +0 -0
  26. data/lib/parlour/plugin.rb +1 -1
  27. data/lib/parlour/rbi_generator.rb +24 -37
  28. data/lib/parlour/rbi_generator/arbitrary.rb +5 -2
  29. data/lib/parlour/rbi_generator/attribute.rb +14 -5
  30. data/lib/parlour/rbi_generator/class_namespace.rb +8 -3
  31. data/lib/parlour/rbi_generator/constant.rb +28 -8
  32. data/lib/parlour/rbi_generator/enum_class_namespace.rb +32 -5
  33. data/lib/parlour/rbi_generator/extend.rb +5 -2
  34. data/lib/parlour/rbi_generator/include.rb +5 -2
  35. data/lib/parlour/rbi_generator/method.rb +15 -10
  36. data/lib/parlour/rbi_generator/module_namespace.rb +7 -2
  37. data/lib/parlour/rbi_generator/namespace.rb +115 -27
  38. data/lib/parlour/rbi_generator/parameter.rb +13 -7
  39. data/lib/parlour/rbi_generator/rbi_object.rb +19 -78
  40. data/lib/parlour/rbi_generator/struct_class_namespace.rb +110 -0
  41. data/lib/parlour/rbi_generator/struct_prop.rb +139 -0
  42. data/lib/parlour/rbi_generator/type_alias.rb +101 -0
  43. data/lib/parlour/rbs_generator.rb +24 -0
  44. data/lib/parlour/rbs_generator/arbitrary.rb +92 -0
  45. data/lib/parlour/rbs_generator/attribute.rb +82 -0
  46. data/lib/parlour/rbs_generator/block.rb +49 -0
  47. data/lib/parlour/rbs_generator/class_namespace.rb +106 -0
  48. data/lib/parlour/rbs_generator/constant.rb +95 -0
  49. data/lib/parlour/rbs_generator/extend.rb +92 -0
  50. data/lib/parlour/rbs_generator/include.rb +92 -0
  51. data/lib/parlour/rbs_generator/interface_namespace.rb +34 -0
  52. data/lib/parlour/rbs_generator/method.rb +146 -0
  53. data/lib/parlour/rbs_generator/method_signature.rb +104 -0
  54. data/lib/parlour/rbs_generator/module_namespace.rb +35 -0
  55. data/lib/parlour/rbs_generator/namespace.rb +627 -0
  56. data/lib/parlour/rbs_generator/parameter.rb +145 -0
  57. data/lib/parlour/rbs_generator/rbs_object.rb +78 -0
  58. data/lib/parlour/rbs_generator/type_alias.rb +96 -0
  59. data/lib/parlour/type_loader.rb +30 -10
  60. data/lib/parlour/type_parser.rb +440 -43
  61. data/lib/parlour/typed_object.rb +87 -0
  62. data/lib/parlour/types.rb +445 -0
  63. data/lib/parlour/version.rb +1 -1
  64. data/parlour.gemspec +2 -2
  65. data/plugin_examples/foobar_plugin.rb +0 -0
  66. data/rbi/parlour.rbi +1799 -0
  67. metadata +42 -15
  68. data/lib/parlour/rbi_generator/options.rb +0 -74
@@ -0,0 +1,92 @@
1
+ # typed: true
2
+ module Parlour
3
+ class RbsGenerator < Generator
4
+ # Represents an +extend+ call.
5
+ class Extend < RbsObject
6
+ sig do
7
+ params(
8
+ generator: Generator,
9
+ type: Types::TypeLike,
10
+ block: T.nilable(T.proc.params(x: Extend).void)
11
+ ).void
12
+ end
13
+ # Creates a new +extend+ call.
14
+ #
15
+ # @param type [Types::TypeLike] The type to extend.
16
+ def initialize(generator, type:, &block)
17
+ super(generator, '')
18
+ @type = type
19
+ yield_self(&block) if block
20
+ end
21
+
22
+ sig { params(other: Object).returns(T::Boolean) }
23
+ # Returns true if this instance is equal to another extend.
24
+ #
25
+ # @param other [Object] The other instance. If this is not a {Extend} (or a
26
+ # subclass of it), this will always return false.
27
+ # @return [Boolean]
28
+ def ==(other)
29
+ Extend === other && type == other.type
30
+ end
31
+
32
+ sig { returns(Types::TypeLike) }
33
+ # @return [Types::TypeLike] The type to extend.
34
+ attr_reader :type
35
+
36
+ sig do
37
+ override.params(
38
+ indent_level: Integer,
39
+ options: Options
40
+ ).returns(T::Array[String])
41
+ end
42
+ # Generates the RBS lines for this extend.
43
+ #
44
+ # @param indent_level [Integer] The indentation level to generate the lines at.
45
+ # @param options [Options] The formatting options to use.
46
+ # @return [Array<String>] The RBS lines, formatted as specified.
47
+ def generate_rbs(indent_level, options)
48
+ [options.indented(indent_level, "extend #{String === @type ? @type : @type.generate_rbs}")]
49
+ end
50
+
51
+ sig do
52
+ override.params(
53
+ others: T::Array[RbsGenerator::RbsObject]
54
+ ).returns(T::Boolean)
55
+ end
56
+ # Given an array of {Extend} instances, returns true if they may be
57
+ # merged into this instance using {merge_into_self}. This is always false.
58
+ #
59
+ # @param others [Array<RbsGenerator::RbsObject>] An array of other
60
+ # {Extend} instances.
61
+ # @return [Boolean] Whether this instance may be merged with them.
62
+ def mergeable?(others)
63
+ others.all? { |other| self == other }
64
+ end
65
+
66
+ sig do
67
+ override.params(
68
+ others: T::Array[RbsGenerator::RbsObject]
69
+ ).void
70
+ end
71
+ # Given an array of {Extend} instances, merges them into this one.
72
+ # This particular implementation will simply do nothing, as instances
73
+ # are only mergeable if they are indentical.
74
+ # You MUST ensure that {mergeable?} is true for those instances.
75
+ #
76
+ # @param others [Array<RbsGenerator::RbsObject>] An array of other
77
+ # {Extend} instances.
78
+ # @return [void]
79
+ def merge_into_self(others)
80
+ # We don't need to change anything! We only merge identical extends
81
+ end
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})"
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,92 @@
1
+ # typed: true
2
+ module Parlour
3
+ class RbsGenerator < Generator
4
+ # Represents an +include+ call.
5
+ class Include < RbsObject
6
+ sig do
7
+ params(
8
+ generator: Generator,
9
+ type: Types::TypeLike,
10
+ block: T.nilable(T.proc.params(x: Include).void)
11
+ ).void
12
+ end
13
+ # Creates a new +include+ call.
14
+ #
15
+ # @param type [Types::TypeLike] The type to include.
16
+ def initialize(generator, type:, &block)
17
+ super(generator, '')
18
+ @type = type
19
+ yield_self(&block) if block
20
+ end
21
+
22
+ sig { params(other: Object).returns(T::Boolean) }
23
+ # Returns true if this instance is equal to another include.
24
+ #
25
+ # @param other [Object] The other instance. If this is not a {Include} (or a
26
+ # subclass of it), this will always return false.
27
+ # @return [Boolean]
28
+ def ==(other)
29
+ Include === other && type == other.type
30
+ end
31
+
32
+ sig { returns(Types::TypeLike) }
33
+ # @return [Types::TypeLike] The type to include.
34
+ attr_reader :type
35
+
36
+ sig do
37
+ override.params(
38
+ indent_level: Integer,
39
+ options: Options
40
+ ).returns(T::Array[String])
41
+ end
42
+ # Generates the RBS lines for this include.
43
+ #
44
+ # @param indent_level [Integer] The indentation level to generate the lines at.
45
+ # @param options [Options] The formatting options to use.
46
+ # @return [Array<String>] The RBS lines, formatted as specified.
47
+ def generate_rbs(indent_level, options)
48
+ [options.indented(indent_level, "include #{String === @type ? @type : @type.generate_rbs}")]
49
+ end
50
+
51
+ sig do
52
+ override.params(
53
+ others: T::Array[RbsGenerator::RbsObject]
54
+ ).returns(T::Boolean)
55
+ end
56
+ # Given an array of {Include} instances, returns true if they may be
57
+ # merged into this instance using {merge_into_self}. This is always false.
58
+ #
59
+ # @param others [Array<RbsGenerator::RbsObject>] An array of other
60
+ # {Include} instances.
61
+ # @return [Boolean] Whether this instance may be merged with them.
62
+ def mergeable?(others)
63
+ others.all? { |other| self == other }
64
+ end
65
+
66
+ sig do
67
+ override.params(
68
+ others: T::Array[RbsGenerator::RbsObject]
69
+ ).void
70
+ end
71
+ # Given an array of {Include} instances, merges them into this one.
72
+ # This particular implementation will simply do nothing, as instances
73
+ # are only mergeable if they are indentical.
74
+ # You MUST ensure that {mergeable?} is true for those instances.
75
+ #
76
+ # @param others [Array<RbsGenerator::RbsObject>] An array of other
77
+ # {Include} instances.
78
+ # @return [void]
79
+ def merge_into_self(others)
80
+ # We don't need to change anything! We only merge identical includes
81
+ end
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})"
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,34 @@
1
+ # typed: true
2
+ module Parlour
3
+ class RbsGenerator < Generator
4
+ # Represents an interface definition.
5
+ class InterfaceNamespace < Namespace
6
+ extend T::Sig
7
+
8
+ sig do
9
+ override.params(
10
+ indent_level: Integer,
11
+ options: Options
12
+ ).returns(T::Array[String])
13
+ end
14
+ # Generates the RBS lines for this interface.
15
+ #
16
+ # @param indent_level [Integer] The indentation level to generate the lines at.
17
+ # @param options [Options] The formatting options to use.
18
+ # @return [Array<String>] The RBS lines, formatted as specified.
19
+ def generate_rbs(indent_level, options)
20
+ lines = generate_comments(indent_level, options)
21
+ lines << options.indented(indent_level, "interface #{name}")
22
+ lines += generate_body(indent_level + 1, options)
23
+ lines << options.indented(indent_level, "end")
24
+ end
25
+
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}"
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,146 @@
1
+ # typed: true
2
+ module Parlour
3
+ class RbsGenerator < Generator
4
+ # Represents a method definition.
5
+ class Method < RbsObject
6
+ extend T::Sig
7
+
8
+ sig do
9
+ params(
10
+ generator: Generator,
11
+ name: String,
12
+ signatures: T::Array[MethodSignature],
13
+ class_method: T::Boolean,
14
+ block: T.nilable(T.proc.params(x: Method).void)
15
+ ).void
16
+ end
17
+ # Creates a new method definition.
18
+ # @note You should use {Namespace#create_method} rather than this directly.
19
+ #
20
+ # @param generator [RbsGenerator] The current RbsGenerator.
21
+ # @param name [String] The name of this method. You should not specify +self.+ in
22
+ # this - use the +class_method+ parameter instead.
23
+ # @param signatures [Array<MethodSignature>] The signatures for each
24
+ # overload of this method.
25
+ # @param class_method [Boolean] Whether this method is a class method; that is, it
26
+ # it is defined using +self.+.
27
+ # @param block A block which the new instance yields itself to.
28
+ # @return [void]
29
+ def initialize(generator, name, signatures, class_method: false, &block)
30
+ super(generator, name)
31
+ @signatures = signatures
32
+ @class_method = class_method
33
+ yield_self(&block) if block
34
+ end
35
+
36
+ sig { overridable.params(other: Object).returns(T::Boolean).checked(:never) }
37
+ # Returns true if this instance is equal to another method.
38
+ #
39
+ # @param other [Object] The other instance. If this is not a {Method} (or a
40
+ # subclass of it), this will always return false.
41
+ # @return [Boolean]
42
+ def ==(other)
43
+ Method === other &&
44
+ name == other.name &&
45
+ signatures == other.signatures &&
46
+ class_method == other.class_method
47
+ end
48
+
49
+ sig { returns(T::Array[MethodSignature]) }
50
+ # The signatures for each overload of this method.
51
+ # @return [Array<MethodSignature>]
52
+ attr_reader :signatures
53
+
54
+ sig { returns(T::Boolean) }
55
+ # Whether this method is a class method; that is, it it is defined using
56
+ # +self.+.
57
+ # @return [Boolean]
58
+ attr_reader :class_method
59
+
60
+ sig do
61
+ override.params(
62
+ indent_level: Integer,
63
+ options: Options
64
+ ).returns(T::Array[String])
65
+ end
66
+ # Generates the RBS lines for this method.
67
+ #
68
+ # @param indent_level [Integer] The indentation level to generate the lines at.
69
+ # @param options [Options] The formatting options to use.
70
+ # @return [Array<String>] The RBS lines, formatted as specified.
71
+ def generate_rbs(indent_level, options)
72
+ definition = "def #{class_method ? 'self.' : ''}#{name}: "
73
+ lines = generate_comments(indent_level, options)
74
+
75
+ # Handle each signature
76
+ signatures.each.with_index do |sig, i|
77
+ this_sig_lines = []
78
+
79
+ # Start off the first line of the signature, either with the definition
80
+ # for the first signature, or a pipe for the rest
81
+ if i == 0
82
+ this_sig_lines << options.indented(indent_level, definition)
83
+ else
84
+ this_sig_lines << options.indented(indent_level, "#{' ' * (definition.length - 2)}| ")
85
+ end
86
+
87
+ # Generate the signature's lines, we'll append them afterwards
88
+ partial_sig_lines = sig.generate_rbs(options)
89
+
90
+ # Merge the first signature line, and indent & concat the rest
91
+ first_line, *rest_lines = *partial_sig_lines
92
+ this_sig_lines[0] += first_line
93
+ rest_lines&.each do |line|
94
+ this_sig_lines << ' ' * definition.length + options.indented(indent_level, line)
95
+ end
96
+
97
+ # Add on all this signature's lines to the complete lines
98
+ lines += this_sig_lines
99
+ end
100
+
101
+ lines
102
+ end
103
+
104
+ sig do
105
+ override.params(
106
+ others: T::Array[RbsGenerator::RbsObject]
107
+ ).returns(T::Boolean)
108
+ end
109
+ # Given an array of {Method} instances, returns true if they may be merged
110
+ # into this instance using {merge_into_self}. For instances to be
111
+ # mergeable, their signatures and definitions must be identical.
112
+ #
113
+ # @param others [Array<RbsGenerator::RbsObject>] An array of other {Method} instances.
114
+ # @return [Boolean] Whether this instance may be merged with them.
115
+ def mergeable?(others)
116
+ others.all? { |other| self == other }
117
+ end
118
+
119
+ sig do
120
+ override.params(
121
+ others: T::Array[RbsGenerator::RbsObject]
122
+ ).void
123
+ end
124
+ # Given an array of {Method} instances, merges them into this one.
125
+ # This particular implementation in fact does nothing, because {Method}
126
+ # instances are only mergeable if they are identical, so nothing needs
127
+ # to be changed.
128
+ # You MUST ensure that {mergeable?} is true for those instances.
129
+ #
130
+ # @param others [Array<RbsGenerator::RbsObject>] An array of other {Method} instances.
131
+ # @return [void]
132
+ def merge_into_self(others)
133
+ # TODO: merge signatures of different definitions
134
+ end
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"
143
+ end
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,104 @@
1
+ # typed: true
2
+ module Parlour
3
+ class RbsGenerator < Generator
4
+ # Represents one signature in a method definition.
5
+ # (This is not an RbsObject because it doesn't generate a full line.)
6
+ class MethodSignature
7
+ extend T::Sig
8
+
9
+ sig do
10
+ params(
11
+ parameters: T::Array[Parameter],
12
+ return_type: T.nilable(Types::TypeLike),
13
+ block: T.nilable(Block),
14
+ type_parameters: T.nilable(T::Array[Symbol])
15
+ ).void
16
+ end
17
+ # Creates a new method signature.
18
+ #
19
+ # @param parameters [Array<Parameter>] An array of {Parameter} instances representing this
20
+ # method's parameters.
21
+ # @param return_type [Types::TypeLike, nil] What this method returns. Passing nil denotes a void return.
22
+ # @param block [Types::TypeLike, nil] The block this method accepts. Passing nil denotes none.
23
+ # @param type_parameters [Array<Symbol>, nil] This method's type parameters.
24
+ # @return [void]
25
+ def initialize(parameters, return_type = nil, block: nil, type_parameters: nil)
26
+ @parameters = parameters
27
+ @return_type = return_type
28
+ @block = block
29
+ @type_parameters = type_parameters || []
30
+ end
31
+
32
+ sig { overridable.params(other: Object).returns(T::Boolean).checked(:never) }
33
+ # Returns true if this instance is equal to another method signature.
34
+ #
35
+ # @param other [Object] The other instance. If this is not a {MethodSignature} (or a
36
+ # subclass of it), this will always return false.
37
+ # @return [Boolean]
38
+ def ==(other)
39
+ MethodSignature === other &&
40
+ parameters == other.parameters &&
41
+ return_type == other.return_type &&
42
+ block == other.block &&
43
+ type_parameters == other.type_parameters
44
+ end
45
+
46
+ sig { returns(T::Array[Parameter]) }
47
+ # An array of {Parameter} instances representing this method's parameters.
48
+ # @return [Array<Parameter>]
49
+ attr_reader :parameters
50
+
51
+ sig { returns(T.nilable(Types::TypeLike)) }
52
+ # What this method returns. Passing nil denotes a void return.
53
+ # @return [Types::TypeLike, nil]
54
+ attr_reader :return_type
55
+
56
+ sig { returns(T.nilable(Block)) }
57
+ # The block this method accepts.
58
+ # @return [Block, nil]
59
+ attr_reader :block
60
+
61
+ sig { returns(T::Array[Symbol]) }
62
+ # This method's type parameters.
63
+ # @return [Array<Symbol>]
64
+ attr_reader :type_parameters
65
+
66
+ sig { params(options: Options).returns(T::Array[String]) }
67
+ # Generates the RBS string for this signature.
68
+ #
69
+ # @param options [Options] The formatting options to use.
70
+ # @return [Array<String>] The RBS string, formatted as specified.
71
+ def generate_rbs(options)
72
+ block_type = @block&.generate_rbs(options)
73
+
74
+ rbs_params = parameters.reject { |x| x.kind == :block }.map(&:to_rbs_param)
75
+ rbs_return_type = String === @return_type ? @return_type : @return_type&.generate_rbs
76
+
77
+ generated_params = parameters.length >= options.break_params \
78
+ ? ["("] +
79
+ (
80
+ parameters.empty? ? [] : rbs_params.map.with_index do |x, i|
81
+ options.indented(
82
+ 1,
83
+ # Don't include the comma on the last parameter.
84
+ parameters.length == i + 1 ? "#{x}" : "#{x},"
85
+ )
86
+ end
87
+ ) +
88
+ [")"]
89
+
90
+ : ["(#{rbs_params.join(', ')})"]
91
+
92
+ generated_params[0] = "#{
93
+ type_parameters.any? ? "[#{type_parameters.join(', ')}] " : ''
94
+ }" + T.must(generated_params[0])
95
+
96
+ generated_params[-1] = T.must(generated_params[-1]) + "#{
97
+ (block_type && block_type != 'untyped') ? block_type.first : '' # TODO: doesn't support multi-line block types
98
+ } -> #{rbs_return_type || 'void'}"
99
+
100
+ generated_params
101
+ end
102
+ end
103
+ end
104
+ end