Skip to content

Commit 9da9418

Browse files
bors[bot]Jonas Schievink
and
Jonas Schievink
authored
Merge #11861
11861: internal: Add "view file text" command to debug sync issues r=jonas-schievink a=jonas-schievink I saw a file sync bug the other day but didn't know how to further debug it. This command might give a clue as to what's wrong and help debug issues like #4829. bors r+ Co-authored-by: Jonas Schievink <[email protected]>
2 parents 259182b + ec2d023 commit 9da9418

File tree

8 files changed

+89
-1
lines changed

8 files changed

+89
-1
lines changed

crates/rust-analyzer/src/handlers.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,14 @@ pub(crate) fn handle_view_hir(
123123
Ok(res)
124124
}
125125

126+
pub(crate) fn handle_view_file_text(
127+
snap: GlobalStateSnapshot,
128+
params: lsp_types::TextDocumentIdentifier,
129+
) -> Result<String> {
130+
let file_id = from_proto::file_id(&snap, &params.uri)?;
131+
Ok(snap.analysis.file_text(file_id)?.to_string())
132+
}
133+
126134
pub(crate) fn handle_view_item_tree(
127135
snap: GlobalStateSnapshot,
128136
params: lsp_ext::ViewItemTreeParams,

crates/rust-analyzer/src/lsp_ext.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,14 @@ impl Request for ViewHir {
7070
const METHOD: &'static str = "rust-analyzer/viewHir";
7171
}
7272

73+
pub enum ViewFileText {}
74+
75+
impl Request for ViewFileText {
76+
type Params = lsp_types::TextDocumentIdentifier;
77+
type Result = String;
78+
const METHOD: &'static str = "rust-analyzer/viewFileText";
79+
}
80+
7381
#[derive(Deserialize, Serialize, Debug)]
7482
#[serde(rename_all = "camelCase")]
7583
pub struct ViewCrateGraphParams {

crates/rust-analyzer/src/main_loop.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,7 @@ impl GlobalState {
590590
.on::<lsp_ext::AnalyzerStatus>(handlers::handle_analyzer_status)
591591
.on::<lsp_ext::SyntaxTree>(handlers::handle_syntax_tree)
592592
.on::<lsp_ext::ViewHir>(handlers::handle_view_hir)
593+
.on::<lsp_ext::ViewFileText>(handlers::handle_view_file_text)
593594
.on::<lsp_ext::ViewCrateGraph>(handlers::handle_view_crate_graph)
594595
.on::<lsp_ext::ViewItemTree>(handlers::handle_view_item_tree)
595596
.on::<lsp_ext::ExpandMacro>(handlers::handle_expand_macro)

docs/dev/lsp-extensions.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!---
2-
lsp_ext.rs hash: 854109e98d02a780
2+
lsp_ext.rs hash: a61de7db4504a4d1
33
44
If you need to change the above hash to make the test pass, please check if you
55
need to adjust this doc as well and ping this issue:
@@ -494,6 +494,17 @@ Primarily for debugging, but very useful for all people working on rust-analyzer
494494
Returns a textual representation of the HIR of the function containing the cursor.
495495
For debugging or when working on rust-analyzer itself.
496496

497+
## View File Text
498+
499+
**Method:** `rust-analyzer/viewFileText`
500+
501+
**Request:** `TextDocumentIdentifier`
502+
503+
**Response:** `string`
504+
505+
Returns the text of a file as seen by the server.
506+
This is for debugging file sync problems.
507+
497508
## View ItemTree
498509

499510
**Method:** `rust-analyzer/viewItemTree`

editors/code/package.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@
104104
"title": "View Hir",
105105
"category": "Rust Analyzer"
106106
},
107+
{
108+
"command": "rust-analyzer.viewFileText",
109+
"title": "View File Text (as seen by the server)",
110+
"category": "Rust Analyzer"
111+
},
107112
{
108113
"command": "rust-analyzer.viewItemTree",
109114
"title": "Debug ItemTree",
@@ -1408,6 +1413,10 @@
14081413
"command": "rust-analyzer.viewHir",
14091414
"when": "inRustProject"
14101415
},
1416+
{
1417+
"command": "rust-analyzer.viewFileText",
1418+
"when": "inRustProject"
1419+
},
14111420
{
14121421
"command": "rust-analyzer.expandMacro",
14131422
"when": "inRustProject"

editors/code/src/commands.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,54 @@ export function viewHir(ctx: Ctx): Cmd {
432432
};
433433
}
434434

435+
export function viewFileText(ctx: Ctx): Cmd {
436+
const tdcp = new class implements vscode.TextDocumentContentProvider {
437+
readonly uri = vscode.Uri.parse('rust-analyzer://viewFileText/file.rs');
438+
readonly eventEmitter = new vscode.EventEmitter<vscode.Uri>();
439+
constructor() {
440+
vscode.workspace.onDidChangeTextDocument(this.onDidChangeTextDocument, this, ctx.subscriptions);
441+
vscode.window.onDidChangeActiveTextEditor(this.onDidChangeActiveTextEditor, this, ctx.subscriptions);
442+
}
443+
444+
private onDidChangeTextDocument(event: vscode.TextDocumentChangeEvent) {
445+
if (isRustDocument(event.document)) {
446+
// We need to order this after language server updates, but there's no API for that.
447+
// Hence, good old sleep().
448+
void sleep(10).then(() => this.eventEmitter.fire(this.uri));
449+
}
450+
}
451+
private onDidChangeActiveTextEditor(editor: vscode.TextEditor | undefined) {
452+
if (editor && isRustEditor(editor)) {
453+
this.eventEmitter.fire(this.uri);
454+
}
455+
}
456+
457+
provideTextDocumentContent(_uri: vscode.Uri, ct: vscode.CancellationToken): vscode.ProviderResult<string> {
458+
const rustEditor = ctx.activeRustEditor;
459+
const client = ctx.client;
460+
if (!rustEditor || !client) return '';
461+
462+
const params = client.code2ProtocolConverter.asTextDocumentIdentifier(rustEditor.document);
463+
return client.sendRequest(ra.viewFileText, params, ct);
464+
}
465+
466+
get onDidChange(): vscode.Event<vscode.Uri> {
467+
return this.eventEmitter.event;
468+
}
469+
};
470+
471+
ctx.pushCleanup(vscode.workspace.registerTextDocumentContentProvider('rust-analyzer', tdcp));
472+
473+
return async () => {
474+
const document = await vscode.workspace.openTextDocument(tdcp.uri);
475+
tdcp.eventEmitter.fire(tdcp.uri);
476+
void await vscode.window.showTextDocument(document, {
477+
viewColumn: vscode.ViewColumn.Two,
478+
preserveFocus: true
479+
});
480+
};
481+
}
482+
435483
export function viewItemTree(ctx: Ctx): Cmd {
436484
const tdcp = new class implements vscode.TextDocumentContentProvider {
437485
readonly uri = vscode.Uri.parse('rust-analyzer://viewItemTree/itemtree.rs');

editors/code/src/lsp_ext.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ export const syntaxTree = new lc.RequestType<SyntaxTreeParams, string, void>("ru
3636

3737
export const viewHir = new lc.RequestType<lc.TextDocumentPositionParams, string, void>("rust-analyzer/viewHir");
3838

39+
export const viewFileText = new lc.RequestType<lc.TextDocumentIdentifier, string, void>("rust-analyzer/viewFileText");
40+
3941
export interface ViewItemTreeParams {
4042
textDocument: lc.TextDocumentIdentifier;
4143
}

editors/code/src/main.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ async function initCommonContext(context: vscode.ExtensionContext, ctx: Ctx) {
114114
ctx.registerCommand('parentModule', commands.parentModule);
115115
ctx.registerCommand('syntaxTree', commands.syntaxTree);
116116
ctx.registerCommand('viewHir', commands.viewHir);
117+
ctx.registerCommand('viewFileText', commands.viewFileText);
117118
ctx.registerCommand('viewItemTree', commands.viewItemTree);
118119
ctx.registerCommand('viewCrateGraph', commands.viewCrateGraph);
119120
ctx.registerCommand('viewFullCrateGraph', commands.viewFullCrateGraph);

0 commit comments

Comments
 (0)