ast-grep / ast-grep

⚡A CLI tool for code structural search, lint and rewriting. Written in Rust
https://ast-grep.github.io/
MIT License
7.44k stars 169 forks source link

[feature] LSP server integration #1581

Closed RoketFlame closed 4 hours ago

RoketFlame commented 4 hours ago

⭐ Suggestion

It would be really cool to use LSP server methods to write rules (specifically go to definition).

💻 Use Cases

Sometimes you need to write a rule that is contiguous for multiple files. For example animal.py

class Animal:
    name: str

dog.py

class Dog(Animal):
    def bark(self) -> str:
        return "Wuf!"

main.py

from dog import Dog

def zoo(dog: Dog):
    print(dog.bark())

is-named-class.yml

id: named-class
language: python

rule:
  kind: function_definition
  has:
    kind: parameters
    has:
      kind: typed_parameter
      has:
        field: type
        pattern: $TYPE
  inside:
    kind: module
    has:
      kind: class_definition
      all:
        - has:
            field: name
            pattern: $TYPE
        - has:
            field: body
            has:
              kind: expression_statement
              regex: ^name

Ast-grep doesn't match any nodes, but actually it is! (If we look inside the import) If we join all .py files into one and rewrite def zoo(dog: Dog) -> def zoo(dog: Animal) (it's wrong, but it just for demonstration), then ast-grep matches function definition.

There is a way to get data from the whole project through the LSP server, but I don't know how implementable it is. Maybe ast-grep is not suitable for this task, but I don't know any other alternatives that can match ast-grep in terms of speed and functionality.

HerringtonDarkholme commented 4 hours ago

Unfortunately an ast-grep rule will only search one file at a time. The searching will not span multiple files.

ast-grep does not have a plan in near future to support multiple-file-aware rules.