From af86d5acc960d4c09586a04f423206e73cc6288e Mon Sep 17 00:00:00 2001 From: eyza Date: Fri, 25 Oct 2024 20:06:44 +0200 Subject: [PATCH] When GSC file is replaced by another GSC file in multi-root workspace because of the same game path (e.g. maps\mp\gametypes\script), the code in text editor is shown as semi-transparent (unreachable code) --- src/GscFiles.ts | 27 ++++++++++++++++++++++++--- src/GscSemanticTokensProvider.ts | 13 +++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/GscFiles.ts b/src/GscFiles.ts index 3e9472f..310cb70 100644 --- a/src/GscFiles.ts +++ b/src/GscFiles.ts @@ -427,6 +427,7 @@ export class GscFiles { * Get referenced file in specified file. It tries to find the file in all possible locations where it can be found (workspace folder and included workspace folders). * @param gscFile GSC file where the reference is located. * @param referencedFilePath Path in GSC file format (e.g. scripts\scriptName) + * @param includeReversedReferences If true, it also checks if the file is replaced by another file in another workspace folder. * @returns The reference status and the parsed file data if found */ public static getReferencedFileForFile(gscFile: GscFile, referencedFilePath: string, includeReversedReferences: boolean = false): GscFileAndReferenceState { @@ -473,12 +474,32 @@ export class GscFiles { * Converts the file URI into game path considering game root folder (eg. "c:/mod/src/maps/mp/script.gsc" -> "maps\mp\script.gsc") */ public static getGamePathFromGscFile(gscFile: GscFile): string { + if (gscFile.workspaceFolder && gscFile.config.rootFolder) { - const path = gscFile.uri.fsPath.replace(gscFile.config.rootFolder.uri.fsPath, "").replace(/\//g, '\\'); - return path; + var path = gscFile.uri.fsPath.replace(gscFile.config.rootFolder.uri.fsPath, "").replace(/\//g, '\\'); } else { - return vscode.workspace.asRelativePath(gscFile.uri).replace(/\//g, '\\'); + var path = vscode.workspace.asRelativePath(gscFile.uri).replace(/\//g, '\\'); + } + + if (path.startsWith("\\")) { + path = path.substring(1); + } + path = path.replace(/\.gsc/i, ""); + + return path; + } + + /** + * Check if the GSC file is replaced by another file in another workspace folder (reverse reference). + */ + public static isFileReplacedByAnotherFile(gscFile: GscFile): boolean { + + const referencedFiles = this.getReferencedFileForFile(gscFile, gscFile.gamePath, true); + + if (referencedFiles.gscFile !== gscFile) { + return true; } + return false; } diff --git a/src/GscSemanticTokensProvider.ts b/src/GscSemanticTokensProvider.ts index a67a197..ea8f8a9 100644 --- a/src/GscSemanticTokensProvider.ts +++ b/src/GscSemanticTokensProvider.ts @@ -120,6 +120,19 @@ export class GscSemanticTokensProvider implements vscode.DocumentSemanticTokensP } + // Check if file is replaced via game path + + if (GscFiles.isFileReplacedByAnotherFile(gscFile)) { + // Get text editor out of the document + const editor = vscode.window.visibleTextEditors.find(e => e.document.uri.toString() === document.uri.toString()); + if (editor !== undefined) { + // Get full range of the document + const documentRange = new vscode.Range(document.positionAt(0), document.positionAt(document.getText().length)); + editor?.setDecorations(vscode.window.createTextEditorDecorationType({opacity: '0.5'}), [documentRange]); + } + } + + walkGroupItems(gscFile.data.root, gscFile.data.root.items, (parentGroup, group) => { /*