ffast 0.1.9 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
data/lib/fast.rb CHANGED
@@ -67,24 +67,103 @@ module Fast
67
67
  %\d # bind extra arguments to the expression
68
68
  /x.freeze
69
69
 
70
+ # Set some convention methods from file.
71
+ class Node < Astrolabe::Node
72
+ # @return [String] with path of the file or simply buffer name.
73
+ def buffer_name
74
+ expression.source_buffer.name
75
+ end
76
+
77
+ # @return [Parser::Source::Range] from the expression
78
+ def expression
79
+ location.expression
80
+ end
81
+
82
+ # @return [String] with the content of the #expression
83
+ def source
84
+ expression.source
85
+ end
86
+
87
+ # @return [Boolean] true if a file exists with the #buffer_name
88
+ def from_file?
89
+ File.exist?(buffer_name)
90
+ end
91
+
92
+ # @return [Array<String>] with authors from the current expression range
93
+ def blame_authors
94
+ `git blame -L #{expression.first_line},#{expression.last_line} #{buffer_name}`.lines.map do |line|
95
+ line.split('(')[1].split(/\d+/).first.strip
96
+ end
97
+ end
98
+
99
+ # @return [String] with the first element from #blame_authors
100
+ def author
101
+ blame_authors.first
102
+ end
103
+
104
+ # Search recursively into a node and its children using a pattern.
105
+ # @param [String] pattern
106
+ # @param [Array] *args extra arguments to interpolate in the pattern.
107
+ # @return [Array<Fast::Node>>] with files and results
108
+ def search(pattern, *args)
109
+ Fast.search(pattern, self, *args)
110
+ end
111
+
112
+ # Captures elements from search recursively
113
+ # @param [String] pattern
114
+ # @param [Array] *args extra arguments to interpolate in the pattern.
115
+ # @return [Array<Fast::Node>>] with files and results
116
+ def capture(pattern, *args)
117
+ Fast.capture(pattern, self, *args)
118
+ end
119
+ end
120
+
121
+ # Custom builder allow us to set a buffer name for each Node
122
+ class Builder < Astrolabe::Builder
123
+ attr_writer :buffer_name
124
+ # Generates {Node} from the given information.
125
+ #
126
+ # @return [Node] the generated node
127
+ def n(type, children, source_map)
128
+ Node.new(type, children, location: source_map, buffer_name: @buffer_name)
129
+ end
130
+ end
131
+
70
132
  class << self
71
- # @return [Astrolabe::Node] from the parsed content
133
+ # @return [Fast::Node] from the parsed content
72
134
  # @example
73
135
  # Fast.ast("1") # => s(:int, 1)
74
136
  # Fast.ast("a.b") # => s(:send, s(:send, nil, :a), :b)
75
137
  def ast(content, buffer_name: '(string)')
76
138
  buffer = Parser::Source::Buffer.new(buffer_name)
77
139
  buffer.source = content
78
- Parser::CurrentRuby.new(Astrolabe::Builder.new).parse(buffer)
140
+ Parser::CurrentRuby.new(builder_for(buffer_name)).parse(buffer)
141
+ end
142
+
143
+ def builder_for(buffer_name)
144
+ builder = Builder.new
145
+ builder.buffer_name = buffer_name
146
+ builder
79
147
  end
80
148
 
81
- # @return [Astrolabe::Node] parsed from file content
149
+ # @return [Fast::Node] parsed from file content
82
150
  # caches the content based on the filename.
151
+ # Also, it can parse SQL files.
83
152
  # @example
84
153
  # Fast.ast_from_file("example.rb") # => s(...)
85
154
  def ast_from_file(file)
86
155
  @cache ||= {}
87
- @cache[file] ||= ast(IO.read(file), buffer_name: file)
156
+ @cache[file] ||=
157
+ begin
158
+ method =
159
+ if file.end_with?('.sql')
160
+ require_relative 'fast/sql' unless respond_to?(:parse_sql)
161
+ :parse_sql
162
+ else
163
+ :ast
164
+ end
165
+ Fast.public_send(method, IO.read(file), buffer_name: file)
166
+ end
88
167
  end
89
168
 
90
169
  # Verify if a given AST matches with a specific pattern
@@ -96,18 +175,23 @@ module Fast
96
175
  end
97
176
 
98
177
  # Search with pattern directly on file
99
- # @return [Array<Astrolabe::Node>] that matches the pattern
178
+ # @return [Array<Fast::Node>] that matches the pattern
100
179
  def search_file(pattern, file)
101
180
  node = ast_from_file(file)
102
181
  return [] unless node
103
182
 
104
- search pattern, node
183
+ case node
184
+ when Array
185
+ node.map { |n| search(pattern, n) }.flatten.compact
186
+ else
187
+ search pattern, node
188
+ end
105
189
  end
106
190
 
107
191
  # Search with pattern on a directory or multiple files
108
192
  # @param [String] pattern
109
193
  # @param [Array<String>] *locations where to search. Default is '.'
110
- # @return [Hash<String,Array<Astrolabe::Node>>] with files and results
194
+ # @return [Hash<String,Array<Fast::Node>>] with files and results
111
195
  def search_all(pattern, locations = ['.'], parallel: true, on_result: nil)
112
196
  group_results(build_grouped_search(:search_file, pattern, on_result),
113
197
  locations, parallel: parallel)
@@ -160,8 +244,12 @@ module Fast
160
244
  def capture_file(pattern, file)
161
245
  node = ast_from_file(file)
162
246
  return [] unless node
163
-
164
- capture pattern, node
247
+ case node
248
+ when Array
249
+ node.map { |n| capture(pattern, n) }.flatten.compact
250
+ else
251
+ capture pattern, node
252
+ end
165
253
  end
166
254
 
167
255
  # Search recursively into a node and its children.
@@ -173,9 +261,14 @@ module Fast
173
261
  yield node, match if block_given?
174
262
  match != true ? [node, match] : [node]
175
263
  else
176
- node.each_child_node
177
- .flat_map { |child| search(pattern, child, *args) }
178
- .compact.flatten
264
+ case node
265
+ when Array
266
+ node.flat_map { |child| search(pattern, child, *args) }
267
+ else
268
+ node.each_child_node
269
+ .flat_map { |child| search(pattern, child, *args) }
270
+ .compact.flatten
271
+ end
179
272
  end
180
273
  end
181
274
 
@@ -241,7 +334,7 @@ module Fast
241
334
  # Useful to index abstract patterns or similar code structure.
242
335
  # @see https://jonatas.github.io/fast/similarity_tutorial/
243
336
  # @return [String] with an pattern to search from it.
244
- # @param node [Astrolabe::Node]
337
+ # @param node [Fast::Node]
245
338
  # @example
246
339
  # Fast.expression_from(Fast.ast('1')) # => '(int _)'
247
340
  # Fast.expression_from(Fast.ast('a = 1')) # => '(lvasgn _ (int _))'
@@ -250,7 +343,7 @@ module Fast
250
343
  case node
251
344
  when Parser::AST::Node
252
345
  children_expression = node.children.map(&method(:expression_from)).join(' ')
253
- "(#{node.type}#{' ' + children_expression if node.children.any?})"
346
+ "(#{node.type}#{" #{children_expression}" if node.children.any?})"
254
347
  when nil, 'nil'
255
348
  'nil'
256
349
  when Symbol, String, Numeric
@@ -305,14 +398,14 @@ module Fast
305
398
  when '{' then Any.new(parse_until_peek('}'))
306
399
  when '[' then All.new(parse_until_peek(']'))
307
400
  when /^"/ then FindString.new(token[1..-2])
308
- when /^#\w/ then MethodCall.new(token[1..-1])
309
- when /^\.\w[\w\d_]+\?/ then InstanceMethodCall.new(token[1..-1])
401
+ when /^#\w/ then MethodCall.new(token[1..])
402
+ when /^\.\w[\w\d_]+\?/ then InstanceMethodCall.new(token[1..])
310
403
  when '$' then Capture.new(parse)
311
404
  when '!' then (@tokens.any? ? Not.new(parse) : Find.new(token))
312
405
  when '?' then Maybe.new(parse)
313
406
  when '^' then Parent.new(parse)
314
407
  when '\\' then FindWithCapture.new(parse)
315
- when /^%\d/ then FindFromArgument.new(token[1..-1])
408
+ when /^%\d/ then FindFromArgument.new(token[1..])
316
409
  else Find.new(token)
317
410
  end
318
411
  end
@@ -367,6 +460,10 @@ module Fast
367
460
  node.type == expression.to_sym
368
461
  when String
369
462
  node == expression.to_s
463
+ when TrueClass
464
+ expression == :true
465
+ when FalseClass
466
+ expression == :false
370
467
  else
371
468
  node == expression
372
469
  end
data/mkdocs.yml CHANGED
@@ -1,12 +1,18 @@
1
1
  site_name: Fast
2
2
  repo_url: https://github.com/jonatas/fast
3
3
  edit_uri: edit/master/docs/
4
- google_analytics: ['UA-125089529-1', 'auto']
4
+ google_analytics: ['G-YKZDZDNRG2', 'auto']
5
+
5
6
  theme:
6
7
  name: material
7
8
  palette:
8
9
  primary: indigo
9
10
  accent: pink
11
+ logo: assets/logo.png
12
+ favicon: assets/favicon.png
13
+ extra_css:
14
+ - stylesheets/custom.css
15
+
10
16
  markdown_extensions:
11
17
  - admonition
12
18
  - codehilite:
@@ -15,13 +21,16 @@ markdown_extensions:
15
21
  permalink: true
16
22
  nav:
17
23
  - Introduction: index.md
24
+ - Walkthrough: walkthrough.md
18
25
  - Syntax: syntax.md
19
26
  - Command Line: command_line.md
20
27
  - Experiments: experiments.md
21
28
  - Shortcuts: shortcuts.md
29
+ - Git Integration: git.md
22
30
  - Code Similarity: similarity_tutorial.md
23
31
  - Pry Integration: pry-integration.md
24
32
  - Editors' Integration: editors-integration.md
25
33
  - Research: research.md
26
34
  - Ideas: ideas.md
27
35
  - Videos: videos.md
36
+ - SQL Support: sql-support.md
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.9
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jônatas Davi Paganini
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-13 00:00:00.000000000 Z
11
+ date: 2023-11-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: astrolabe
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pg_query
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: bundler
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +94,20 @@ dependencies:
80
94
  - - ">="
81
95
  - !ruby/object:Gem::Version
82
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: git
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
83
111
  - !ruby/object:Gem::Dependency
84
112
  name: guard
85
113
  requirement: !ruby/object:Gem::Requirement
@@ -154,30 +182,30 @@ dependencies:
154
182
  name: rspec
155
183
  requirement: !ruby/object:Gem::Requirement
156
184
  requirements:
157
- - - "~>"
185
+ - - ">="
158
186
  - !ruby/object:Gem::Version
159
- version: '3.0'
187
+ version: '0'
160
188
  type: :development
161
189
  prerelease: false
162
190
  version_requirements: !ruby/object:Gem::Requirement
163
191
  requirements:
164
- - - "~>"
192
+ - - ">="
165
193
  - !ruby/object:Gem::Version
166
- version: '3.0'
194
+ version: '0'
167
195
  - !ruby/object:Gem::Dependency
168
196
  name: rspec-its
169
197
  requirement: !ruby/object:Gem::Requirement
170
198
  requirements:
171
- - - "~>"
199
+ - - ">="
172
200
  - !ruby/object:Gem::Version
173
- version: '1.2'
201
+ version: '0'
174
202
  type: :development
175
203
  prerelease: false
176
204
  version_requirements: !ruby/object:Gem::Requirement
177
205
  requirements:
178
- - - "~>"
206
+ - - ">="
179
207
  - !ruby/object:Gem::Version
180
- version: '1.2'
208
+ version: '0'
181
209
  - !ruby/object:Gem::Dependency
182
210
  name: rubocop
183
211
  requirement: !ruby/object:Gem::Requirement
@@ -247,6 +275,7 @@ files:
247
275
  - ".projections.json"
248
276
  - ".rspec"
249
277
  - ".rubocop.yml"
278
+ - ".sourcelevel.yml"
250
279
  - ".travis.yml"
251
280
  - CODE_OF_CONDUCT.md
252
281
  - Fastfile
@@ -263,14 +292,17 @@ files:
263
292
  - docs/command_line.md
264
293
  - docs/editors-integration.md
265
294
  - docs/experiments.md
295
+ - docs/git.md
266
296
  - docs/ideas.md
267
297
  - docs/index.md
268
298
  - docs/pry-integration.md
269
299
  - docs/research.md
270
300
  - docs/shortcuts.md
271
301
  - docs/similarity_tutorial.md
302
+ - docs/sql-support.md
272
303
  - docs/syntax.md
273
304
  - docs/videos.md
305
+ - docs/walkthrough.md
274
306
  - examples/build_stubbed_and_let_it_be_experiment.rb
275
307
  - examples/experimental_replacement.rb
276
308
  - examples/find_usage.rb
@@ -286,15 +318,33 @@ files:
286
318
  - lib/fast.rb
287
319
  - lib/fast/cli.rb
288
320
  - lib/fast/experiment.rb
321
+ - lib/fast/git.rb
289
322
  - lib/fast/rewriter.rb
290
323
  - lib/fast/shortcut.rb
324
+ - lib/fast/sql.rb
325
+ - lib/fast/sql/rewriter.rb
291
326
  - lib/fast/version.rb
292
327
  - mkdocs.yml
293
328
  homepage: https://jonatas.github.io/fast/
294
329
  licenses:
295
330
  - MIT
296
331
  metadata: {}
297
- post_install_message:
332
+ post_install_message: |2+
333
+
334
+ ==========================================================
335
+ Yay! Thanks for installing
336
+
337
+ ___ __ ___
338
+ |__ / /__` |
339
+ | /~~ .__/ |
340
+
341
+ To interactive learn about the gem in the terminal use:
342
+
343
+ fast .intro
344
+
345
+ More docs at: https://jonatas.github.io/fast/
346
+ ==========================================================
347
+
298
348
  rdoc_options: []
299
349
  require_paths:
300
350
  - lib
@@ -303,15 +353,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
303
353
  requirements:
304
354
  - - ">="
305
355
  - !ruby/object:Gem::Version
306
- version: '2.3'
356
+ version: '2.6'
307
357
  required_rubygems_version: !ruby/object:Gem::Requirement
308
358
  requirements:
309
359
  - - ">="
310
360
  - !ruby/object:Gem::Version
311
361
  version: '0'
312
362
  requirements: []
313
- rubygems_version: 3.0.3
314
- signing_key:
363
+ rubygems_version: 3.4.22
364
+ signing_key:
315
365
  specification_version: 4
316
366
  summary: 'FAST: Find by AST.'
317
367
  test_files: []
368
+ ...