Class: RubyLint::DefinitionGenerator
- Inherits:
-
Object
- Object
- RubyLint::DefinitionGenerator
- Defined in:
- lib/ruby-lint/definition_generator.rb
Overview
The DefinitionGenerator class is used for generating definitions based on the data that is available in the current Ruby runtime. Using this generator the otherwise painful and time consuming task of adding definitions for large projects (e.g. Ruby itself or Rails) becomes very easy up to the point where it will only take a minute or two.
Note that this generator works best on Ruby implementations that provide
accurate parameter information using UnboundMethod#parameters
. Currently
the only implementation where this is the case is Rubinius HEAD. Both MRI
and Jruby provide inaccurate information.
Instance Attribute Summary collapse
-
#directory ⇒ String
readonly
The directory to store the generated definitions in.
-
#inspector ⇒ RubyLint::Inspector
readonly
-
#options ⇒ Hash
readonly
-
#template ⇒ String
readonly
The ERB template to use.
Instance Method Summary collapse
-
#argument_mapping ⇒ Hash
private
-
#default_options ⇒ Hash
private
-
#generate ⇒ Object
Generates the definitions for every constant.
-
#group_constants(constants) ⇒ Hash
private
Groups constants together based on the top level namespace segment.
-
#initialize(constant, directory, options = {}) ⇒ DefinitionGenerator
constructor
A new instance of DefinitionGenerator.
-
#inspect_methods(inspector) ⇒ Hash
private
-
#method_information(inspected) ⇒ Hash
private
Returns a Hash containing all the instance and class methods and their arguments.
-
#render_erb(template, variables = {}) ⇒ Object
private
-
#render_template(path, template, constants) ⇒ Object
private
Constructor Details
#initialize(constant, directory, options = {}) ⇒ DefinitionGenerator
Returns a new instance of DefinitionGenerator
40 41 42 43 44 45 46 47 |
# File 'lib/ruby-lint/definition_generator.rb', line 40 def initialize(constant, directory, = {}) @options = .merge() @inspector = Inspector.new(constant) @directory = directory @template = File.read( File.('../template/definition.erb', __FILE__) ) end |
Instance Attribute Details
#directory ⇒ String (readonly)
Returns The directory to store the generated definitions in.
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/ruby-lint/definition_generator.rb', line 32 class DefinitionGenerator attr_reader :directory, :options, :template, :inspector ## # @param [Class] constant # @param [String] directory # @param [Hash] options # def initialize(constant, directory, = {}) @options = .merge() @inspector = Inspector.new(constant) @directory = directory @template = File.read( File.('../template/definition.erb', __FILE__) ) end ## # Generates the definitions for every constant. # def generate constants = inspector.inspect_constants( inspector.constant, [:ignore].dup ) constants = constants.sort group_constants(constants).each do |root, names| filepath = File.join(directory, "#{root.snake_case}.rb") constants = [] if File.file?(filepath) and ![:overwrite] next end names.each do |name| current_inspector = Inspector.new(name) inspected_methods = inspect_methods(current_inspector) superclass = nil if current_inspector.inspect_superclass superclass = current_inspector.inspect_superclass.to_s end constant = GeneratedConstant.new( :name => current_inspector.constant_name, :constant => current_inspector.constant, :methods => method_information(inspected_methods), :superclass => superclass, # Kernel is ignored since its included already in core/object.rb :modules => current_inspector.inspect_modules - [Kernel] ) constants << constant end render_template(filepath, template, constants) end end private ## # @param [String] path # @param [String] template # @param [Array] constants # def render_template(path, template, constants) erb = render_erb(template, :constants => constants) File.open(path, 'w') do |handle| handle.write(erb) end end ## # Groups constants together based on the top level namespace segment. # # @param [Array] constants # @return [Hash] # def group_constants(constants) grouped = Hash.new { |hash, key| hash[key] = [] } constants.each do |name| root = name.split('::')[0] grouped[root] << name end return grouped end ## # @return [Hash] # def return {:ignore => [], :overwrite => false} end ## # @param [RubyLint::Inspector] inspector # @return [Hash] # def inspect_methods(inspector) return { :method => inspector.inspect_methods, :instance_method => inspector.inspect_instance_methods } end ## # Returns a Hash containing all the instance and class methods and their # arguments. # # @param [Hash] inspected # @return [Hash] # def method_information(inspected) arg_mapping = argument_mapping info = {:method => {}, :instance_method => {}} inspected.each do |type, methods| methods.each do |method| args = [] method.parameters.each_with_index do |arg, index| name = arg[1] || "arg#{index + 1}" args << {:type => arg_mapping[arg[0]], :name => name} end info[type][method.name] = args end end return info end ## # @return [Hash] # def argument_mapping return { :req => :argument, :opt => :optional_argument, :rest => :rest_argument, :block => :block_argument } end ## # @param [String] template # @param [Hash] variables # def render_erb(template, variables = {}) scope = Template::Scope.new(variables) erb = ERB.new(template, nil, '-').result(scope.get_binding) # Trim excessive newlines. erb.gsub!(/\n{3,}/, "\n\n") # Get rid of the occasional empty newline before `end` tokens. erb.gsub!(/\n{2,}end/, "\nend") return erb end end |
#inspector ⇒ RubyLint::Inspector (readonly)
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/ruby-lint/definition_generator.rb', line 32 class DefinitionGenerator attr_reader :directory, :options, :template, :inspector ## # @param [Class] constant # @param [String] directory # @param [Hash] options # def initialize(constant, directory, = {}) @options = .merge() @inspector = Inspector.new(constant) @directory = directory @template = File.read( File.('../template/definition.erb', __FILE__) ) end ## # Generates the definitions for every constant. # def generate constants = inspector.inspect_constants( inspector.constant, [:ignore].dup ) constants = constants.sort group_constants(constants).each do |root, names| filepath = File.join(directory, "#{root.snake_case}.rb") constants = [] if File.file?(filepath) and ![:overwrite] next end names.each do |name| current_inspector = Inspector.new(name) inspected_methods = inspect_methods(current_inspector) superclass = nil if current_inspector.inspect_superclass superclass = current_inspector.inspect_superclass.to_s end constant = GeneratedConstant.new( :name => current_inspector.constant_name, :constant => current_inspector.constant, :methods => method_information(inspected_methods), :superclass => superclass, # Kernel is ignored since its included already in core/object.rb :modules => current_inspector.inspect_modules - [Kernel] ) constants << constant end render_template(filepath, template, constants) end end private ## # @param [String] path # @param [String] template # @param [Array] constants # def render_template(path, template, constants) erb = render_erb(template, :constants => constants) File.open(path, 'w') do |handle| handle.write(erb) end end ## # Groups constants together based on the top level namespace segment. # # @param [Array] constants # @return [Hash] # def group_constants(constants) grouped = Hash.new { |hash, key| hash[key] = [] } constants.each do |name| root = name.split('::')[0] grouped[root] << name end return grouped end ## # @return [Hash] # def return {:ignore => [], :overwrite => false} end ## # @param [RubyLint::Inspector] inspector # @return [Hash] # def inspect_methods(inspector) return { :method => inspector.inspect_methods, :instance_method => inspector.inspect_instance_methods } end ## # Returns a Hash containing all the instance and class methods and their # arguments. # # @param [Hash] inspected # @return [Hash] # def method_information(inspected) arg_mapping = argument_mapping info = {:method => {}, :instance_method => {}} inspected.each do |type, methods| methods.each do |method| args = [] method.parameters.each_with_index do |arg, index| name = arg[1] || "arg#{index + 1}" args << {:type => arg_mapping[arg[0]], :name => name} end info[type][method.name] = args end end return info end ## # @return [Hash] # def argument_mapping return { :req => :argument, :opt => :optional_argument, :rest => :rest_argument, :block => :block_argument } end ## # @param [String] template # @param [Hash] variables # def render_erb(template, variables = {}) scope = Template::Scope.new(variables) erb = ERB.new(template, nil, '-').result(scope.get_binding) # Trim excessive newlines. erb.gsub!(/\n{3,}/, "\n\n") # Get rid of the occasional empty newline before `end` tokens. erb.gsub!(/\n{2,}end/, "\nend") return erb end end |
#options ⇒ Hash (readonly)
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/ruby-lint/definition_generator.rb', line 32 class DefinitionGenerator attr_reader :directory, :options, :template, :inspector ## # @param [Class] constant # @param [String] directory # @param [Hash] options # def initialize(constant, directory, = {}) @options = .merge() @inspector = Inspector.new(constant) @directory = directory @template = File.read( File.('../template/definition.erb', __FILE__) ) end ## # Generates the definitions for every constant. # def generate constants = inspector.inspect_constants( inspector.constant, [:ignore].dup ) constants = constants.sort group_constants(constants).each do |root, names| filepath = File.join(directory, "#{root.snake_case}.rb") constants = [] if File.file?(filepath) and ![:overwrite] next end names.each do |name| current_inspector = Inspector.new(name) inspected_methods = inspect_methods(current_inspector) superclass = nil if current_inspector.inspect_superclass superclass = current_inspector.inspect_superclass.to_s end constant = GeneratedConstant.new( :name => current_inspector.constant_name, :constant => current_inspector.constant, :methods => method_information(inspected_methods), :superclass => superclass, # Kernel is ignored since its included already in core/object.rb :modules => current_inspector.inspect_modules - [Kernel] ) constants << constant end render_template(filepath, template, constants) end end private ## # @param [String] path # @param [String] template # @param [Array] constants # def render_template(path, template, constants) erb = render_erb(template, :constants => constants) File.open(path, 'w') do |handle| handle.write(erb) end end ## # Groups constants together based on the top level namespace segment. # # @param [Array] constants # @return [Hash] # def group_constants(constants) grouped = Hash.new { |hash, key| hash[key] = [] } constants.each do |name| root = name.split('::')[0] grouped[root] << name end return grouped end ## # @return [Hash] # def return {:ignore => [], :overwrite => false} end ## # @param [RubyLint::Inspector] inspector # @return [Hash] # def inspect_methods(inspector) return { :method => inspector.inspect_methods, :instance_method => inspector.inspect_instance_methods } end ## # Returns a Hash containing all the instance and class methods and their # arguments. # # @param [Hash] inspected # @return [Hash] # def method_information(inspected) arg_mapping = argument_mapping info = {:method => {}, :instance_method => {}} inspected.each do |type, methods| methods.each do |method| args = [] method.parameters.each_with_index do |arg, index| name = arg[1] || "arg#{index + 1}" args << {:type => arg_mapping[arg[0]], :name => name} end info[type][method.name] = args end end return info end ## # @return [Hash] # def argument_mapping return { :req => :argument, :opt => :optional_argument, :rest => :rest_argument, :block => :block_argument } end ## # @param [String] template # @param [Hash] variables # def render_erb(template, variables = {}) scope = Template::Scope.new(variables) erb = ERB.new(template, nil, '-').result(scope.get_binding) # Trim excessive newlines. erb.gsub!(/\n{3,}/, "\n\n") # Get rid of the occasional empty newline before `end` tokens. erb.gsub!(/\n{2,}end/, "\nend") return erb end end |
#template ⇒ String (readonly)
Returns The ERB template to use.
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/ruby-lint/definition_generator.rb', line 32 class DefinitionGenerator attr_reader :directory, :options, :template, :inspector ## # @param [Class] constant # @param [String] directory # @param [Hash] options # def initialize(constant, directory, = {}) @options = .merge() @inspector = Inspector.new(constant) @directory = directory @template = File.read( File.('../template/definition.erb', __FILE__) ) end ## # Generates the definitions for every constant. # def generate constants = inspector.inspect_constants( inspector.constant, [:ignore].dup ) constants = constants.sort group_constants(constants).each do |root, names| filepath = File.join(directory, "#{root.snake_case}.rb") constants = [] if File.file?(filepath) and ![:overwrite] next end names.each do |name| current_inspector = Inspector.new(name) inspected_methods = inspect_methods(current_inspector) superclass = nil if current_inspector.inspect_superclass superclass = current_inspector.inspect_superclass.to_s end constant = GeneratedConstant.new( :name => current_inspector.constant_name, :constant => current_inspector.constant, :methods => method_information(inspected_methods), :superclass => superclass, # Kernel is ignored since its included already in core/object.rb :modules => current_inspector.inspect_modules - [Kernel] ) constants << constant end render_template(filepath, template, constants) end end private ## # @param [String] path # @param [String] template # @param [Array] constants # def render_template(path, template, constants) erb = render_erb(template, :constants => constants) File.open(path, 'w') do |handle| handle.write(erb) end end ## # Groups constants together based on the top level namespace segment. # # @param [Array] constants # @return [Hash] # def group_constants(constants) grouped = Hash.new { |hash, key| hash[key] = [] } constants.each do |name| root = name.split('::')[0] grouped[root] << name end return grouped end ## # @return [Hash] # def return {:ignore => [], :overwrite => false} end ## # @param [RubyLint::Inspector] inspector # @return [Hash] # def inspect_methods(inspector) return { :method => inspector.inspect_methods, :instance_method => inspector.inspect_instance_methods } end ## # Returns a Hash containing all the instance and class methods and their # arguments. # # @param [Hash] inspected # @return [Hash] # def method_information(inspected) arg_mapping = argument_mapping info = {:method => {}, :instance_method => {}} inspected.each do |type, methods| methods.each do |method| args = [] method.parameters.each_with_index do |arg, index| name = arg[1] || "arg#{index + 1}" args << {:type => arg_mapping[arg[0]], :name => name} end info[type][method.name] = args end end return info end ## # @return [Hash] # def argument_mapping return { :req => :argument, :opt => :optional_argument, :rest => :rest_argument, :block => :block_argument } end ## # @param [String] template # @param [Hash] variables # def render_erb(template, variables = {}) scope = Template::Scope.new(variables) erb = ERB.new(template, nil, '-').result(scope.get_binding) # Trim excessive newlines. erb.gsub!(/\n{3,}/, "\n\n") # Get rid of the occasional empty newline before `end` tokens. erb.gsub!(/\n{2,}end/, "\nend") return erb end end |
Instance Method Details
#argument_mapping ⇒ Hash (private)
174 175 176 177 178 179 180 181 |
# File 'lib/ruby-lint/definition_generator.rb', line 174 def argument_mapping return { :req => :argument, :opt => :optional_argument, :rest => :rest_argument, :block => :block_argument } end |
#default_options ⇒ Hash (private)
129 130 131 |
# File 'lib/ruby-lint/definition_generator.rb', line 129 def return {:ignore => [], :overwrite => false} end |
#generate ⇒ Object
Generates the definitions for every constant.
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/ruby-lint/definition_generator.rb', line 52 def generate constants = inspector.inspect_constants( inspector.constant, [:ignore].dup ) constants = constants.sort group_constants(constants).each do |root, names| filepath = File.join(directory, "#{root.snake_case}.rb") constants = [] if File.file?(filepath) and ![:overwrite] next end names.each do |name| current_inspector = Inspector.new(name) inspected_methods = inspect_methods(current_inspector) superclass = nil if current_inspector.inspect_superclass superclass = current_inspector.inspect_superclass.to_s end constant = GeneratedConstant.new( :name => current_inspector.constant_name, :constant => current_inspector.constant, :methods => method_information(inspected_methods), :superclass => superclass, # Kernel is ignored since its included already in core/object.rb :modules => current_inspector.inspect_modules - [Kernel] ) constants << constant end render_template(filepath, template, constants) end end |
#group_constants(constants) ⇒ Hash (private)
Groups constants together based on the top level namespace segment.
115 116 117 118 119 120 121 122 123 124 |
# File 'lib/ruby-lint/definition_generator.rb', line 115 def group_constants(constants) grouped = Hash.new { |hash, key| hash[key] = [] } constants.each do |name| root = name.split('::')[0] grouped[root] << name end return grouped end |
#inspect_methods(inspector) ⇒ Hash (private)
137 138 139 140 141 142 |
# File 'lib/ruby-lint/definition_generator.rb', line 137 def inspect_methods(inspector) return { :method => inspector.inspect_methods, :instance_method => inspector.inspect_instance_methods } end |
#method_information(inspected) ⇒ Hash (private)
Returns a Hash containing all the instance and class methods and their arguments.
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/ruby-lint/definition_generator.rb', line 151 def method_information(inspected) arg_mapping = argument_mapping info = {:method => {}, :instance_method => {}} inspected.each do |type, methods| methods.each do |method| args = [] method.parameters.each_with_index do |arg, index| name = arg[1] || "arg#{index + 1}" args << {:type => arg_mapping[arg[0]], :name => name} end info[type][method.name] = args end end return info end |
#render_erb(template, variables = {}) ⇒ Object (private)
187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/ruby-lint/definition_generator.rb', line 187 def render_erb(template, variables = {}) scope = Template::Scope.new(variables) erb = ERB.new(template, nil, '-').result(scope.get_binding) # Trim excessive newlines. erb.gsub!(/\n{3,}/, "\n\n") # Get rid of the occasional empty newline before `end` tokens. erb.gsub!(/\n{2,}end/, "\nend") return erb end |
#render_template(path, template, constants) ⇒ Object (private)
101 102 103 104 105 106 107 |
# File 'lib/ruby-lint/definition_generator.rb', line 101 def render_template(path, template, constants) erb = render_erb(template, :constants => constants) File.open(path, 'w') do |handle| handle.write(erb) end end |