ffast 0.1.0 → 0.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7b1063b0bb3b8dcc82515f0b10fc24601c6b322979d0a53eb6e65fa6f3ab439c
4
- data.tar.gz: b984df89b42bb0f21c2f91567d37fe10e336fb489fdea3ad8ff5ae658dc1de34
3
+ metadata.gz: 25f7e0fd657799e3fb4a1871fc8a88f8bab0737c7a24720d2bd58e9da7cd2d80
4
+ data.tar.gz: 1acb400b517ab4b5e68dd931639eb1916638951c745fff49823d6b6cb9aa7e09
5
5
  SHA512:
6
- metadata.gz: adf2973bf7e616dbd7fe1866abda708afd1e667ee2938d74f3204d26f228b8f235b017f6729cc083651627aee97ac924d6042ef73248e8d5bcd4491065f18ade
7
- data.tar.gz: b6c77021c7db79ed8e7382e168409cfbc2c66b94681b6ba8fbcd6ec0842aedf3fe431ce894034640a2dfe2b22a8cf22884498d2b40df674e6a697aa16dd1282d
6
+ metadata.gz: 8302eeefd5df60556bc07db2724d45f02325b02e7c8edb1f5cdf2ccb26a2e88fcdfe0bf01b4bbe3bb3959c5571ffb63ecf6c8d97794a36421188c24bdb439a01
7
+ data.tar.gz: 4cbb366fb6be3c0e8be305922b286154524337b504d42f43098641359ad2916f4e3a64f5c3982099f5a0660a01fac0b218f26019bbdf2f104ce8f33ce2f5a4ba
@@ -2,6 +2,7 @@
2
2
 
3
3
  require:
4
4
  - rubocop-rspec
5
+ - rubocop-performance
5
6
 
6
7
  AllCops:
7
8
  Exclude:
@@ -1,14 +1,18 @@
1
1
  sudo: false
2
2
  language: ruby
3
+ env:
4
+ global:
5
+ - CC_TEST_REPORTER_ID=cf3977cb8c335147723d765c91877e0506ba43e56a22a0dc5b83d7fb969cf5e4
3
6
  rvm:
4
7
  - 2.5.0
5
- before_install: gem install bundler -v 1.16.1
8
+ before_install:
9
+ gem install bundler -v 1.16.1
6
10
  before_script:
7
11
  - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
8
12
  - chmod +x ./cc-test-reporter
9
13
  - ./cc-test-reporter before-build
10
14
  after_script:
11
- - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
15
+ - ./cc-test-reporter after-build -t simplecov --exit-code $TRAVIS_TEST_RESULT
12
16
  script:
13
17
  - bundle exec rubocop
14
18
  - bundle exec rspec
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # Fast
2
2
 
3
3
  [![Build Status](https://travis-ci.org/jonatas/fast.svg?branch=master)](https://travis-ci.org/jonatas/fast)
4
+ [![Maintainability](https://api.codeclimate.com/v1/badges/b03d62ee266399e76e32/maintainability)](https://codeclimate.com/github/jonatas/fast/maintainability)
5
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/b03d62ee266399e76e32/test_coverage)](https://codeclimate.com/github/jonatas/fast/test_coverage)
4
6
 
5
7
  Fast, short for "Find AST", is a tool to search, prune, and edit Ruby ASTs.
6
8
 
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
29
29
  spec.add_dependency 'parser'
30
30
  spec.add_dependency 'pry'
31
31
 
32
- spec.add_development_dependency 'bundler', '~> 1.14'
32
+ spec.add_development_dependency 'bundler'
33
33
  spec.add_development_dependency 'guard'
34
34
  spec.add_development_dependency 'guard-livereload'
35
35
  spec.add_development_dependency 'guard-rspec'
@@ -37,5 +37,7 @@ Gem::Specification.new do |spec|
37
37
  spec.add_development_dependency 'rspec', '~> 3.0'
38
38
  spec.add_development_dependency 'rspec-its', '~> 1.2'
39
39
  spec.add_development_dependency 'rubocop'
40
+ spec.add_development_dependency 'rubocop-performance'
40
41
  spec.add_development_dependency 'rubocop-rspec'
42
+ spec.add_development_dependency 'simplecov'
41
43
  end
@@ -113,7 +113,7 @@ module Fast
113
113
  rewriter.buffer = buffer
114
114
  rewriter.search = pattern
115
115
  rewriter.replacement = replacement
116
- rewriter.affect_types(*types)
116
+ rewriter.replace_on(*types)
117
117
  rewriter.rewrite(buffer, ast)
118
118
  end
119
119
 
@@ -144,10 +144,10 @@ module Fast
144
144
  # otherwise it recursively collect possible children nodes
145
145
  # @yield node and capture if block given
146
146
  def search(node, pattern)
147
- if (match = Fast.match?(node, pattern))
147
+ if (match = match?(node, pattern))
148
148
  yield node, match if block_given?
149
149
  match != true ? [node, match] : [node]
150
- elsif Fast.match?(node, '...')
150
+ else
151
151
  node.each_child_node
152
152
  .flat_map { |e| search(e, pattern) }
153
153
  .compact.flatten
@@ -156,12 +156,12 @@ module Fast
156
156
 
157
157
  # Return only captures from a search
158
158
  # @return [Array<Object>] with all captured elements.
159
- # If the result is only a single capture, it will return the single element.
159
+ # @return [Object] with single element when single capture.
160
160
  def capture(node, pattern)
161
161
  res =
162
- if (match = Fast.match?(node, pattern))
162
+ if (match = match?(node, pattern))
163
163
  match == true ? node : match
164
- elsif node.child_nodes.any?
164
+ else
165
165
  node.each_child_node
166
166
  .flat_map { |child| capture(child, pattern) }
167
167
  .compact.flatten
@@ -169,33 +169,6 @@ module Fast
169
169
  res&.size == 1 ? res[0] : res
170
170
  end
171
171
 
172
- # Highligh some source code based on the node.
173
- # Useful for printing code with syntax highlight.
174
- def highlight(node, show_sexp: false)
175
- output =
176
- if node.respond_to?(:loc) && !show_sexp
177
- node.loc.expression.source
178
- else
179
- node
180
- end
181
- CodeRay.scan(output, :ruby).term
182
- end
183
-
184
- # Combines {.highlight} with files printing file name in the head with the
185
- # source line.
186
- # @param result [Astrolabe::Node]
187
- # @param show_sexp [Boolean] Show string expression instead of source
188
- # @param file [String] Show the file name and result line before content
189
- # @example
190
- # Fast.highlight(Fast.search(...))
191
- def report(result, show_sexp: nil, file: nil)
192
- if file
193
- line = result.loc.expression.line if result.is_a?(Parser::AST::Node)
194
- puts Fast.highlight("# #{file}:#{line}")
195
- end
196
- puts Fast.highlight(result, show_sexp: show_sexp)
197
- end
198
-
199
172
  def expression(string)
200
173
  ExpressionParser.new(string).parse
201
174
  end
@@ -253,14 +226,12 @@ module Fast
253
226
  def expression_from(node)
254
227
  case node
255
228
  when Parser::AST::Node
256
- children_expression = node.children.map(&Fast.method(:expression_from)).join(' ')
229
+ children_expression = node.children.map(&method(:expression_from)).join(' ')
257
230
  "(#{node.type}#{' ' + children_expression if node.children.any?})"
258
231
  when nil, 'nil'
259
232
  'nil'
260
233
  when Symbol, String, Numeric
261
234
  '_'
262
- when Array, Hash
263
- '...'
264
235
  end
265
236
  end
266
237
  end
@@ -268,7 +239,7 @@ module Fast
268
239
  # Rewriter encapsulates {Rewriter#match_index} to allow
269
240
  # {ExperimentFile.partial_replace} in a {Fast::ExperimentFile}.
270
241
  # @see https://www.rubydoc.info/github/whitequark/parser/Parser/TreeRewriter
271
- # @note the standalone class needs to combines {Rewriter#affect_types} to properly generate the `on_<node-type>` methods depending on the expression being used.
242
+ # @note the standalone class needs to combines {Rewriter#replace_on} to properly generate the `on_<node-type>` methods depending on the expression being used.
272
243
  # @example Simple Rewriter
273
244
  # ast = Fast.ast("a = 1")
274
245
  # buffer = Parser::Source::Buffer.new('replacement')
@@ -277,7 +248,7 @@ module Fast
277
248
  # rewriter.buffer = buffer
278
249
  # rewriter.search ='(lvasgn _ ...)'
279
250
  # rewriter.replacement = -> (node) { replace(node.location.name, 'variable_renamed') }
280
- # rewriter.affect_types(:lvasgn)
251
+ # rewriter.replace_on(:lvasgn)
281
252
  # rewriter.rewrite(buffer, ast) # => "variable_renamed = 1"
282
253
  class Rewriter < Parser::TreeRewriter
283
254
  # @return [Integer] with occurrence index
@@ -294,21 +265,28 @@ module Fast
294
265
 
295
266
  # Generate methods for all affected types.
296
267
  # @see Fast.replace
297
- def affect_types(*types) # rubocop:disable Metrics/MethodLength
268
+ def replace_on(*types)
298
269
  types.map do |type|
299
270
  self.class.send :define_method, "on_#{type}" do |node|
300
271
  if captures = match?(node) # rubocop:disable Lint/AssignmentInCondition
301
272
  @match_index += 1
302
- if replacement.parameters.length == 1
303
- instance_exec node, &replacement
304
- else
305
- instance_exec node, captures, &replacement
306
- end
273
+ execute_replacement(node, captures)
307
274
  end
308
275
  super(node)
309
276
  end
310
277
  end
311
278
  end
279
+
280
+ # Execute {#replacement} block
281
+ # @param [Astrolabe::Node] node that will be yield in the replacement block
282
+ # @param [Array<Object>, nil] captures are yield if {#replacement} take second argument.
283
+ def execute_replacement(node, captures)
284
+ if replacement.parameters.length == 1
285
+ instance_exec node, &replacement
286
+ else
287
+ instance_exec node, captures, &replacement
288
+ end
289
+ end
312
290
  end
313
291
 
314
292
  # ExpressionParser empowers the AST search in Ruby.
@@ -435,7 +413,7 @@ module Fast
435
413
  end
436
414
 
437
415
  def to_s
438
- "f[#{[*token].join(', ')}]"
416
+ "f[#{[*token].map(&:to_s).join(', ')}]"
439
417
  end
440
418
 
441
419
  def ==(other)
@@ -458,8 +436,8 @@ module Fast
458
436
 
459
437
  def typecast_value(token)
460
438
  case token
461
- when /\d+\.\d*/ then token.to_f
462
- when /\d+/ then token.to_i
439
+ when /^\d+\.\d*/ then token.to_f
440
+ when /^\d+/ then token.to_i
463
441
  else token.to_sym
464
442
  end
465
443
  end
@@ -594,7 +572,7 @@ module Fast
594
572
  end
595
573
 
596
574
  def to_s
597
- "c[#{token} $: #{@captures}]"
575
+ "c[#{token}]"
598
576
  end
599
577
  end
600
578
 
@@ -623,7 +601,7 @@ module Fast
623
601
  end
624
602
 
625
603
  def to_s
626
- "any[#{token}]"
604
+ "any[#{token.map(&:to_s).join(', ')}]"
627
605
  end
628
606
  end
629
607
 
@@ -689,11 +667,13 @@ module Fast
689
667
  def match?(ast = @ast, fast = @fast)
690
668
  head, *tail = fast
691
669
  return false unless head.match?(ast)
692
- if tail.empty?
693
- return ast == @ast ? find_captures : true # root node
694
- end
670
+ return find_captures if tail.empty?
671
+
672
+ match_tail?(ast.children, tail)
673
+ end
695
674
 
696
- child = ast.children
675
+ # @return [true] if all children matches with tail
676
+ def match_tail?(child, tail)
697
677
  tail.each_with_index.all? do |token, i|
698
678
  prepare_token(token)
699
679
  token.is_a?(Array) ? match?(child[i], token) : token.match?(child[i])
@@ -6,7 +6,37 @@ require 'coderay'
6
6
  require 'optparse'
7
7
  require 'ostruct'
8
8
 
9
+ # Command Line Interface powered by CodeRay
9
10
  module Fast
11
+ module_function
12
+
13
+ # Highligh some source code based on the node.
14
+ # Useful for printing code with syntax highlight.
15
+ def highlight(node, show_sexp: false)
16
+ output =
17
+ if node.respond_to?(:loc) && !show_sexp
18
+ node.loc.expression.source
19
+ else
20
+ node
21
+ end
22
+ CodeRay.scan(output, :ruby).term
23
+ end
24
+
25
+ # Combines {.highlight} with files printing file name in the head with the
26
+ # source line.
27
+ # @param result [Astrolabe::Node]
28
+ # @param show_sexp [Boolean] Show string expression instead of source
29
+ # @param file [String] Show the file name and result line before content
30
+ # @example
31
+ # Fast.highlight(Fast.search(...))
32
+ def report(result, show_sexp: nil, file: nil)
33
+ if file
34
+ line = result.loc.expression.line if result.is_a?(Parser::AST::Node)
35
+ puts Fast.highlight("# #{file}:#{line}")
36
+ end
37
+ puts Fast.highlight(result, show_sexp: show_sexp)
38
+ end
39
+
10
40
  # Command Line Interface for Fast
11
41
  class Cli
12
42
  attr_reader :pattern, :show_sexp, :pry, :from_code, :similar, :help
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fast
4
- VERSION = '0.1.0'
4
+ VERSION = '0.1.1'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ffast
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jônatas Davi Paganini
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-04-27 00:00:00.000000000 Z
11
+ date: 2019-05-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: astrolabe
@@ -70,16 +70,16 @@ dependencies:
70
70
  name: bundler
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - "~>"
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: '1.14'
75
+ version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - "~>"
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: '1.14'
82
+ version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: guard
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -178,6 +178,20 @@ dependencies:
178
178
  - - ">="
179
179
  - !ruby/object:Gem::Version
180
180
  version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: rubocop-performance
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
181
195
  - !ruby/object:Gem::Dependency
182
196
  name: rubocop-rspec
183
197
  requirement: !ruby/object:Gem::Requirement
@@ -192,6 +206,20 @@ dependencies:
192
206
  - - ">="
193
207
  - !ruby/object:Gem::Version
194
208
  version: '0'
209
+ - !ruby/object:Gem::Dependency
210
+ name: simplecov
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - ">="
214
+ - !ruby/object:Gem::Version
215
+ version: '0'
216
+ type: :development
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - ">="
221
+ - !ruby/object:Gem::Version
222
+ version: '0'
195
223
  description: Allow you to search for code using node pattern syntax.
196
224
  email:
197
225
  - jonatasdp@gmail.com
@@ -259,7 +287,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
259
287
  version: '0'
260
288
  requirements: []
261
289
  rubyforge_project:
262
- rubygems_version: 2.7.6
290
+ rubygems_version: 2.7.6.2
263
291
  signing_key:
264
292
  specification_version: 4
265
293
  summary: 'FAST: Find by AST.'