ffast 0.1.5 → 0.2.0
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 +114 -2
 - data/.sourcelevel.yml +2 -0
 - data/.travis.yml +2 -2
 - data/Fastfile +3 -0
 - data/README.md +10 -5
 - data/docs/command_line.md +1 -0
 - data/docs/editors-integration.md +46 -0
 - data/docs/ideas.md +80 -0
 - data/docs/index.md +5 -0
 - data/docs/research.md +93 -0
 - data/docs/shortcuts.md +323 -0
 - data/docs/videos.md +16 -0
 - data/fast.gemspec +6 -4
 - data/lib/fast.rb +135 -40
 - data/lib/fast/cli.rb +61 -23
 - data/lib/fast/experiment.rb +1 -2
 - data/lib/fast/git.rb +101 -0
 - data/lib/fast/shortcut.rb +6 -9
 - data/lib/fast/version.rb +1 -1
 - data/mkdocs.yml +5 -0
 - metadata +54 -13
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 3942d57d80b4c4a1cd1c8ff40f18cc56508a51f4b6cae53480536f7c36a60b05
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: b60976ea570cf722ae6face8541881c6a1231b2d645727f25231a05c9f33f7ee
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: c4df11570f2b2cc164dbd43815a37443541c98c955d6c84ea0b24564fd03b8534cf73479844393ecd72c794231ad40baf678784f9863a8f90c157ac8477f3c9d
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: d9481952776fc77d251a3c9f518f41e20d672298e9ff01b53b8673a0c0bc38f4919e4dd7234365e8044f5cef8e0738823d847900bea790f9796e6d8554342a06
         
     | 
    
        data/.rubocop.yml
    CHANGED
    
    | 
         @@ -8,11 +8,114 @@ AllCops: 
     | 
|
| 
       8 
8 
     | 
    
         
             
              Exclude:
         
     | 
| 
       9 
9 
     | 
    
         
             
                - 'tmp/**/*'
         
     | 
| 
       10 
10 
     | 
    
         
             
                - 'examples/*'
         
     | 
| 
       11 
     | 
    
         
            -
              TargetRubyVersion: 2. 
     | 
| 
      
 11 
     | 
    
         
            +
              TargetRubyVersion: 2.6
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
      
 13 
     | 
    
         
            +
            Layout/LineLength:
         
     | 
| 
       14 
14 
     | 
    
         
             
              Enabled: false
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
      
 16 
     | 
    
         
            +
            Layout/EmptyLinesAroundAttributeAccessor:
         
     | 
| 
      
 17 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            Layout/SpaceAroundMethodCallOperator:
         
     | 
| 
      
 20 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            Lint/BinaryOperatorWithIdenticalOperands:
         
     | 
| 
      
 23 
     | 
    
         
            +
              Enabled: true
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            Lint/DuplicateElsifCondition:
         
     | 
| 
      
 26 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            Lint/DuplicateRescueException:
         
     | 
| 
      
 29 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            Lint/EmptyConditionalBody:
         
     | 
| 
      
 32 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            Lint/FloatComparison:
         
     | 
| 
      
 35 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
            Lint/MissingSuper:
         
     | 
| 
      
 38 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            Lint/OutOfRangeRegexpRef:
         
     | 
| 
      
 41 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            Lint/SelfAssignment:
         
     | 
| 
      
 44 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
            Lint/TopLevelReturnWithArgument:
         
     | 
| 
      
 47 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
            Lint/UnreachableLoop:
         
     | 
| 
      
 50 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
            Lint/DeprecatedOpenSSLConstant:
         
     | 
| 
      
 54 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
            Lint/MixedRegexpCaptureTypes:
         
     | 
| 
      
 57 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
            Lint/RaiseException:
         
     | 
| 
      
 60 
     | 
    
         
            +
              Enabled: true
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
            Lint/StructNewOverride:
         
     | 
| 
      
 63 
     | 
    
         
            +
              Enabled: true
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
            Style/AccessorGrouping:
         
     | 
| 
      
 66 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
            Style/ArrayCoercion:
         
     | 
| 
      
 69 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
            Style/BisectedAttrAccessor:
         
     | 
| 
      
 72 
     | 
    
         
            +
              Enabled: true
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
            Style/CaseLikeIf:
         
     | 
| 
      
 75 
     | 
    
         
            +
              Enabled: true
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
            Style/ExplicitBlockArgument:
         
     | 
| 
      
 78 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
            Style/ExponentialNotation:
         
     | 
| 
      
 81 
     | 
    
         
            +
              Enabled: true
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
            Style/GlobalStdStream:
         
     | 
| 
      
 84 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
            Style/HashAsLastArrayItem:
         
     | 
| 
      
 87 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
            Style/HashLikeCase:
         
     | 
| 
      
 90 
     | 
    
         
            +
              Enabled: true
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
            Style/OptionalBooleanParameter:
         
     | 
| 
      
 93 
     | 
    
         
            +
              Enabled: true
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
            Style/RedundantAssignment:
         
     | 
| 
      
 96 
     | 
    
         
            +
              Enabled: true
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
            Style/RedundantFetchBlock:
         
     | 
| 
      
 99 
     | 
    
         
            +
              Enabled: true
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
            Style/RedundantFileExtensionInRequire:
         
     | 
| 
      
 102 
     | 
    
         
            +
              Enabled: true
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
            Style/SingleArgumentDig:
         
     | 
| 
      
 105 
     | 
    
         
            +
              Enabled: true
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
            Style/StringConcatenation:
         
     | 
| 
      
 108 
     | 
    
         
            +
              Enabled: true
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
            Style/RedundantRegexpCharacterClass:
         
     | 
| 
      
 111 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
            Style/RedundantRegexpEscape:
         
     | 
| 
      
 114 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
            Style/SlicingWithRange:
         
     | 
| 
      
 117 
     | 
    
         
            +
              Enabled: true
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
       16 
119 
     | 
    
         
             
            Metrics/BlockLength:
         
     | 
| 
       17 
120 
     | 
    
         
             
              Exclude:
         
     | 
| 
       18 
121 
     | 
    
         
             
                - 'spec/**/*'
         
     | 
| 
         @@ -46,3 +149,12 @@ RSpec/DescribedClass: 
     | 
|
| 
       46 
149 
     | 
    
         | 
| 
       47 
150 
     | 
    
         
             
            RSpec/ImplicitSubject:
         
     | 
| 
       48 
151 
     | 
    
         
             
              Enabled: false
         
     | 
| 
      
 152 
     | 
    
         
            +
             
     | 
| 
      
 153 
     | 
    
         
            +
            Style/HashEachMethods:
         
     | 
| 
      
 154 
     | 
    
         
            +
              Enabled: true
         
     | 
| 
      
 155 
     | 
    
         
            +
             
     | 
| 
      
 156 
     | 
    
         
            +
            Style/HashTransformKeys:
         
     | 
| 
      
 157 
     | 
    
         
            +
              Enabled: true
         
     | 
| 
      
 158 
     | 
    
         
            +
             
     | 
| 
      
 159 
     | 
    
         
            +
            Style/HashTransformValues:
         
     | 
| 
      
 160 
     | 
    
         
            +
              Enabled: true
         
     | 
    
        data/.sourcelevel.yml
    ADDED
    
    
    
        data/.travis.yml
    CHANGED
    
    | 
         @@ -6,7 +6,7 @@ env: 
     | 
|
| 
       6 
6 
     | 
    
         
             
            rvm:
         
     | 
| 
       7 
7 
     | 
    
         
             
              - 2.6.3
         
     | 
| 
       8 
8 
     | 
    
         
             
            before_install:
         
     | 
| 
       9 
     | 
    
         
            -
              gem install bundler -v 1. 
     | 
| 
      
 9 
     | 
    
         
            +
              gem install bundler -v 2.1.4
         
     | 
| 
       10 
10 
     | 
    
         
             
            before_script:
         
     | 
| 
       11 
11 
     | 
    
         
             
              - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
         
     | 
| 
       12 
12 
     | 
    
         
             
              - chmod +x ./cc-test-reporter
         
     | 
| 
         @@ -14,5 +14,5 @@ before_script: 
     | 
|
| 
       14 
14 
     | 
    
         
             
            after_script:
         
     | 
| 
       15 
15 
     | 
    
         
             
              - ./cc-test-reporter after-build -t simplecov --exit-code $TRAVIS_TEST_RESULT
         
     | 
| 
       16 
16 
     | 
    
         
             
            script:
         
     | 
| 
       17 
     | 
    
         
            -
              - bundle exec rubocop
         
     | 
| 
      
 17 
     | 
    
         
            +
              - bundle exec rubocop --fail-level warning --display-only-fail-level-offenses
         
     | 
| 
       18 
18 
     | 
    
         
             
              - bundle exec rspec
         
     | 
    
        data/Fastfile
    CHANGED
    
    | 
         @@ -8,6 +8,9 @@ 
     | 
|
| 
       8 
8 
     | 
    
         
             
            # Let's say you'd like to show the version that is over the version file
         
     | 
| 
       9 
9 
     | 
    
         
             
            Fast.shortcut(:version, '(casgn nil VERSION (str _))', 'lib/fast/version.rb')
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
      
 11 
     | 
    
         
            +
            # Show all classes that inherits Fast::Find
         
     | 
| 
      
 12 
     | 
    
         
            +
            Fast.shortcut(:finders, '(class ... (const nil Find)', 'lib')
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
       11 
14 
     | 
    
         
             
            # You can run shortcuts appending a dot to the shortcut.
         
     | 
| 
       12 
15 
     | 
    
         
             
            #   $ fast .version
         
     | 
| 
       13 
16 
     | 
    
         
             
            #   # lib/fast/version.rb:4
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -32,7 +32,7 @@ The current version of Fast covers the following token elements: 
     | 
|
| 
       32 
32 
     | 
    
         
             
                to build custom rules.
         
     | 
| 
       33 
33 
     | 
    
         
             
            - `.<method-name>` - will call `<method-name>` from the `node`
         
     | 
| 
       34 
34 
     | 
    
         | 
| 
       35 
     | 
    
         
            -
            The syntax is inspired by the [RuboCop Node Pattern](https://github.com/ 
     | 
| 
      
 35 
     | 
    
         
            +
            The syntax is inspired by the [RuboCop Node Pattern](https://github.com/rubocop-hq/rubocop-ast/blob/master/lib/rubocop/ast/node_pattern.rb).
         
     | 
| 
       36 
36 
     | 
    
         | 
| 
       37 
37 
     | 
    
         
             
            ## Installation
         
     | 
| 
       38 
38 
     | 
    
         | 
| 
         @@ -253,25 +253,29 @@ This can be represented as the following AST: 
     | 
|
| 
       253 
253 
     | 
    
         | 
| 
       254 
254 
     | 
    
         
             
            We can create a query that searches for such a method:
         
     | 
| 
       255 
255 
     | 
    
         | 
| 
       256 
     | 
    
         
            -
                Fast.match?( 
     | 
| 
      
 256 
     | 
    
         
            +
                Fast.match?('(def $_ ... (send (send nil _) \1))', ast) # => [:name]
         
     | 
| 
       257 
257 
     | 
    
         | 
| 
       258 
258 
     | 
    
         
             
            ## Fast.search
         
     | 
| 
       259 
259 
     | 
    
         | 
| 
       260 
260 
     | 
    
         
             
            Search allows you to go search the entire AST, collecting nodes that matches given
         
     | 
| 
       261 
261 
     | 
    
         
             
            expression. Any matching node is then returned:
         
     | 
| 
       262 
262 
     | 
    
         | 
| 
       263 
     | 
    
         
            -
                Fast.search(Fast.ast('a = 1') 
     | 
| 
      
 263 
     | 
    
         
            +
                Fast.search('(int _)', Fast.ast('a = 1')) # => s(:int, 1)
         
     | 
| 
       264 
264 
     | 
    
         | 
| 
       265 
265 
     | 
    
         
             
            If you use captures along with a search, both the matching nodes and the
         
     | 
| 
       266 
266 
     | 
    
         
             
            captures will be returned:
         
     | 
| 
       267 
267 
     | 
    
         | 
| 
       268 
     | 
    
         
            -
                Fast.search(Fast.ast('a = 1') 
     | 
| 
      
 268 
     | 
    
         
            +
                Fast.search('(int $_)', Fast.ast('a = 1')) # => [s(:int, 1), 1]
         
     | 
| 
      
 269 
     | 
    
         
            +
             
     | 
| 
      
 270 
     | 
    
         
            +
            You can also bind external parameters from the search:
         
     | 
| 
      
 271 
     | 
    
         
            +
             
     | 
| 
      
 272 
     | 
    
         
            +
                Fast.search('(int %1)', Fast.ast('a = 1'), 1) # => [s(:int, 1)]
         
     | 
| 
       269 
273 
     | 
    
         | 
| 
       270 
274 
     | 
    
         
             
            ## Fast.capture
         
     | 
| 
       271 
275 
     | 
    
         | 
| 
       272 
276 
     | 
    
         
             
            To only pick captures and ignore the nodes, use `Fast.capture`:
         
     | 
| 
       273 
277 
     | 
    
         | 
| 
       274 
     | 
    
         
            -
              Fast.capture(Fast.ast('a = 1') 
     | 
| 
      
 278 
     | 
    
         
            +
              Fast.capture('(int $_)', Fast.ast('a = 1')) # => 1
         
     | 
| 
       275 
279 
     | 
    
         | 
| 
       276 
280 
     | 
    
         
             
            ## Fast.replace
         
     | 
| 
       277 
281 
     | 
    
         | 
| 
         @@ -421,6 +425,7 @@ The CLI tool takes the following flags 
     | 
|
| 
       421 
425 
     | 
    
         
             
            - Use `--pry` to jump debugging the first result with pry
         
     | 
| 
       422 
426 
     | 
    
         
             
            - Use `-c` to search from code example
         
     | 
| 
       423 
427 
     | 
    
         
             
            - Use `-s` to search similar code
         
     | 
| 
      
 428 
     | 
    
         
            +
            - Use `-p` or `--parallel` to parallelize the search
         
     | 
| 
       424 
429 
     | 
    
         | 
| 
       425 
430 
     | 
    
         
             
            ### Define your `Fastfile`
         
     | 
| 
       426 
431 
     | 
    
         | 
    
        data/docs/command_line.md
    CHANGED
    
    
| 
         @@ -0,0 +1,46 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Editors' integration
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            We don't have any proper integration or official plugins for editors yet.
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            Here are a few ideas you can use to make your own flow.
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            ## Vim
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            Split terminal vertically and open fast focused on build the expression.
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            ```vim
         
     | 
| 
      
 12 
     | 
    
         
            +
            nnoremap <Leader>ff :vsplit \| terminal fast "()" % <Left><Left><Left><Left><Left>
         
     | 
| 
      
 13 
     | 
    
         
            +
            ```
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            Or you can build a function:
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            ```vim
         
     | 
| 
      
 18 
     | 
    
         
            +
            function! s:Fast(args)
         
     | 
| 
      
 19 
     | 
    
         
            +
              let cmd = ''
         
     | 
| 
      
 20 
     | 
    
         
            +
              if !empty(b:ruby_project_root)
         
     | 
| 
      
 21 
     | 
    
         
            +
                let cmd .= 'cd ' . b:ruby_project_root . ' && '
         
     | 
| 
      
 22 
     | 
    
         
            +
              endif
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
              let cmd .= 'fast --no-color ' . a:args
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              let custom_maker = neomake#utils#MakerFromCommand(cmd)
         
     | 
| 
      
 27 
     | 
    
         
            +
              let custom_maker.name = cmd
         
     | 
| 
      
 28 
     | 
    
         
            +
              let custom_maker.cwd = b:ruby_project_root
         
     | 
| 
      
 29 
     | 
    
         
            +
              let custom_maker.remove_invalid_entries = 0
         
     | 
| 
      
 30 
     | 
    
         
            +
              " e.g.:
         
     | 
| 
      
 31 
     | 
    
         
            +
              "   # path/to/file.rb:1141
         
     | 
| 
      
 32 
     | 
    
         
            +
              "   my_method(
         
     | 
| 
      
 33 
     | 
    
         
            +
              "     :boom,
         
     | 
| 
      
 34 
     | 
    
         
            +
              "     arg1: 1,
         
     | 
| 
      
 35 
     | 
    
         
            +
              "   )
         
     | 
| 
      
 36 
     | 
    
         
            +
              " %W# %f:%l -> start a multiline warning when the line matches '# path/file.rb:1234'
         
     | 
| 
      
 37 
     | 
    
         
            +
              " %-Z# end multiline warning on the next line that starts with '#'
         
     | 
| 
      
 38 
     | 
    
         
            +
              " %C%m continued multiline warning message
         
     | 
| 
      
 39 
     | 
    
         
            +
              let custom_maker.errorformat = '%W# %f:%l, %-Z#, %C%m'
         
     | 
| 
      
 40 
     | 
    
         
            +
              let enabled_makers = [custom_maker]
         
     | 
| 
      
 41 
     | 
    
         
            +
              update | call neomake#Make(0, enabled_makers) | echom "running: " . cmd
         
     | 
| 
      
 42 
     | 
    
         
            +
            endfunction
         
     | 
| 
      
 43 
     | 
    
         
            +
            command! -complete=file -nargs=1 Fast call s:Fast(<q-args>)
         
     | 
| 
      
 44 
     | 
    
         
            +
            ```
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
            Check the conversation about vim integration [here](https://github.com/jonatas/fast/pull/16#issuecomment-555115606).
         
     | 
    
        data/docs/ideas.md
    ADDED
    
    | 
         @@ -0,0 +1,80 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Ideas I want to build with Fast
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            I don't have all the time I need to develop all the ideas I have to build
         
     | 
| 
      
 4 
     | 
    
         
            +
            around this tool, so here is a dump of a few brainstormings:
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            ## Inline target code
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            I started [fast-inline](https://github.com/jonatas/fast-inline) that can be
         
     | 
| 
      
 9 
     | 
    
         
            +
            useful to try to see how much every library is used in a project.
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            My idea is try to inline some specific method call to understand if it makes
         
     | 
| 
      
 12 
     | 
    
         
            +
            sense to have an entire library in the stock.
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            Understanding dependencies and how the code works can be a first step to get an
         
     | 
| 
      
 15 
     | 
    
         
            +
            "algorithm as a service". Instead of loading everything from the library, it
         
     | 
| 
      
 16 
     | 
    
         
            +
            would facilitate the cherry pick of only the proper dependencies necessaries to
         
     | 
| 
      
 17 
     | 
    
         
            +
            run the code you have and not the code that is overloading the project.
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            ## Neo4J adapter
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            Easy pipe fast results to Neo4J. It would facilitate to explore more complex
         
     | 
| 
      
 22 
     | 
    
         
            +
            scenarios and combine data from other sources.
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            ## Git adapter
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            Add extra tags to nodes with information from Git.
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            * Revision
         
     | 
| 
      
 29 
     | 
    
         
            +
            * Author
         
     | 
| 
      
 30 
     | 
    
         
            +
            * Date
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            Tag every node with the proper author.
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            ## Ast Diff
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            Allow to compare and return a summary of differences between two trees.
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            It would be useful to identify renamings or other small changes, like only
         
     | 
| 
      
 39 
     | 
    
         
            +
            changes in comments that does not affect the file and possibly be ignored for
         
     | 
| 
      
 40 
     | 
    
         
            +
            some operations like run or not run tests.
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            ## Transition synapses
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
            Following the previous idea, it would be great if we can understand the
         
     | 
| 
      
 45 
     | 
    
         
            +
            transition synapses and make it easily available to catch up with previous
         
     | 
| 
      
 46 
     | 
    
         
            +
            learnings.
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            https://github.com/jonatas/chewy-diff/blob/master/lib/chewy/diff.rb
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
            This example, shows adds and removals from specific node targets between two
         
     | 
| 
      
 51 
     | 
    
         
            +
            different files.
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
            If we start tracking AST transition synapses and associating with "Fixes" or
         
     | 
| 
      
 54 
     | 
    
         
            +
            "Reverts" we can predict introduction of new bugs by inpecting if the
         
     | 
| 
      
 55 
     | 
    
         
            +
            introduction of new patterns that can be possibly reverted or improved.
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
            ## Fast Rewriter with pure strings
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
            As the AST rewriter adopts a custom block that needs to implement ruby code,
         
     | 
| 
      
 60 
     | 
    
         
            +
            we can expand the a query language for rewriting files without need to take the
         
     | 
| 
      
 61 
     | 
    
         
            +
            custom Ruby block.
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
            Example:
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 66 
     | 
    
         
            +
            Fast.gsub_expression('remove(@expression)') # (node) => { remove(node.location.expression) }
         
     | 
| 
      
 67 
     | 
    
         
            +
            ```
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
            And later we can bind it in the command line to allow implement custom
         
     | 
| 
      
 70 
     | 
    
         
            +
            replacements without need to write a ruby file.
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
            ```
         
     | 
| 
      
 73 
     | 
    
         
            +
            fast (def my_target_method) lib spec --rewrite "remove(@expression)"
         
     | 
| 
      
 74 
     | 
    
         
            +
            ```
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
            or
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
            ```
         
     | 
| 
      
 79 
     | 
    
         
            +
            fast (def my_target_method) lib spec --rewrite "replace(@name, 'renamed_method')"
         
     | 
| 
      
 80 
     | 
    
         
            +
            ```
         
     | 
    
        data/docs/index.md
    CHANGED
    
    | 
         @@ -269,6 +269,11 @@ If you use captures, it returns the node and the captures respectively: 
     | 
|
| 
       269 
269 
     | 
    
         
             
            Fast.search('(int $_)', Fast.ast('a = 1')) # => [s(:int, 1), 1]
         
     | 
| 
       270 
270 
     | 
    
         
             
            ```
         
     | 
| 
       271 
271 
     | 
    
         | 
| 
      
 272 
     | 
    
         
            +
            You can also bind external parameters in the search using extra arguments:
         
     | 
| 
      
 273 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 274 
     | 
    
         
            +
                Fast.search('(int %1)', Fast.ast('a = 1'), 1) # => [s(:int, 1)]
         
     | 
| 
      
 275 
     | 
    
         
            +
            ```
         
     | 
| 
      
 276 
     | 
    
         
            +
             
     | 
| 
       272 
277 
     | 
    
         
             
            ## capture
         
     | 
| 
       273 
278 
     | 
    
         | 
| 
       274 
279 
     | 
    
         
             
            To pick just the captures and ignore the nodes, use `Fast.capture`:
         
     | 
    
        data/docs/research.md
    ADDED
    
    | 
         @@ -0,0 +1,93 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
             
     | 
| 
      
 2 
     | 
    
         
            +
            # Research
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            I love to research about codebase as data and prototyping ideas several times
         
     | 
| 
      
 5 
     | 
    
         
            +
            doesn't fit in simple [shortcuts](/shortcuts).
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            Here is my first research that worth sharing:
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            ## Combining Runtime metadata with AST complex searches
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            This example covers how to find RSpec `allow` combined with `and_return` missing
         
     | 
| 
      
 12 
     | 
    
         
            +
            the `with` clause specifying the nested parameters.
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            Here is the [gist](https://gist.github.com/jonatas/c1e580dcb74e20d4f2df4632ceb084ef)
         
     | 
| 
      
 15 
     | 
    
         
            +
            if you want to go straight and run it.
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            Scenario for simple example:
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            Given I have the following class:
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 22 
     | 
    
         
            +
            class Account
         
     | 
| 
      
 23 
     | 
    
         
            +
              def withdraw(value)
         
     | 
| 
      
 24 
     | 
    
         
            +
                if @total >= value
         
     | 
| 
      
 25 
     | 
    
         
            +
                  @total -= value
         
     | 
| 
      
 26 
     | 
    
         
            +
                  :ok
         
     | 
| 
      
 27 
     | 
    
         
            +
                else
         
     | 
| 
      
 28 
     | 
    
         
            +
                  :not_allowed
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
            end
         
     | 
| 
      
 32 
     | 
    
         
            +
            ```
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            And I'm testing it with `allow` and some possibilities:
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 37 
     | 
    
         
            +
            # bad
         
     | 
| 
      
 38 
     | 
    
         
            +
            allow(Account).to receive(:withdraw).and_return(:ok)
         
     | 
| 
      
 39 
     | 
    
         
            +
            # good
         
     | 
| 
      
 40 
     | 
    
         
            +
            allow(Account).to receive(:withdraw).with(100).and_return(:ok)
         
     | 
| 
      
 41 
     | 
    
         
            +
            ```
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            **Objective:** find all bad cases of **any** class that does not respect the method
         
     | 
| 
      
 44 
     | 
    
         
            +
            parameters signature.
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
            First, let's understand the method signature of a method:
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 49 
     | 
    
         
            +
            Account.instance_method(:withdraw).parameters
         
     | 
| 
      
 50 
     | 
    
         
            +
            # => [[:req, :value]]
         
     | 
| 
      
 51 
     | 
    
         
            +
            ```
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
            Now, we can build a small script to use the node pattern to match the proper
         
     | 
| 
      
 54 
     | 
    
         
            +
            specs that are using such pattern and later visit their method signatures.
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 58 
     | 
    
         
            +
            Fast.class_eval do
         
     | 
| 
      
 59 
     | 
    
         
            +
              # Captures class and method name when find syntax like:
         
     | 
| 
      
 60 
     | 
    
         
            +
              # `allow(...).to receive(...)` that does not end with `.with(...)`
         
     | 
| 
      
 61 
     | 
    
         
            +
              pattern_with_captures = <<~FAST
         
     | 
| 
      
 62 
     | 
    
         
            +
              (send (send nil allow (const nil $_)) to
         
     | 
| 
      
 63 
     | 
    
         
            +
                (send (send nil receive (sym $_)) !with))
         
     | 
| 
      
 64 
     | 
    
         
            +
              FAST
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
              pattern = expression(pattern_with_captures.tr('$',''))
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
              ruby_files_from('spec').each do |file|
         
     | 
| 
      
 69 
     | 
    
         
            +
                results = search_file(pattern, file) || [] rescue next
         
     | 
| 
      
 70 
     | 
    
         
            +
                results.each do |n|
         
     | 
| 
      
 71 
     | 
    
         
            +
                  clazz, method = capture(n, pattern_with_captures)
         
     | 
| 
      
 72 
     | 
    
         
            +
                  if klazz = Object.const_get(clazz.to_s) rescue nil
         
     | 
| 
      
 73 
     | 
    
         
            +
                    if klazz.respond_to?(method)
         
     | 
| 
      
 74 
     | 
    
         
            +
                      params = klazz.method(method).parameters
         
     | 
| 
      
 75 
     | 
    
         
            +
                      if params.any?{|e|e.first == :req}
         
     | 
| 
      
 76 
     | 
    
         
            +
                        code = n.loc.expression
         
     | 
| 
      
 77 
     | 
    
         
            +
                        range = [code.first_line, code.last_line].uniq.join(",")
         
     | 
| 
      
 78 
     | 
    
         
            +
                        boom_message = "BOOM! #{clazz}.#{method} does not include the REQUIRED parameters!"
         
     | 
| 
      
 79 
     | 
    
         
            +
                        puts boom_message, "#{file}:#{range}", code.source
         
     | 
| 
      
 80 
     | 
    
         
            +
                      end
         
     | 
| 
      
 81 
     | 
    
         
            +
                    end
         
     | 
| 
      
 82 
     | 
    
         
            +
                  end
         
     | 
| 
      
 83 
     | 
    
         
            +
                end
         
     | 
| 
      
 84 
     | 
    
         
            +
              end
         
     | 
| 
      
 85 
     | 
    
         
            +
            end
         
     | 
| 
      
 86 
     | 
    
         
            +
            ```
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
            !!! hint "Preload your environment **before** run the script"
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                Keep in mind that you should run it with your environment preloaded otherwise it
         
     | 
| 
      
 91 
     | 
    
         
            +
                will skip the classes.
         
     | 
| 
      
 92 
     | 
    
         
            +
                You can add elses for `const_get` and `respond_to` and report weird cases if
         
     | 
| 
      
 93 
     | 
    
         
            +
                your environment is not preloading properly.
         
     |