parlour 4.0.0 → 5.0.0.beta.4

Sign up to get free protection for your applications and to get access to all the features.
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 +0 -0
  6. data/.rspec +0 -0
  7. data/.travis.yml +0 -0
  8. data/CHANGELOG.md +52 -0
  9. data/CODE_OF_CONDUCT.md +0 -0
  10. data/Gemfile +0 -0
  11. data/LICENSE.txt +0 -0
  12. data/README.md +208 -20
  13. data/Rakefile +0 -0
  14. data/exe/parlour +45 -6
  15. data/lib/parlour.rb +27 -1
  16. data/lib/parlour/conflict_resolver.rb +31 -9
  17. data/lib/parlour/conversion/converter.rb +34 -0
  18. data/lib/parlour/conversion/rbi_to_rbs.rb +229 -0
  19. data/lib/parlour/debugging.rb +0 -0
  20. data/lib/parlour/detached_rbi_generator.rb +0 -0
  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 +0 -0
  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 +17 -6
  32. data/lib/parlour/rbi_generator/enum_class_namespace.rb +8 -3
  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 +40 -13
  38. data/lib/parlour/rbi_generator/parameter.rb +11 -5
  39. data/lib/parlour/rbi_generator/rbi_object.rb +19 -78
  40. data/lib/parlour/rbi_generator/struct_class_namespace.rb +9 -2
  41. data/lib/parlour/rbi_generator/struct_prop.rb +12 -9
  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 +146 -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 +0 -0
  60. data/lib/parlour/type_parser.rb +174 -5
  61. data/lib/parlour/typed_object.rb +87 -0
  62. data/lib/parlour/types.rb +539 -0
  63. data/lib/parlour/version.rb +1 -1
  64. data/parlour.gemspec +1 -1
  65. data/plugin_examples/foobar_plugin.rb +0 -0
  66. data/rbi/parlour.rbi +1404 -441
  67. metadata +33 -10
  68. data/lib/parlour/rbi_generator/options.rb +0 -74
@@ -0,0 +1,24 @@
1
+ # typed: true
2
+ module Parlour
3
+ # The RBS generator.
4
+ class RbsGenerator < Generator
5
+ def initialize(**hash)
6
+ super
7
+ @root = RbsGenerator::Namespace.new(self)
8
+ end
9
+
10
+ sig { overridable.returns(RbsGenerator::Namespace) }
11
+ # The root {Namespace} of this generator.
12
+ # @return [Namespace]
13
+ attr_reader :root
14
+
15
+ sig { overridable.returns(String) }
16
+ # Returns the complete contents of the generated RBS file as a string.
17
+ #
18
+ # @return [String] The generated RBS file
19
+ def rbs
20
+ root.generate_rbs(0, options).join("\n")
21
+ end
22
+ end
23
+ end
24
+
@@ -0,0 +1,92 @@
1
+ # typed: true
2
+ module Parlour
3
+ class RbsGenerator < Generator
4
+ # Represents miscellaneous Ruby code.
5
+ class Arbitrary < RbsObject
6
+ sig do
7
+ params(
8
+ generator: Generator,
9
+ code: String,
10
+ block: T.nilable(T.proc.params(x: Arbitrary).void)
11
+ ).void
12
+ end
13
+ # Creates new arbitrary code.
14
+ #
15
+ # @param code [String] The arbitrary code string. Indentation is added to
16
+ # the beginning of each line.
17
+ def initialize(generator, code: '', &block)
18
+ super(generator, '')
19
+ @code = code
20
+ yield_self(&block) if block
21
+ end
22
+
23
+ sig { returns(String) }
24
+ # Returns arbitrary code string.
25
+ attr_accessor :code
26
+
27
+ sig { params(other: Object).returns(T::Boolean) }
28
+ # Returns true if this instance is equal to another arbitrary code line.
29
+ #
30
+ # @param other [Object] The other instance. If this is not a {Arbitrary} (or a
31
+ # subclass of it), this will always return false.
32
+ # @return [Boolean]
33
+ def ==(other)
34
+ Arbitrary === other && code == other.code
35
+ end
36
+
37
+ sig do
38
+ override.params(
39
+ indent_level: Integer,
40
+ options: Options
41
+ ).returns(T::Array[String])
42
+ end
43
+ # Generates the RBS lines for this arbitrary code.
44
+ #
45
+ # @param indent_level [Integer] The indentation level to generate the lines at.
46
+ # @param options [Options] The formatting options to use.
47
+ # @return [Array<String>] The RBS lines, formatted as specified.
48
+ def generate_rbs(indent_level, options)
49
+ code.split("\n").map { |l| options.indented(indent_level, l) }
50
+ end
51
+
52
+ sig do
53
+ override.params(
54
+ others: T::Array[RbsGenerator::RbsObject]
55
+ ).returns(T::Boolean)
56
+ end
57
+ # Given an array of {Arbitrary} instances, returns true if they may be
58
+ # merged into this instance using {merge_into_self}. This is always false.
59
+ #
60
+ # @param others [Array<RbsGenerator::RbsObject>] An array of other
61
+ # {Arbitrary} instances.
62
+ # @return [Boolean] Whether this instance may be merged with them.
63
+ def mergeable?(others)
64
+ false
65
+ end
66
+
67
+ sig do
68
+ override.params(
69
+ others: T::Array[RbsGenerator::RbsObject]
70
+ ).void
71
+ end
72
+ # Given an array of {Arbitrary} instances, merges them into this one.
73
+ # This particular implementation always throws an exception, because
74
+ # {mergeable?} is always false.
75
+ #
76
+ # @param others [Array<RbsGenerator::RbsObject>] An array of other
77
+ # {Arbitrary} instances.
78
+ # @return [void]
79
+ def merge_into_self(others)
80
+ raise 'arbitrary code is never mergeable'
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
+ "Arbitrary code (#{code})"
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,82 @@
1
+ # typed: true
2
+ module Parlour
3
+ class RbsGenerator < Generator
4
+ # Represents an attribute reader, writer or accessor.
5
+ class Attribute < RbsGenerator::Method
6
+ extend T::Sig
7
+
8
+ sig do
9
+ params(
10
+ generator: Generator,
11
+ name: String,
12
+ kind: Symbol,
13
+ type: Types::TypeLike,
14
+ block: T.nilable(T.proc.params(x: Attribute).void)
15
+ ).void
16
+ end
17
+ # Creates a new attribute.
18
+ # @note You should use {Namespace#create_attribute} rather than this directly.
19
+ #
20
+ # @param generator [RbsGenerator] The current RbsGenerator.
21
+ # @param name [String] The name of this attribute.
22
+ # @param kind [Symbol] The kind of attribute this is; one of :writer, :reader or
23
+ # :accessor.
24
+ # @param type [String, Types::Type] This attribute's type.
25
+ # @param block A block which the new instance yields itself to.
26
+ # @return [void]
27
+ def initialize(generator, name, kind, type, &block)
28
+ @type = type
29
+ @kind = kind
30
+ case kind
31
+ when :accessor, :reader
32
+ super(generator, name, [MethodSignature.new([], type)], &block)
33
+ when :writer
34
+ super(generator, name, [MethodSignature.new([
35
+ Parameter.new(name, type: type)
36
+ ], type)], &block)
37
+ else
38
+ raise 'unknown kind'
39
+ end
40
+ end
41
+
42
+ sig { returns(Symbol) }
43
+ # The kind of attribute this is; one of +:writer+, +:reader+, or +:accessor+.
44
+ # @return [Symbol]
45
+ attr_reader :kind
46
+
47
+ sig { returns(Types::TypeLike) }
48
+ # The type of this attribute.
49
+ attr_reader :type
50
+
51
+ sig do
52
+ override.params(
53
+ indent_level: Integer,
54
+ options: Options
55
+ ).returns(T::Array[String])
56
+ end
57
+ # Generates the RBS lines for this arbstrary code.
58
+ #
59
+ # @param indent_level [Integer] The indentation level to generate the lines at.
60
+ # @param options [Options] The formatting options to use.
61
+ # @return [Array<String>] The RBS lines, formatted as specified.
62
+ def generate_rbs(indent_level, options)
63
+ generate_comments(indent_level, options) + [options.indented(
64
+ indent_level,
65
+ "attr_#{kind} #{name}: #{String === @type ? @type : @type.generate_rbs}"
66
+ )]
67
+ end
68
+
69
+ sig { override.params(other: Object).returns(T::Boolean) }
70
+ # Returns true if this instance is equal to another attribute.
71
+ #
72
+ # @param other [Object] The other instance. If this is not a {Attribute}
73
+ # (or a subclass of it), this will always return false.
74
+ # @return [Boolean]
75
+ def ==(other)
76
+ T.must(
77
+ super(other) && Attribute === other && kind == other.kind
78
+ )
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,49 @@
1
+ # typed: true
2
+ module Parlour
3
+ class RbsGenerator < Generator
4
+ # Represents a block in a method signature.
5
+ # (This is not an RbsObject because it doesn't generate a full line.)
6
+ class Block
7
+ extend T::Sig
8
+
9
+ sig { params(type: Types::Proc, required: T::Boolean).void }
10
+ # Creates a new block for a method signature.
11
+ #
12
+ # @param type [Types::Proc] The type of this block.
13
+ # @param required [T::Boolean] Whether this block is required.
14
+ def initialize(type, required)
15
+ @type = type
16
+ @required = required
17
+ end
18
+
19
+ sig { overridable.params(other: Object).returns(T::Boolean).checked(:never) }
20
+ # Returns true if this instance is equal to another method signature.
21
+ #
22
+ # @param other [Object] The other instance. If this is not a {MethodSignature} (or a
23
+ # subclass of it), this will always return false.
24
+ # @return [Boolean]
25
+ def ==(other)
26
+ Block === other && type == other.type && required == other.required
27
+ end
28
+
29
+ sig { returns(Types::Proc) }
30
+ # The type of this block.
31
+ # @return [Types::Proc]
32
+ attr_reader :type
33
+
34
+ sig { returns(T::Boolean) }
35
+ # Whether this block is required.
36
+ # @return [Boolean]
37
+ attr_reader :required
38
+
39
+ sig { params(options: Options).returns(T::Array[String]) }
40
+ # Generates the RBS string for this signature.
41
+ #
42
+ # @param options [Options] The formatting options to use.
43
+ # @return [Array<String>] The RBS string, formatted as specified.
44
+ def generate_rbs(options)
45
+ ["#{required ? '' : '?'}{ #{type.generate_rbs} }"]
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,106 @@
1
+ # typed: true
2
+ module Parlour
3
+ class RbsGenerator < Generator
4
+ # Represents a class definition.
5
+ class ClassNamespace < Namespace
6
+ extend T::Sig
7
+
8
+ sig do
9
+ params(
10
+ generator: Generator,
11
+ name: String,
12
+ superclass: T.nilable(Types::TypeLike),
13
+ block: T.nilable(T.proc.params(x: ClassNamespace).void)
14
+ ).void
15
+ end
16
+ # Creates a new class definition.
17
+ # @note You should use {Namespace#create_class} rather than this directly.
18
+ #
19
+ # @param generator [RbsGenerator] The current RbsGenerator.
20
+ # @param name [String] The name of this class.
21
+ # @param final [Boolean] Whether this namespace is final.
22
+ # @param superclass [String, nil] The superclass of this class, or nil if it doesn't
23
+ # have one.
24
+ # @param abstract [Boolean] A boolean indicating whether this class is abstract.
25
+ # @param block A block which the new instance yields itself to.
26
+ # @return [void]
27
+ def initialize(generator, name, superclass, &block)
28
+ super(generator, name, &block)
29
+ @superclass = superclass
30
+ end
31
+
32
+ sig do
33
+ override.params(
34
+ indent_level: Integer,
35
+ options: Options
36
+ ).returns(T::Array[String])
37
+ end
38
+ def generate_rbs(indent_level, options)
39
+ class_definition = @superclass.nil? \
40
+ ? "class #{name}"
41
+ : "class #{name} < #{String === @superclass ? @superclass : @superclass.generate_rbs}"
42
+
43
+ lines = generate_comments(indent_level, options)
44
+ lines << options.indented(indent_level, class_definition)
45
+ lines += generate_body(indent_level + 1, options)
46
+ lines << options.indented(indent_level, "end")
47
+ end
48
+
49
+ sig { returns(T.nilable(Types::TypeLike)) }
50
+ # The superclass of this class, or nil if it doesn't have one.
51
+ # @return [Types::TypeLike, nil]
52
+ attr_reader :superclass
53
+
54
+ sig do
55
+ override.params(
56
+ others: T::Array[RbsGenerator::RbsObject]
57
+ ).returns(T::Boolean)
58
+ end
59
+ # Given an array of {Namespace} instances, returns true if they may
60
+ # be merged into this instance using {merge_into_self}. For instances to
61
+ # be mergeable, they must either all be abstract or all not be abstract,
62
+ # and they must define the same superclass (or none at all).
63
+ #
64
+ # @param others [Array<RbsGenerator::RbsObject>] An array of other {Namespace} instances.
65
+ # @return [Boolean] Whether this instance may be merged with them.
66
+ def mergeable?(others)
67
+ others = T.cast(others, T::Array[Namespace]) rescue (return false)
68
+ all = others + [self]
69
+
70
+ all_classes = T.cast(all.select { |x| ClassNamespace === x }, T::Array[ClassNamespace])
71
+
72
+ all_classes.map(&:superclass).compact.uniq.length <= 1
73
+ end
74
+
75
+ sig do
76
+ override.params(
77
+ others: T::Array[RbsGenerator::RbsObject]
78
+ ).void
79
+ end
80
+ # Given an array of {ClassNamespace} instances, merges them into this one.
81
+ # You MUST ensure that {mergeable?} is true for those instances.
82
+ #
83
+ # @param others [Array<RbsGenerator::RbsObject>] An array of other {ClassNamespace} instances.
84
+ # @return [void]
85
+ def merge_into_self(others)
86
+ super
87
+
88
+ others.each do |other|
89
+ next unless ClassNamespace === other
90
+ other = T.cast(other, ClassNamespace)
91
+
92
+ @superclass = other.superclass unless superclass
93
+ end
94
+ end
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"
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,95 @@
1
+ # typed: true
2
+ module Parlour
3
+ class RbsGenerator < Generator
4
+ # Represents a constant definition.
5
+ class Constant < RbsObject
6
+ sig do
7
+ params(
8
+ generator: Generator,
9
+ name: String,
10
+ type: Types::TypeLike,
11
+ block: T.nilable(T.proc.params(x: Constant).void)
12
+ ).void
13
+ end
14
+ # Creates a new constant definition.
15
+ #
16
+ # @param name [String] The name of the constant.
17
+ # @param value [String] The value of the constant, as a Ruby code string.
18
+ # eigenclass of the current namespace.
19
+ def initialize(generator, name, type:, &block)
20
+ super(generator, name)
21
+ @type = type
22
+ yield_self(&block) if block
23
+ end
24
+
25
+ # @return [Types::TypeLike] The type of the constant.
26
+ sig { returns(Types::TypeLike) }
27
+ attr_reader :type
28
+
29
+ sig { params(other: Object).returns(T::Boolean) }
30
+ # Returns true if this instance is equal to another extend.
31
+ #
32
+ # @param other [Object] The other instance. If this is not a {Extend} (or a
33
+ # subclass of it), this will always return false.
34
+ # @return [Boolean]
35
+ def ==(other)
36
+ Constant === other && name == other.name && type == other.type
37
+ end
38
+
39
+ sig do
40
+ override.params(
41
+ indent_level: Integer,
42
+ options: Options
43
+ ).returns(T::Array[String])
44
+ end
45
+ # Generates the RBS lines for this constant.
46
+ #
47
+ # @param indent_level [Integer] The indentation level to generate the lines at.
48
+ # @param options [Options] The formatting options to use.
49
+ # @return [Array<String>] The RBS lines, formatted as specified.
50
+ def generate_rbs(indent_level, options)
51
+ [options.indented(indent_level, "#{name}: #{String === @type ? @type : @type.generate_rbs}")]
52
+ end
53
+
54
+ sig do
55
+ override.params(
56
+ others: T::Array[RbsGenerator::RbsObject]
57
+ ).returns(T::Boolean)
58
+ end
59
+ # Given an array of {Constant} instances, returns true if they may be
60
+ # merged into this instance using {merge_into_self}. This is always false.
61
+ #
62
+ # @param others [Array<RbsGenerator::RbsObject>] An array of other
63
+ # {Constant} instances.
64
+ # @return [Boolean] Whether this instance may be merged with them.
65
+ def mergeable?(others)
66
+ others.all? { |other| self == other }
67
+ end
68
+
69
+ sig do
70
+ override.params(
71
+ others: T::Array[RbsGenerator::RbsObject]
72
+ ).void
73
+ end
74
+ # Given an array of {Constant} instances, merges them into this one.
75
+ # This particular implementation will simply do nothing, as instances
76
+ # are only mergeable if they are indentical.
77
+ # You MUST ensure that {mergeable?} is true for those instances.
78
+ #
79
+ # @param others [Array<RbsGenerator::RbsObject>] An array of other
80
+ # {Extend} instances.
81
+ # @return [void]
82
+ def merge_into_self(others)
83
+ # We don't need to change anything! We only merge identical constants
84
+ end
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})"
92
+ end
93
+ end
94
+ end
95
+ end