parlour 0.1.1 → 0.2.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.
@@ -1,6 +1,7 @@
1
1
  # typed: true
2
2
  module Parlour
3
3
  class RbiGenerator
4
+ # Represents a method parameter with a Sorbet type signature.
4
5
  class Parameter
5
6
  extend T::Sig
6
7
 
@@ -11,6 +12,27 @@ module Parlour
11
12
  default: T.nilable(String)
12
13
  ).void
13
14
  end
15
+ # Create a new method parameter.
16
+ #
17
+ # @example Create a simple Integer parameter named +num+.
18
+ # Parlour::RbiGenerator::Parameter.new('num', type: 'Integer')
19
+ # @example Create a nilable array parameter.
20
+ # Parlour::RbiGenerator::Parameter.new('array_of_strings_or_symbols', type: 'T.nilable(T::Array(String, Symbol))')
21
+ # @example Create a block parameter.
22
+ # Parlour::RbiGenerator::Parameter.new('&blk', type: 'T.proc.void')
23
+ # @example Create a parameter with a default value.
24
+ # Parlour::RbiGenerator::Parameter.new('name', type: 'String', default: 'Parlour')
25
+ #
26
+ # @param name [String] The name of this parameter. This may start with +*+, +**+,
27
+ # or +&+, or end with +:+, which will infer the {kind} of this
28
+ # parameter. (If it contains none of those, {kind} will be +:normal+.)
29
+ # @param type [String, nil] A Sorbet string of this parameter's type, such as
30
+ # +"String"+ or +"T.untyped"+.
31
+ # @param default [String, nil] A string of Ruby code for this parameter's default value.
32
+ # For example, the default value of an empty string would be represented
33
+ # as +"\"\""+ (or +'""'+). The default value of the decimal +3.14+
34
+ # would be +"3.14"+.
35
+ # @return [void]
14
36
  def initialize(name, type: nil, default: nil)
15
37
  @name = name
16
38
 
@@ -24,6 +46,11 @@ module Parlour
24
46
  end
25
47
 
26
48
  sig { params(other: Object).returns(T::Boolean) }
49
+ # Returns true if this instance is equal to another method.
50
+ #
51
+ # @param other [Object] The other instance. If this is not a {Parameter} (or a
52
+ # subclass of it), this will always return false.
53
+ # @return [Boolean]
27
54
  def ==(other)
28
55
  Parameter === other &&
29
56
  name == other.name &&
@@ -33,9 +60,16 @@ module Parlour
33
60
  end
34
61
 
35
62
  sig { returns(String) }
63
+ # The name of this parameter, including any prefixes or suffixes such as
64
+ # +*+.
65
+ # @return [String]
36
66
  attr_reader :name
37
67
 
38
68
  sig { returns(String) }
69
+ # The name of this parameter, stripped of any prefixes or suffixes. For
70
+ # example, +*rest+ would become +rest+, or +foo:+ would become +foo+.
71
+ #
72
+ # @return [String]
39
73
  def name_without_kind
40
74
  return T.must(name[0..-2]) if kind == :keyword
41
75
 
@@ -46,15 +80,28 @@ module Parlour
46
80
  end
47
81
 
48
82
  sig { returns(T.nilable(String)) }
83
+ # A Sorbet string of this parameter's type, such as +"String"+ or
84
+ # +"T.untyped"+.
85
+ # @return [String, nil]
49
86
  attr_reader :type
50
87
 
51
88
  sig { returns(T.nilable(String)) }
89
+ # A string of Ruby code for this parameter's default value. For example,
90
+ # the default value of an empty string would be represented as +"\"\""+
91
+ # (or +'""'+). The default value of the decimal +3.14+ would be +"3.14"+.
92
+ # @return [String, nil]
52
93
  attr_reader :default
53
94
 
54
95
  sig { returns(Symbol) }
96
+ # The kind of parameter that this is. This will be one of +:normal+,
97
+ # +:splat+, +:double_splat+, +:block+ or +:keyword+.
98
+ # @return [Symbol]
55
99
  attr_reader :kind
56
100
 
57
101
  sig { returns(String) }
102
+ # A string of how this parameter should be defined in a method definition.
103
+ #
104
+ # @return [String]
58
105
  def to_def_param
59
106
  if default.nil?
60
107
  "#{name}"
@@ -66,10 +113,14 @@ module Parlour
66
113
  end
67
114
 
68
115
  sig { returns(String) }
116
+ # A string of how this parameter should be defined in a Sorbet +sig+.
117
+ #
118
+ # @return [String]
69
119
  def to_sig_param
70
120
  "#{name_without_kind}: #{type || 'T.untyped'}"
71
- end
121
+ end#
72
122
 
123
+ # A mapping of {kind} values to the characteristic prefixes each kind has.
73
124
  PREFIXES = {
74
125
  normal: '',
75
126
  splat: '*',
@@ -1,10 +1,76 @@
1
1
  # typed: true
2
2
  module Parlour
3
3
  class RbiGenerator
4
- module RbiObject
4
+ # An abstract class which is subclassed by any classes which can generate
5
+ # entire lines of an RBI, such as {Namespace} and {Method}. (As an example,
6
+ # {Parameter} is _not_ a subclass because it does not generate lines, only
7
+ # segments of definition and signature lines.)
8
+ # @abstract
9
+ class RbiObject
5
10
  extend T::Helpers
6
11
  extend T::Sig
7
- interface!
12
+ abstract!
13
+
14
+ sig { params(generator: RbiGenerator, name: String).void }
15
+ # Creates a new RBI object.
16
+ # @note Don't call this directly.
17
+ #
18
+ # @param generator [RbiGenerator] The current RbiGenerator.
19
+ # @param name [String] The name of this module.
20
+ # @return [void]
21
+ def initialize(generator, name)
22
+ @generator = generator
23
+ @generated_by = generator.current_plugin
24
+ @name = name
25
+ @comments = []
26
+ end
27
+
28
+ sig { returns(RbiGenerator) }
29
+ # The generator which this object belongs to.
30
+ # @return [RbiGenerator]
31
+ attr_reader :generator
32
+
33
+ sig { returns(T.nilable(Plugin)) }
34
+ # The {Plugin} which was controlling the {generator} when this object was
35
+ # created.
36
+ # @return [Plugin, nil]
37
+ attr_reader :generated_by
38
+
39
+ sig { returns(String) }
40
+ # The name of this object.
41
+ # @return [String]
42
+ attr_reader :name
43
+
44
+ sig { returns(T::Array[String]) }
45
+ # An array of comments which will be placed above the object in the RBI
46
+ # file.
47
+ # @return [Array<String>]
48
+ attr_reader :comments
49
+
50
+ sig { params(comment: T.any(String, T::Array[String])).void }
51
+ # Adds one or more comments to this RBI object.
52
+ #
53
+ # @example Creating a module with a comment.
54
+ # namespace.create_module('M') do |m|
55
+ # m.add_comment('This is a module')
56
+ # end
57
+ #
58
+ # @example Creating a class with a multi-line comment.
59
+ # namespace.create_class('C') do |c|
60
+ # c.add_comment(['This is a multi-line comment!', 'It can be as long as you want!'])
61
+ # end
62
+ #
63
+ # @param comment [String, Array<String>] The new comment(s).
64
+ # @return [void]
65
+ def add_comment(comment)
66
+ if comment.is_a?(String)
67
+ comments << comment
68
+ elsif comment.is_a?(Array)
69
+ comments.concat(comment)
70
+ end
71
+ end
72
+
73
+ alias_method :add_comments, :add_comment
8
74
 
9
75
  sig do
10
76
  abstract.params(
@@ -12,6 +78,12 @@ module Parlour
12
78
  options: Options
13
79
  ).returns(T::Array[String])
14
80
  end
81
+ # Generates the RBI lines for this object.
82
+ #
83
+ # @abstract
84
+ # @param indent_level [Integer] The indentation level to generate the lines at.
85
+ # @param options [Options] The formatting options to use.
86
+ # @return [Array<String>] The RBI lines, formatted as specified.
15
87
  def generate_rbi(indent_level, options); end
16
88
 
17
89
  sig do
@@ -19,6 +91,13 @@ module Parlour
19
91
  others: T::Array[RbiGenerator::RbiObject]
20
92
  ).returns(T::Boolean)
21
93
  end
94
+ # Given an array of other objects, returns true if they may be merged
95
+ # into this instance using {merge_into_self}. Each subclass will have its
96
+ # own criteria on what allows objects to be mergeable.
97
+ #
98
+ # @abstract
99
+ # @param others [Array<RbiGenerator::RbiObject>] An array of other {RbiObject} instances.
100
+ # @return [Boolean] Whether this instance may be merged with them.
22
101
  def mergeable?(others); end
23
102
 
24
103
  sig do
@@ -26,7 +105,41 @@ module Parlour
26
105
  others: T::Array[RbiGenerator::RbiObject]
27
106
  ).void
28
107
  end
108
+ # Given an array of other objects, merges them into this one. Each
109
+ # subclass will do this differently.
110
+ # You MUST ensure that {mergeable?} is true for those instances.
111
+ #
112
+ # @abstract
113
+ # @param others [Array<RbiGenerator::RbiObject>] An array of other {RbiObject} instances.
114
+ # @return [void]
29
115
  def merge_into_self(others); end
116
+
117
+ sig { abstract.returns(String) }
118
+ # Returns a human-readable brief string description of this object. This
119
+ # is displayed during manual conflict resolution with the +parlour+ CLI.
120
+ #
121
+ # @abstract
122
+ # @return [String]
123
+ def describe; end
124
+
125
+ private
126
+
127
+ sig do
128
+ params(
129
+ indent_level: Integer,
130
+ options: Options
131
+ ).returns(T::Array[String])
132
+ end
133
+ # Generates the RBI lines for this object's comments.
134
+ #
135
+ # @param indent_level [Integer] The indentation level to generate the lines at.
136
+ # @param options [Options] The formatting options to use.
137
+ # @return [Array<String>] The RBI lines for each comment, formatted as specified.
138
+ def generate_comments(indent_level, options)
139
+ comments.any? \
140
+ ? comments.map { |c| options.indented(indent_level, "# #{c}") }
141
+ : []
142
+ end
30
143
  end
31
144
  end
32
- end
145
+ end
@@ -1,4 +1,5 @@
1
1
  # typed: strong
2
2
  module Parlour
3
- VERSION = '0.1.1'
3
+ # The library version.
4
+ VERSION = '0.2.0'
4
5
  end
@@ -23,6 +23,7 @@ Gem::Specification.new do |spec|
23
23
  spec.require_paths = ["lib"]
24
24
 
25
25
  spec.add_dependency "sorbet-runtime"
26
+ spec.add_dependency "rainbow", "~> 3.0.0"
26
27
 
27
28
  spec.add_development_dependency "bundler", "~> 2.0"
28
29
  spec.add_development_dependency "rake", "~> 10.0"
@@ -0,0 +1,13 @@
1
+ require 'parlour'
2
+
3
+ module FooBar
4
+ class Plugin < Parlour::Plugin
5
+ def generate(root)
6
+ root.create_module('Foo') do |foo|
7
+ foo.add_comment('This is an example plugin!')
8
+ foo.create_module('Bar')
9
+ foo.create_module('Bar', interface: true)
10
+ end
11
+ end
12
+ end
13
+ end
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: 0.1.1
4
+ version: 0.2.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: 2019-07-05 00:00:00.000000000 Z
11
+ date: 2019-07-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sorbet-runtime
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rainbow
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 3.0.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 3.0.0
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: bundler
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -97,20 +111,28 @@ dependencies:
97
111
  description:
98
112
  email:
99
113
  - hello@aaronc.cc
100
- executables: []
114
+ executables:
115
+ - parlour
101
116
  extensions: []
102
117
  extra_rdoc_files: []
103
118
  files:
119
+ - ".github/ISSUE_TEMPLATE/bug-report.md"
120
+ - ".github/ISSUE_TEMPLATE/feature-request.md"
104
121
  - ".gitignore"
105
122
  - ".rspec"
123
+ - ".travis.yml"
106
124
  - CHANGELOG.md
107
125
  - CODE_OF_CONDUCT.md
108
126
  - Gemfile
109
127
  - LICENSE.txt
110
128
  - README.md
129
+ - Rakefile
130
+ - exe/parlour
111
131
  - lib/parlour.rb
112
132
  - lib/parlour/conflict_resolver.rb
133
+ - lib/parlour/plugin.rb
113
134
  - lib/parlour/rbi_generator.rb
135
+ - lib/parlour/rbi_generator/attribute.rb
114
136
  - lib/parlour/rbi_generator/class_namespace.rb
115
137
  - lib/parlour/rbi_generator/method.rb
116
138
  - lib/parlour/rbi_generator/module_namespace.rb
@@ -120,6 +142,7 @@ files:
120
142
  - lib/parlour/rbi_generator/rbi_object.rb
121
143
  - lib/parlour/version.rb
122
144
  - parlour.gemspec
145
+ - plugin_examples/foobar_plugin.rb
123
146
  - sorbet/config
124
147
  - sorbet/rbi/gems/rake.rbi
125
148
  - sorbet/rbi/gems/rspec-core.rbi