diff --git a/server/src/lfortran-accessors.ts b/server/src/lfortran-accessors.ts index 99bd2f4..d74c652 100644 --- a/server/src/lfortran-accessors.ts +++ b/server/src/lfortran-accessors.ts @@ -33,12 +33,19 @@ import { import shellescape from 'shell-escape'; +const RE_FILE_URI: RegExp = /^file:(?:\/\/)?/; + /** * Accessor interface for interacting with LFortran. Possible implementations * include a CLI accessor and service accessor. */ export interface LFortranAccessor { + resolve(uri: string, + filename: string, + flags: string[], + resolved?: Map): string; + version(settings: LFortranSettings): Promise; /** @@ -299,12 +306,21 @@ export class LFortranCLIAccessor implements LFortranAccessor { return output; } - resolve(filename: string, flags: string[], resolved?: Map): string { + resolve(uri: string, + filename: string, + flags: string[], + resolved?: Map): string { const fnid: string = "resolve"; const start: number = performance.now(); let filePath: string = filename; + if (filePath === this.tmpFile.name) { + filePath = uri; + } + + filePath = filePath.replace(RE_FILE_URI, ""); + if (!fs.existsSync(filePath)) { let resolution: string | undefined = resolved?.get(filePath); if (resolution === undefined) { @@ -331,8 +347,12 @@ export class LFortranCLIAccessor implements LFortranAccessor { // if file name is `b.f90` then it will be replaced with `$(pwd)/b.f90` // if file name is `a/b.f90` then it will be replaced with `$(pwd)/a/b.f90` - + // ----------------------------------------------------------------------- + // TODO: Collect an example that demonstrates the need for this resolution + // that does not work with `fs.realpathSync`, above. + // ----------------------------------------------------------------------- const newFilePath: string = path.resolve(filePath); + if (this.logger.isBenchmarkOrTraceEnabled()) { this.logBenchmarkAndTrace( fnid, start, @@ -374,7 +394,7 @@ export class LFortranCLIAccessor implements LFortranAccessor { for (let i = 0, k = symbols.length; i < k; i++) { const symbol: Record = symbols[i]; const symbolPath: string = - this.resolve(symbol.filename, settings.compiler.flags, resolved); + this.resolve(uri, symbol.filename, settings.compiler.flags, resolved); const location: Location = symbol.location; // location.uri = uri; @@ -428,8 +448,8 @@ export class LFortranCLIAccessor implements LFortranAccessor { const results: Record[] = JSON.parse(stdout); for (let i = 0, k = results.length; i < k; i++) { const result: Record = results[i]; - let symbolPath: string = - this.resolve(result.filename, settings.compiler.flags); + const symbolPath: string = + this.resolve(uri, result.filename, settings.compiler.flags); const location = result.location; @@ -443,9 +463,6 @@ export class LFortranCLIAccessor implements LFortranAccessor { end.line--; end.character--; - if (symbolPath.endsWith(".tmp")) { - symbolPath = uri; - } definitions.push({ targetUri: symbolPath, targetRange: range, diff --git a/server/src/lfortran-language-server.ts b/server/src/lfortran-language-server.ts index 126d3fd..0cbf80b 100644 --- a/server/src/lfortran-language-server.ts +++ b/server/src/lfortran-language-server.ts @@ -5,8 +5,6 @@ import fs from 'fs'; -import path from 'path'; - import { CompletionItem, CompletionItemKind, @@ -260,29 +258,8 @@ export class LFortranLanguageServer { const document = this.documents.get(uri); let text = document?.getText(); if (text === undefined) { - let filePath: string = uri; - if (filePath.startsWith("file://")) { - filePath = filePath.substring(7); - } - if (!fs.existsSync(filePath)) { - let resolution: string | undefined = resolved?.get(filePath); - if (resolution === undefined) { - for (const flag of this.settings.compiler.flags) { - if (flag.startsWith("-I")) { - const includeDir = flag.substring(2); - resolution = path.join(includeDir, filePath); - if (fs.existsSync(resolution)) { - resolution = fs.realpathSync(resolution); - resolved?.set(filename, resolution); - filePath = resolution; - break; - } - } - } - } else { - filePath = resolution; - } - } + const filePath: string = + this.lfortran.resolve(uri, uri, this.settings.compiler.flags, resolved); if (fs.existsSync(filePath)) { let entry = this.fileCache.get(filePath); const stats = fs.statSync(filePath);