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 +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
|
[](https://travis-ci.org/jonatas/fast)
|
4
|
+
[](https://codeclimate.com/github/jonatas/fast/maintainability)
|
5
|
+
[](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.'
|