ffast 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -0
- data/.travis.yml +6 -2
- data/README.md +2 -0
- data/fast.gemspec +3 -1
- data/lib/fast.rb +33 -53
- data/lib/fast/cli.rb +30 -0
- data/lib/fast/version.rb +1 -1
- metadata +35 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 25f7e0fd657799e3fb4a1871fc8a88f8bab0737c7a24720d2bd58e9da7cd2d80
|
4
|
+
data.tar.gz: 1acb400b517ab4b5e68dd931639eb1916638951c745fff49823d6b6cb9aa7e09
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8302eeefd5df60556bc07db2724d45f02325b02e7c8edb1f5cdf2ccb26a2e88fcdfe0bf01b4bbe3bb3959c5571ffb63ecf6c8d97794a36421188c24bdb439a01
|
7
|
+
data.tar.gz: 4cbb366fb6be3c0e8be305922b286154524337b504d42f43098641359ad2916f4e3a64f5c3982099f5a0660a01fac0b218f26019bbdf2f104ce8f33ce2f5a4ba
|
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
@@ -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:
|
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
|
|
data/fast.gemspec
CHANGED
@@ -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'
|
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
|
data/lib/fast.rb
CHANGED
@@ -113,7 +113,7 @@ module Fast
|
|
113
113
|
rewriter.buffer = buffer
|
114
114
|
rewriter.search = pattern
|
115
115
|
rewriter.replacement = replacement
|
116
|
-
rewriter.
|
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 =
|
147
|
+
if (match = match?(node, pattern))
|
148
148
|
yield node, match if block_given?
|
149
149
|
match != true ? [node, match] : [node]
|
150
|
-
|
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
|
-
#
|
159
|
+
# @return [Object] with single element when single capture.
|
160
160
|
def capture(node, pattern)
|
161
161
|
res =
|
162
|
-
if (match =
|
162
|
+
if (match = match?(node, pattern))
|
163
163
|
match == true ? node : match
|
164
|
-
|
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(&
|
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#
|
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.
|
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
|
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
|
-
|
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
|
462
|
-
when
|
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}
|
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
|
-
|
694
|
-
|
670
|
+
return find_captures if tail.empty?
|
671
|
+
|
672
|
+
match_tail?(ast.children, tail)
|
673
|
+
end
|
695
674
|
|
696
|
-
|
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])
|
data/lib/fast/cli.rb
CHANGED
@@ -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
|
data/lib/fast/version.rb
CHANGED
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.
|
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-
|
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: '
|
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: '
|
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.'
|