Skip to content

Structural Search Replace #2267

@matklad

Description

@matklad

#2266 added a new function for Source:

impl<T> Source<T> {
    pub fn new(file_id: HirFileId, ast: T) -> Source<T> {
        Source { file_id, ast }
    }
}

The goal of this issue is to replace all Source { file_id: foo, ast: bar } literals with more succinct calls to Source::new(foo, bar).

However, we are not going to do this in a boring manual way. Instead, what we'll do is we provide an IDE feature, such that you enter

Source { file_id: $file_id:expr, ast: $ast:expr }  ==>> Source::new($file_id, $ast)

and IDE uses this template to fix all files.

This is called SSR.

Here's the rough plan:

  • add Analysis::structural_search_replace(&self, template: &str) -> Cancelable<Result<SourceChange, SomeError>> method: this will be the main entry point.
  • add ssr module to ra_ide_api crate
  • implement template parsing:
    • split the input request on ==>> into pattern and template (separator is bikesheddable)
    • using text search (regex or, better in this case I think, hand-rolled) to replace $ident:fragment with __search_pattern_ident
    • parse both pattern and template as expression (we might add more types in the future, but let's start with expressions)
    • Group all the info above into some nice data structures, like SsrPattern and SsrTemplate
  • implement search in a single file with SsrPattern. Note that this should do only searching, replacement should be separate. Again, this should return a structured result like SsrMatches.
    • searching means visiting files's AST, and matching each node against pattern. Matching should ignore whitespace difference. Bonus points if it an ignore insignificant order difference (like the order of fields in the struct literal)
  • Implement replacement in a single file, which takes a file, an SsrMatches, an SsrTemplate, and produces a `TextEdit
  • Implement the driver, which visits all files in the current project and builds a SourceEdit
  • Expose this functionality via ra_cli
  • Expose this functionality via custom LSP request
  • Write typescript code to use this request from VS Code (there's an API to ask user for a string, that should be enough. Alternatively, allow user to write template in a file, and get it from selection )

EDIT: Zulip thread for discussion: https://rust-lang.zulipchat.com/#narrow/stream/185405-t-compiler.2Fwg-rls-2.2E0/topic/Structural.20Search.20Replace

Metadata

Metadata

Assignees

No one assigned

    Labels

    E-hardE-has-instructionsIssue has some instructions and pointers to code to get startedfunA technically challenging issue with high impact

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions