ffast 0.0.6 → 0.0.7
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/README.md +3 -2
- data/docs/syntax.md +7 -0
- data/fast.gemspec +1 -0
- data/lib/fast.rb +27 -24
- data/lib/fast/version.rb +1 -1
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 36aaca199777feb62d91a6e052c038f4a971ab20fd37f1adcb7b0c8d3a90553b
|
4
|
+
data.tar.gz: 0ab405982443936ecaad957b43100496dce63d213e2a61c840b3002028c245e8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 32a5615982972c2e13582a8279cf94043a3a571044a6b1a04fee253f04c7ff93733eab4fca22f2878dc3e16d519cb3d78f06adafbe4b6bb998a72bea97929bc6
|
7
|
+
data.tar.gz: 277f3082ab12c310be88c1bda1d8fa57be86bae02ddc39c8c5adb6e49704aec036c801abe6d6f18527f23996d560bd95d199cb6c0209c72474acc1c031600bc0
|
data/README.md
CHANGED
@@ -18,8 +18,6 @@ The current version of Fast covers the following token elements:
|
|
18
18
|
- `{}` - looks for **any** element to match, like a **Set** inclusion or `any?` in Ruby
|
19
19
|
- `[]` - looks for **all** elements to match, like `all?` in Ruby.
|
20
20
|
- `$` - will **capture** the contents of the current expression like a `Regex` group
|
21
|
-
- `#<method-name>` - will call `<method-name>` with `node` as param allowing you
|
22
|
-
to build custom rules.
|
23
21
|
- `_` - represents any non-nil value, or **something** being present
|
24
22
|
- `nil` - matches exactly **nil**
|
25
23
|
- `...` - matches a **node** with children
|
@@ -28,6 +26,9 @@ The current version of Fast covers the following token elements:
|
|
28
26
|
- `\1` - represents a substitution for any of the **previously captured** elements
|
29
27
|
- `%1` - to bind the first extra argument in an expression
|
30
28
|
- `""` - will match a literal string with double quotes
|
29
|
+
- `#<method-name>` - will call `<method-name>` with `node` as param allowing you
|
30
|
+
to build custom rules.
|
31
|
+
- `.<method-name>` - will call `<method-name>` from the `node`
|
31
32
|
|
32
33
|
The syntax is inspired by the [RuboCop Node Pattern](https://github.com/bbatsov/rubocop/blob/master/lib/rubocop/node_pattern.rb).
|
33
34
|
|
data/docs/syntax.md
CHANGED
@@ -403,3 +403,10 @@ more details of the node
|
|
403
403
|
```ruby
|
404
404
|
puts Fast.search_file('[ (def a) #debug ]', 'example.rb')
|
405
405
|
```
|
406
|
+
## Calling Instance Methods
|
407
|
+
|
408
|
+
You can also call instance methods using `.<method-name>`.
|
409
|
+
|
410
|
+
Example `nil` is the same of calling `nil?` and you can also use `(int .odd?)`
|
411
|
+
to pick only odd integers. The `int` fragment can also be `int_type?`.
|
412
|
+
|
data/fast.gemspec
CHANGED
data/lib/fast.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'fileutils'
|
4
|
+
require 'astrolabe/builder'
|
4
5
|
|
5
6
|
# suppress output to avoid parser gem warnings'
|
6
7
|
def suppress_output
|
@@ -56,9 +57,11 @@ module Fast
|
|
56
57
|
|
|
57
58
|
\#\w[\d\w_]+[\\!\?]? # custom method call
|
58
59
|
|
|
60
|
+
\.\w[\d\w_]+\? # instance method call
|
61
|
+
|
|
59
62
|
\\\d # find using captured expression
|
60
63
|
|
|
61
|
-
%\d #
|
64
|
+
%\d # bind extra arguments to the expression
|
62
65
|
/x.freeze
|
63
66
|
|
64
67
|
class << self
|
@@ -99,8 +102,7 @@ module Fast
|
|
99
102
|
yield node, match if block_given?
|
100
103
|
match != true ? [node, match] : [node]
|
101
104
|
elsif Fast.match?(node, '...')
|
102
|
-
node.
|
103
|
-
.grep(Parser::AST::Node)
|
105
|
+
node.each_child_node
|
104
106
|
.flat_map { |e| search(e, pattern) }
|
105
107
|
.compact.flatten
|
106
108
|
end
|
@@ -110,21 +112,23 @@ module Fast
|
|
110
112
|
res =
|
111
113
|
if (match = Fast.match?(node, pattern))
|
112
114
|
match == true ? node : match
|
113
|
-
elsif
|
114
|
-
node.
|
115
|
-
.
|
116
|
-
.
|
115
|
+
elsif node.child_nodes.any?
|
116
|
+
node.each_child_node
|
117
|
+
.flat_map { |child| capture(child, pattern) }
|
118
|
+
.compact.flatten
|
117
119
|
end
|
118
120
|
res&.size == 1 ? res[0] : res
|
119
121
|
end
|
120
122
|
|
121
|
-
def ast(content)
|
122
|
-
Parser::
|
123
|
+
def ast(content, buffer_name: '(string)')
|
124
|
+
buffer = Parser::Source::Buffer.new(buffer_name)
|
125
|
+
buffer.source = content
|
126
|
+
Parser::CurrentRuby.new(Astrolabe::Builder.new).parse(buffer)
|
123
127
|
end
|
124
128
|
|
125
129
|
def ast_from_file(file)
|
126
130
|
@cache ||= {}
|
127
|
-
@cache[file] ||= ast(IO.read(file))
|
131
|
+
@cache[file] ||= ast(IO.read(file), buffer_name: file)
|
128
132
|
end
|
129
133
|
|
130
134
|
def highlight(node, show_sexp: false)
|
@@ -145,12 +149,6 @@ module Fast
|
|
145
149
|
puts Fast.highlight(result, show_sexp: show_sexp)
|
146
150
|
end
|
147
151
|
|
148
|
-
def buffer_for(file)
|
149
|
-
buffer = Parser::Source::Buffer.new(file.to_s)
|
150
|
-
buffer.source = IO.read(file)
|
151
|
-
buffer
|
152
|
-
end
|
153
|
-
|
154
152
|
def expression(string)
|
155
153
|
ExpressionParser.new(string).parse
|
156
154
|
end
|
@@ -261,6 +259,7 @@ module Fast
|
|
261
259
|
when '[' then All.new(parse_until_peek(']'))
|
262
260
|
when /^"/ then FindString.new(token[1..-2])
|
263
261
|
when /^#\w/ then MethodCall.new(token[1..-1])
|
262
|
+
when /^\.\w[\w\d_]+\?/ then InstanceMethodCall.new(token[1..-1])
|
264
263
|
when '$' then Capture.new(parse)
|
265
264
|
when '!' then (@tokens.any? ? Not.new(parse) : Find.new(token))
|
266
265
|
when '?' then Maybe.new(parse)
|
@@ -280,13 +279,6 @@ module Fast
|
|
280
279
|
next_token
|
281
280
|
list
|
282
281
|
end
|
283
|
-
|
284
|
-
def append_token_until_peek(token)
|
285
|
-
list = []
|
286
|
-
list << next_token until @tokens.empty? || @tokens.first == token
|
287
|
-
next_token
|
288
|
-
list.join
|
289
|
-
end
|
290
282
|
end
|
291
283
|
|
292
284
|
# Find is the top level class that respond to #match?(node) interface.
|
@@ -389,6 +381,17 @@ module Fast
|
|
389
381
|
end
|
390
382
|
end
|
391
383
|
|
384
|
+
# Search using custom instance methods
|
385
|
+
class InstanceMethodCall < Find
|
386
|
+
def initialize(method_name)
|
387
|
+
@method_name = method_name
|
388
|
+
end
|
389
|
+
|
390
|
+
def match?(node)
|
391
|
+
node.send(@method_name)
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
392
395
|
# Allow use previous captures while searching in the AST.
|
393
396
|
# Use `\\1` to point the match to the first captured element
|
394
397
|
class FindWithCapture < Find
|
@@ -464,7 +467,7 @@ module Fast
|
|
464
467
|
class Parent < Find
|
465
468
|
alias match_node match?
|
466
469
|
def match?(node)
|
467
|
-
node.
|
470
|
+
node.each_child_node.any?(&method(:match_node))
|
468
471
|
end
|
469
472
|
|
470
473
|
def to_s
|
data/lib/fast/version.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ffast
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
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-03-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: astrolabe
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: coderay
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|