Skip to content

Renaming will fail under certain circumstances #687

@luo2430

Description

@luo2430

Steps to reproduce

  1. Create a new folder and open it with vscode
  2. Create a new file 'a.h' and type in
extern int a;
  1. Create a new file 'a.cpp' and type in
#include "a.h"

int a;
  1. Use a tool (such as cmake) to generate the 'compile_commands.json' file
  2. Execute 'clangd: Restart language server'
  3. Open 'a.h' and then open 'a.cpp' (It's the same in reverse order)
  4. Rename 'int a' and then it will be failed. (If you preview the rename, you will notice that the same place in a file has been modified twice. This problem also occurs when renaming function names or class names)
    image

Description

This issue seems to have come up a long time ago, not a recent update. When renaming failed in the past I always thought it was because the extension wasn't powerful enough until one time I previewed renaming.
I came up with a temporary solution by adding the following code inside the {} of 'middleware' in the 'clangd-context.ts' file.

provideRenameEdits: async (document, position, newName, token, next) => {
  let edits = await next(document, position, newName, token);
  // Since edits doesn't provide a member function to modify it, I had to create a new variable
  let new_edits = new vscode.WorkspaceEdit;
  edits?.entries().map(entry => {
    /* For performance reasons, since the same place is renamed twice,
        the operation is performed only if the number of modifications is even */
    if (entry[1].length % 2 == 0) {
      /* When the file has problems renaming symbols, the modifications are
          listed as "change1, change2, change3, change1, change2, change3". 
          So as long as "entry[1][0].range.isEqual(entry[1][index].range" is true, 
          that means there was a renaming error */
      const index = entry[1].length / 2;
      if (entry[1][0].range.isEqual(entry[1][index].range)) {
        entry[1].splice(index);
      }
    }
    // Insert elements
    new_edits.set(entry[0], entry[1]);
  });
  return new_edits;
}

Logs

V[18:05:14.219] <<< {"id":29,"jsonrpc":"2.0","method":"textDocument/rename","params":{"newName":"ClassName1","position":{"character":10,"line":4},"textDocument":{"uri":"file:///c%3A/Users/24306/Desktop/abcd/main.cpp"}}}

I[18:05:14.219] <-- textDocument/rename(29)
V[18:05:14.220] ASTWorker running Rename on version 1 of c:/Users/24306/Desktop/abcd/main.cpp
I[18:05:14.221] --> reply:textDocument/rename(29) 1 ms
V[18:05:14.221] >>> {"id":29,"jsonrpc":"2.0","result":{"changes":{"file:///C:/Users/24306/Desktop/abcd/main.h":[{"newText":"ClassName1","range":{"end":{"character":15,"line":0},"start":{"character":6,"line":0}}},{"newText":"ClassName1","range":{"end":{"character":13,"line":2},"start":{"character":4,"line":2}}}],"file:///c:/Users/24306/Desktop/abcd/main.cpp":[{"newText":"ClassName1","range":{"end":{"character":13,"line":4},"start":{"character":4,"line":4}}}],"file:///c:/Users/24306/Desktop/abcd/main.h":[{"newText":"ClassName1","range":{"end":{"character":15,"line":0},"start":{"character":6,"line":0}}},{"newText":"ClassName1","range":{"end":{"character":13,"line":2},"start":{"character":4,"line":2}}}]}}}

I[18:05:14.221] --> textDocument/clangd.fileStatus
V[18:05:14.221] >>> {"jsonrpc":"2.0","method":"textDocument/clangd.fileStatus","params":{"state":"idle","uri":"file:///c:/Users/24306/Desktop/abcd/main.cpp"}}

V[18:05:14.279] <<< {"id":30,"jsonrpc":"2.0","method":"textDocument/documentHighlight","params":{"position":{"character":10,"line":4},"textDocument":{"uri":"file:///c%3A/Users/24306/Desktop/abcd/main.cpp"}}}

I[18:05:14.279] <-- textDocument/documentHighlight(30)
V[18:05:14.279] ASTWorker running Highlights on version 1 of c:/Users/24306/Desktop/abcd/main.cpp
I[18:05:14.280] --> reply:textDocument/documentHighlight(30) 0 ms
V[18:05:14.280] >>> {"id":30,"jsonrpc":"2.0","result":[{"kind":1,"range":{"end":{"character":13,"line":4},"start":{"character":4,"line":4}}}]}

I[18:05:14.280] --> textDocument/clangd.fileStatus
V[18:05:14.280] >>> {"jsonrpc":"2.0","method":"textDocument/clangd.fileStatus","params":{"state":"idle","uri":"file:///c:/Users/24306/Desktop/abcd/main.cpp"}}

System information

clangd version: 18.1.7 (git://code.qt.io/clang/llvm-project.git 393c912b8e044eb2a86dd9336f4915525bbc051c)
                Features: windows
                Platform: x86_64-w64-windows-gnu
clangd extension version: v0.1.29
Operating system: Windows 11

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions