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.
- checksums.yaml +4 -4
- data/.github/workflows/release.yml +27 -0
- data/.github/workflows/ruby.yml +34 -0
- data/.gitignore +2 -0
- data/Fastfile +146 -3
- data/README.md +244 -132
- data/bin/console +6 -1
- data/bin/fast-experiment +3 -0
- data/bin/fast-mcp +7 -0
- data/fast.gemspec +24 -7
- data/lib/fast/cli.rb +129 -38
- data/lib/fast/experiment.rb +19 -2
- data/lib/fast/git.rb +1 -1
- data/lib/fast/mcp_server.rb +317 -0
- data/lib/fast/node.rb +258 -0
- data/lib/fast/prism_adapter.rb +310 -0
- data/lib/fast/rewriter.rb +64 -10
- data/lib/fast/scan.rb +203 -0
- data/lib/fast/shortcut.rb +23 -6
- data/lib/fast/source.rb +116 -0
- data/lib/fast/source_rewriter.rb +153 -0
- data/lib/fast/sql/rewriter.rb +98 -0
- data/lib/fast/sql.rb +165 -0
- data/lib/fast/summary.rb +435 -0
- data/lib/fast/version.rb +1 -1
- data/lib/fast.rb +165 -79
- data/mkdocs.yml +27 -3
- data/requirements-docs.txt +3 -0
- metadata +48 -62
- data/docs/command_line.md +0 -238
- data/docs/editors-integration.md +0 -46
- data/docs/experiments.md +0 -153
- data/docs/ideas.md +0 -80
- data/docs/index.md +0 -402
- data/docs/pry-integration.md +0 -27
- data/docs/research.md +0 -93
- data/docs/shortcuts.md +0 -323
- data/docs/similarity_tutorial.md +0 -176
- data/docs/syntax.md +0 -395
- data/docs/videos.md +0 -16
- data/examples/build_stubbed_and_let_it_be_experiment.rb +0 -51
- data/examples/experimental_replacement.rb +0 -46
- data/examples/find_usage.rb +0 -26
- data/examples/let_it_be_experiment.rb +0 -11
- data/examples/method_complexity.rb +0 -37
- data/examples/search_duplicated.rb +0 -15
- data/examples/similarity_research.rb +0 -58
- data/examples/simple_rewriter.rb +0 -6
- data/experiments/let_it_be_experiment.rb +0 -9
- data/experiments/remove_useless_hook.rb +0 -9
- 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
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
-
|
|
83
|
-
|
|
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
|
-
|
|
88
|
-
|
|
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
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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
|
-
|
|
100
|
-
|
|
101
|
-
|
|
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
|
-
|
|
105
|
-
|
|
106
|
-
|
|
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
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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
|
-
|
|
139
|
-
|
|
140
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
245
|
-
|
|
246
|
-
.
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
-
|
|
13
|
-
|
|
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
|
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.
|
|
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:
|
|
11
|
+
date: 2026-03-30 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
|
-
name:
|
|
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:
|
|
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:
|
|
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:
|
|
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: :
|
|
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:
|
|
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:
|
|
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:
|
|
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: '
|
|
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: '
|
|
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
|
|
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
|
|
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.
|
|
321
|
+
rubygems_version: 3.5.22
|
|
336
322
|
signing_key:
|
|
337
323
|
specification_version: 4
|
|
338
324
|
summary: 'FAST: Find by AST.'
|