ffast 0.2.0 → 0.2.3

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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/release.yml +27 -0
  3. data/.github/workflows/ruby.yml +34 -0
  4. data/.gitignore +2 -0
  5. data/Fastfile +146 -3
  6. data/README.md +244 -132
  7. data/bin/console +6 -1
  8. data/bin/fast-experiment +3 -0
  9. data/bin/fast-mcp +7 -0
  10. data/fast.gemspec +24 -7
  11. data/lib/fast/cli.rb +129 -38
  12. data/lib/fast/experiment.rb +19 -2
  13. data/lib/fast/git.rb +1 -1
  14. data/lib/fast/mcp_server.rb +317 -0
  15. data/lib/fast/node.rb +258 -0
  16. data/lib/fast/prism_adapter.rb +310 -0
  17. data/lib/fast/rewriter.rb +64 -10
  18. data/lib/fast/scan.rb +203 -0
  19. data/lib/fast/shortcut.rb +23 -6
  20. data/lib/fast/source.rb +116 -0
  21. data/lib/fast/source_rewriter.rb +153 -0
  22. data/lib/fast/sql/rewriter.rb +98 -0
  23. data/lib/fast/sql.rb +165 -0
  24. data/lib/fast/summary.rb +435 -0
  25. data/lib/fast/version.rb +1 -1
  26. data/lib/fast.rb +165 -79
  27. data/mkdocs.yml +27 -3
  28. data/requirements-docs.txt +3 -0
  29. metadata +48 -62
  30. data/docs/command_line.md +0 -238
  31. data/docs/editors-integration.md +0 -46
  32. data/docs/experiments.md +0 -153
  33. data/docs/ideas.md +0 -80
  34. data/docs/index.md +0 -402
  35. data/docs/pry-integration.md +0 -27
  36. data/docs/research.md +0 -93
  37. data/docs/shortcuts.md +0 -323
  38. data/docs/similarity_tutorial.md +0 -176
  39. data/docs/syntax.md +0 -395
  40. data/docs/videos.md +0 -16
  41. data/examples/build_stubbed_and_let_it_be_experiment.rb +0 -51
  42. data/examples/experimental_replacement.rb +0 -46
  43. data/examples/find_usage.rb +0 -26
  44. data/examples/let_it_be_experiment.rb +0 -11
  45. data/examples/method_complexity.rb +0 -37
  46. data/examples/search_duplicated.rb +0 -15
  47. data/examples/similarity_research.rb +0 -58
  48. data/examples/simple_rewriter.rb +0 -6
  49. data/experiments/let_it_be_experiment.rb +0 -9
  50. data/experiments/remove_useless_hook.rb +0 -9
  51. data/experiments/replace_create_with_build_stubbed.rb +0 -10
data/lib/fast.rb CHANGED
@@ -1,28 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'fileutils'
4
- require 'astrolabe/builder'
5
- require_relative 'fast/rewriter'
6
-
7
- # suppress output to avoid parser gem warnings'
8
- def suppress_output
9
- original_stdout = $stdout.clone
10
- original_stderr = $stderr.clone
11
- $stderr.reopen File.new('/dev/null', 'w')
12
- $stdout.reopen File.new('/dev/null', 'w')
13
- yield
14
- ensure
15
- $stdout.reopen original_stdout
16
- $stderr.reopen original_stderr
17
- end
18
4
 
19
- suppress_output do
20
- require 'parser'
21
- require 'parser/current'
22
- end
5
+ require_relative 'fast/source'
6
+ require_relative 'fast/node'
7
+ require_relative 'fast/rewriter'
23
8
 
24
9
  # Fast is a tool to help you search in the code through the Abstract Syntax Tree
25
10
  module Fast
11
+ NODE_PARENTS = ObjectSpace::WeakMap.new
12
+
13
+ class SyntaxError < StandardError; end
14
+
26
15
  # Literals are shortcuts allowed inside {ExpressionParser}
27
16
  LITERAL = {
28
17
  '...' => ->(node) { node&.children&.any? },
@@ -67,92 +56,104 @@ module Fast
67
56
  %\d # bind extra arguments to the expression
68
57
  /x.freeze
69
58
 
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
59
+ class << self
60
+ def ast_node?(node)
61
+ node.respond_to?(:type) && node.respond_to?(:children)
75
62
  end
76
63
 
77
- # @return [Parser::Source::Range] from the expression
78
- def expression
79
- location.expression
64
+ def prism_ast(content, buffer_name: '(string)')
65
+ require_relative 'fast/prism_adapter'
66
+ result = Fast::PrismAdapter.parse(content, buffer_name: buffer_name)
67
+ return result if result
68
+
69
+ prism_errors = Prism.parse(content).errors
70
+ message = prism_errors.map(&:message).uniq.join("\n")
71
+ raise SyntaxError, message
80
72
  end
81
73
 
82
- # @return [String] with the content of the #expression
83
- def source
84
- expression.source
74
+ def parse_ruby(content, buffer_name: '(string)')
75
+ prism_ast(content, buffer_name: buffer_name)
85
76
  end
86
77
 
87
- # @return [Boolean] true if a file exists with the #buffer_name
88
- def from_file?
89
- File.exist?(buffer_name)
78
+ def parser_ast(content, buffer_name: '(string)')
79
+ prism_ast(content, buffer_name: buffer_name)
90
80
  end
91
81
 
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
82
+ def parser_ast_from_file(file)
83
+ @parser_cache ||= {}
84
+ @parser_cache[file] ||=
85
+ begin
86
+ method =
87
+ if file.end_with?('.sql')
88
+ require_relative 'fast/sql' unless respond_to?(:parse_sql)
89
+ :parse_sql
90
+ else
91
+ :parser_ast
92
+ end
93
+ Fast.public_send(method, IO.read(file), buffer_name: file)
94
+ end
97
95
  end
98
96
 
99
- # @return [String] with the first element from #blame_authors
100
- def author
101
- blame_authors.first
97
+ def parse_file(file)
98
+ return parser_ast_from_file(file) if file.end_with?('.sql')
99
+
100
+ @cache ||= {}
101
+ @cache[file] ||=
102
+ begin
103
+ parse_ruby(IO.read(file), buffer_name: file)
104
+ end
102
105
  end
103
106
 
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)
107
+ def summary(code_or_ast, file: nil, command_name: '.summary', level: nil)
108
+ require_relative 'fast/summary'
109
+ Summary.new(code_or_ast, file: file, command_name: command_name, level: level)
110
110
  end
111
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)
112
+ def scan(locations, command_name: '.scan', level: nil)
113
+ require_relative 'fast/scan'
114
+ Scan.new(locations, command_name: command_name, level: level)
118
115
  end
119
- end
120
116
 
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)
117
+ def parser_class
118
+ raise NoMethodError, 'Fast.parser_class was removed; Fast now parses Ruby with Prism'
119
+ end
120
+
121
+ def parser_require_path
122
+ raise NoMethodError, 'Fast.parser_require_path was removed; Fast now parses Ruby with Prism'
123
+ end
124
+
125
+ def parser_const_name
126
+ raise NoMethodError, 'Fast.parser_const_name was removed; Fast now parses Ruby with Prism'
127
+ end
128
+
129
+ def parser_version_supported?(const_name)
130
+ raise NoMethodError, "Fast.parser_version_supported?(#{const_name.inspect}) was removed; Fast now parses Ruby with Prism"
129
131
  end
130
- end
131
132
 
132
- class << self
133
133
  # @return [Fast::Node] from the parsed content
134
134
  # @example
135
135
  # Fast.ast("1") # => s(:int, 1)
136
136
  # Fast.ast("a.b") # => s(:send, s(:send, nil, :a), :b)
137
137
  def ast(content, buffer_name: '(string)')
138
- buffer = Parser::Source::Buffer.new(buffer_name)
139
- buffer.source = content
140
- Parser::CurrentRuby.new(builder_for(buffer_name)).parse(buffer)
138
+ parse_ruby(content, buffer_name: buffer_name)
139
+ end
140
+
141
+ def validate_ruby!(content, buffer_name: '(string)')
142
+ prism_ast(content, buffer_name: buffer_name)
143
+ true
141
144
  end
142
145
 
143
146
  def builder_for(buffer_name)
144
- builder = Builder.new
145
- builder.buffer_name = buffer_name
146
- builder
147
+ raise NoMethodError, "Fast.builder_for(#{buffer_name.inspect}) was removed; Fast now parses Ruby with Prism"
147
148
  end
148
149
 
149
150
  # @return [Fast::Node] parsed from file content
150
151
  # caches the content based on the filename.
152
+ # Also, it can parse SQL files.
151
153
  # @example
152
154
  # Fast.ast_from_file("example.rb") # => s(...)
153
155
  def ast_from_file(file)
154
- @cache ||= {}
155
- @cache[file] ||= ast(IO.read(file), buffer_name: file)
156
+ parse_file(file)
156
157
  end
157
158
 
158
159
  # Verify if a given AST matches with a specific pattern
@@ -169,7 +170,12 @@ module Fast
169
170
  node = ast_from_file(file)
170
171
  return [] unless node
171
172
 
172
- search pattern, node
173
+ case node
174
+ when Array
175
+ node.map { |n| search(pattern, n) }.flatten.compact
176
+ else
177
+ search pattern, node
178
+ end
173
179
  end
174
180
 
175
181
  # Search with pattern on a directory or multiple files
@@ -228,8 +234,12 @@ module Fast
228
234
  def capture_file(pattern, file)
229
235
  node = ast_from_file(file)
230
236
  return [] unless node
231
-
232
- capture pattern, node
237
+ case node
238
+ when Array
239
+ node.map { |n| capture(pattern, n) }.flatten.compact
240
+ else
241
+ capture pattern, node
242
+ end
233
243
  end
234
244
 
235
245
  # Search recursively into a node and its children.
@@ -241,9 +251,14 @@ module Fast
241
251
  yield node, match if block_given?
242
252
  match != true ? [node, match] : [node]
243
253
  else
244
- node.each_child_node
245
- .flat_map { |child| search(pattern, child, *args) }
246
- .compact.flatten
254
+ case node
255
+ when Array
256
+ node.flat_map { |child| search(pattern, child, *args) }
257
+ else
258
+ node.each_child_node
259
+ .flat_map { |child| search(pattern, child, *args) }
260
+ .compact.flatten
261
+ end
247
262
  end
248
263
  end
249
264
 
@@ -305,6 +320,73 @@ module Fast
305
320
  files.reject(&dir_filter)
306
321
  end
307
322
 
323
+ # Folds the AST to a maximum depth, replacing deeper branches with `...`
324
+ # @param node [Fast::Node]
325
+ # @param level [Integer] maximum depth to explore
326
+ # @param current_level [Integer] internal tracker for depth
327
+ # @return [Fast::Node] the folded AST
328
+ def fold_ast(node, level: nil, current_level: 1)
329
+ return node unless ast_node?(node) && node.respond_to?(:updated)
330
+ return node if level.nil?
331
+
332
+ if current_level >= level
333
+ if node.children.any?
334
+ node.updated(nil, [:'...'])
335
+ else
336
+ node
337
+ end
338
+ else
339
+ new_children = node.children.map { |c| fold_ast(c, level: level, current_level: current_level + 1) }
340
+ node.updated(nil, new_children)
341
+ end
342
+ end
343
+
344
+ # Folds ruby source code to a maximum depth, replacing deep block bodies with `# ...`
345
+ # @param node [Fast::Node]
346
+ # @param level [Integer] maximum depth to explore
347
+ # @return [String] the folded source representation
348
+ def fold_source(node, level: 1)
349
+ return node if node.is_a?(String)
350
+ return node.loc.expression.source rescue node.to_s unless ast_node?(node) && node.respond_to?(:loc)
351
+
352
+ source = node.loc.expression.source.dup
353
+ root_begin = node.loc.expression.begin_pos
354
+
355
+ regions = []
356
+
357
+ walker = ->(n, current_level) do
358
+ return unless ast_node?(n)
359
+
360
+ if current_level >= level
361
+ body_node = nil
362
+ case n.type
363
+ when :class, :module, :def, :defs, :block
364
+ body_node = n.children.last
365
+ when :begin
366
+ body_node = n
367
+ end
368
+
369
+ if body_node && body_node.loc && body_node.loc.respond_to?(:expression) && body_node.loc.expression
370
+ regions << [
371
+ body_node.loc.expression.begin_pos - root_begin,
372
+ body_node.loc.expression.end_pos - root_begin
373
+ ]
374
+ return
375
+ end
376
+ end
377
+
378
+ n.children.each { |c| walker.call(c, current_level + 1) if ast_node?(c) }
379
+ end
380
+
381
+ walker.call(node, 1)
382
+
383
+ regions.sort_by { |r| -r[0] }.each do |start_pos, end_pos|
384
+ source[start_pos...end_pos] = "# ..."
385
+ end
386
+
387
+ source
388
+ end
389
+
308
390
  # Extracts a node pattern expression from a given node supressing identifiers and primitive types.
309
391
  # Useful to index abstract patterns or similar code structure.
310
392
  # @see https://jonatas.github.io/fast/similarity_tutorial/
@@ -316,7 +398,7 @@ module Fast
316
398
  # Fast.expression_from(Fast.ast('def name; person.name end')) # => '(def _ (args) (send (send nil _) _))'
317
399
  def expression_from(node)
318
400
  case node
319
- when Parser::AST::Node
401
+ when ->(candidate) { ast_node?(candidate) }
320
402
  children_expression = node.children.map(&method(:expression_from)).join(' ')
321
403
  "(#{node.type}#{" #{children_expression}" if node.children.any?})"
322
404
  when nil, 'nil'
@@ -431,10 +513,14 @@ module Fast
431
513
 
432
514
  def compare_symbol_or_head(expression, node)
433
515
  case node
434
- when Parser::AST::Node
516
+ when ->(candidate) { Fast.ast_node?(candidate) }
435
517
  node.type == expression.to_sym
436
518
  when String
437
519
  node == expression.to_s
520
+ when TrueClass
521
+ expression == :true
522
+ when FalseClass
523
+ expression == :false
438
524
  else
439
525
  node == expression
440
526
  end
data/mkdocs.yml CHANGED
@@ -1,27 +1,51 @@
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
+
5
+ extra:
6
+ analytics:
7
+ provider: google
8
+ property: G-YKZDZDNRG2
9
+
5
10
  theme:
6
11
  name: material
7
12
  palette:
8
13
  primary: indigo
9
14
  accent: pink
15
+ logo: assets/logo.png
16
+ favicon: assets/favicon.png
17
+ extra_css:
18
+ - stylesheets/custom.css
19
+
20
+ plugins:
21
+ - search
22
+
10
23
  markdown_extensions:
11
24
  - admonition
12
- - codehilite:
13
- guess_lang: false
25
+ - pymdownx.details
26
+ - pymdownx.superfences
27
+ - pymdownx.tabbed:
28
+ alternate_style: true
14
29
  - toc:
15
30
  permalink: true
16
31
  nav:
17
32
  - Introduction: index.md
33
+ - Walkthrough: walkthrough.md
18
34
  - Syntax: syntax.md
19
35
  - Command Line: command_line.md
20
36
  - Experiments: experiments.md
21
37
  - Shortcuts: shortcuts.md
38
+ - Git Integration: git.md
39
+ - Fast for LLMs and Agents: agents.md
40
+ - MCP Server Tutorial: mcp_tutorial.md
22
41
  - Code Similarity: similarity_tutorial.md
42
+ - LLM/Agent Feature TODOs: llm_features.md
23
43
  - Pry Integration: pry-integration.md
24
44
  - Editors' Integration: editors-integration.md
25
45
  - Research: research.md
26
46
  - Ideas: ideas.md
27
47
  - Videos: videos.md
48
+ - SQL:
49
+ - Intro: sql/index.md
50
+ - Shortcuts: sql/shortcuts.md
51
+ - About: sql-support.md
@@ -0,0 +1,3 @@
1
+ mkdocs>=1.6,<2.0
2
+ mkdocs-material>=9.5,<10.0
3
+ pymdown-extensions>=10.0,<11.0
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ffast
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.3
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: 2020-09-29 00:00:00.000000000 Z
11
+ date: 2026-03-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: astrolabe
14
+ name: coderay
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: coderay
28
+ name: parallel
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -39,7 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: parallel
42
+ name: pg_query
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -53,13 +53,13 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: parser
56
+ name: bundler
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
- type: :runtime
62
+ type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
@@ -67,7 +67,7 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: bundler
70
+ name: git
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
@@ -137,7 +137,7 @@ dependencies:
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
139
  - !ruby/object:Gem::Dependency
140
- name: git
140
+ name: rake
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
143
  - - ">="
@@ -151,7 +151,7 @@ dependencies:
151
151
  - !ruby/object:Gem::Version
152
152
  version: '0'
153
153
  - !ruby/object:Gem::Dependency
154
- name: rake
154
+ name: rspec
155
155
  requirement: !ruby/object:Gem::Requirement
156
156
  requirements:
157
157
  - - ">="
@@ -164,34 +164,20 @@ dependencies:
164
164
  - - ">="
165
165
  - !ruby/object:Gem::Version
166
166
  version: '0'
167
- - !ruby/object:Gem::Dependency
168
- name: rspec
169
- requirement: !ruby/object:Gem::Requirement
170
- requirements:
171
- - - "~>"
172
- - !ruby/object:Gem::Version
173
- version: '3.0'
174
- type: :development
175
- prerelease: false
176
- version_requirements: !ruby/object:Gem::Requirement
177
- requirements:
178
- - - "~>"
179
- - !ruby/object:Gem::Version
180
- version: '3.0'
181
167
  - !ruby/object:Gem::Dependency
182
168
  name: rspec-its
183
169
  requirement: !ruby/object:Gem::Requirement
184
170
  requirements:
185
- - - "~>"
171
+ - - ">="
186
172
  - !ruby/object:Gem::Version
187
- version: '1.2'
173
+ version: '0'
188
174
  type: :development
189
175
  prerelease: false
190
176
  version_requirements: !ruby/object:Gem::Requirement
191
177
  requirements:
192
- - - "~>"
178
+ - - ">="
193
179
  - !ruby/object:Gem::Version
194
- version: '1.2'
180
+ version: '0'
195
181
  - !ruby/object:Gem::Dependency
196
182
  name: rubocop
197
183
  requirement: !ruby/object:Gem::Requirement
@@ -238,22 +224,16 @@ dependencies:
238
224
  name: simplecov
239
225
  requirement: !ruby/object:Gem::Requirement
240
226
  requirements:
241
- - - "~>"
242
- - !ruby/object:Gem::Version
243
- version: '0.10'
244
- - - "<"
227
+ - - ">="
245
228
  - !ruby/object:Gem::Version
246
- version: '0.18'
229
+ version: '0'
247
230
  type: :development
248
231
  prerelease: false
249
232
  version_requirements: !ruby/object:Gem::Requirement
250
233
  requirements:
251
- - - "~>"
252
- - !ruby/object:Gem::Version
253
- version: '0.10'
254
- - - "<"
234
+ - - ">="
255
235
  - !ruby/object:Gem::Version
256
- version: '0.18'
236
+ version: '0'
257
237
  description: Allow you to search for code using node pattern syntax.
258
238
  email:
259
239
  - jonatasdp@gmail.com
@@ -263,6 +243,8 @@ executables:
263
243
  extensions: []
264
244
  extra_rdoc_files: []
265
245
  files:
246
+ - ".github/workflows/release.yml"
247
+ - ".github/workflows/ruby.yml"
266
248
  - ".gitignore"
267
249
  - ".projections.json"
268
250
  - ".rspec"
@@ -280,43 +262,47 @@ files:
280
262
  - bin/console
281
263
  - bin/fast
282
264
  - bin/fast-experiment
265
+ - bin/fast-mcp
283
266
  - bin/setup
284
- - docs/command_line.md
285
- - docs/editors-integration.md
286
- - docs/experiments.md
287
- - docs/ideas.md
288
- - docs/index.md
289
- - docs/pry-integration.md
290
- - docs/research.md
291
- - docs/shortcuts.md
292
- - docs/similarity_tutorial.md
293
- - docs/syntax.md
294
- - docs/videos.md
295
- - examples/build_stubbed_and_let_it_be_experiment.rb
296
- - examples/experimental_replacement.rb
297
- - examples/find_usage.rb
298
- - examples/let_it_be_experiment.rb
299
- - examples/method_complexity.rb
300
- - examples/search_duplicated.rb
301
- - examples/similarity_research.rb
302
- - examples/simple_rewriter.rb
303
- - experiments/let_it_be_experiment.rb
304
- - experiments/remove_useless_hook.rb
305
- - experiments/replace_create_with_build_stubbed.rb
306
267
  - fast.gemspec
307
268
  - lib/fast.rb
308
269
  - lib/fast/cli.rb
309
270
  - lib/fast/experiment.rb
310
271
  - lib/fast/git.rb
272
+ - lib/fast/mcp_server.rb
273
+ - lib/fast/node.rb
274
+ - lib/fast/prism_adapter.rb
311
275
  - lib/fast/rewriter.rb
276
+ - lib/fast/scan.rb
312
277
  - lib/fast/shortcut.rb
278
+ - lib/fast/source.rb
279
+ - lib/fast/source_rewriter.rb
280
+ - lib/fast/sql.rb
281
+ - lib/fast/sql/rewriter.rb
282
+ - lib/fast/summary.rb
313
283
  - lib/fast/version.rb
314
284
  - mkdocs.yml
285
+ - requirements-docs.txt
315
286
  homepage: https://jonatas.github.io/fast/
316
287
  licenses:
317
288
  - MIT
318
289
  metadata: {}
319
- post_install_message:
290
+ post_install_message: |2+
291
+
292
+ ==========================================================
293
+ Yay! Thanks for installing
294
+
295
+ ___ __ ___
296
+ |__ / /__` |
297
+ | /~~ .__/ |
298
+
299
+ To interactive learn about the gem in the terminal use:
300
+
301
+ fast .intro
302
+
303
+ More docs at: https://jonatas.github.io/fast/
304
+ ==========================================================
305
+
320
306
  rdoc_options: []
321
307
  require_paths:
322
308
  - lib
@@ -332,7 +318,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
332
318
  - !ruby/object:Gem::Version
333
319
  version: '0'
334
320
  requirements: []
335
- rubygems_version: 3.0.3
321
+ rubygems_version: 3.5.22
336
322
  signing_key:
337
323
  specification_version: 4
338
324
  summary: 'FAST: Find by AST.'