Skip to content

Commit d37c233

Browse files
committed
Adds config option for log path; removes config options for benchmarking and filtering logs since they are no longer needed; passes config options to lfortran when the server is initialized
1 parent fd21699 commit d37c233

File tree

3 files changed

+273
-248
lines changed

3 files changed

+273
-248
lines changed

client/src/extension.ts

Lines changed: 131 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* you may not use this file except in compliance with the License.
99
* You may obtain a copy of the License at
1010
*
11-
* http: // www.apache.org/licenses/LICENSE-2.0
11+
* http: // www.apache.org/licenses/LICENSE-2.0
1212
*
1313
* Unless required by applicable law or agreed to in writing, software
1414
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -25,10 +25,10 @@ import * as vscode from "vscode";
2525
import which from "which";
2626

2727
import {
28-
LanguageClient,
29-
LanguageClientOptions,
30-
ServerOptions,
31-
State,
28+
LanguageClient,
29+
LanguageClientOptions,
30+
ServerOptions,
31+
State,
3232
} from "vscode-languageclient/node";
3333

3434
let client: LanguageClient;
@@ -40,39 +40,41 @@ let logger: vscode.LogOutputChannel
4040
* Called when vscode first activates the extension
4141
*/
4242
export async function activate(context: vscode.ExtensionContext) {
43-
logger = vscode.window.createOutputChannel('LFortran Language Server', {
44-
log: true
45-
});
43+
logger = vscode.window.createOutputChannel('LFortran Language Server', {
44+
log: true
45+
});
4646

47-
logger.info("Extension activated.");
48-
await startLangServer();
47+
logger.info("Extension activated.");
48+
await startLangServer();
4949
}
5050

5151
async function checkPathExistsAndIsExecutable(path: string): Promise<boolean> {
52-
let pathExistsAndIsExecutable: boolean = false;
53-
54-
try {
55-
const stats = await fs.promises.stat(path);
56-
pathExistsAndIsExecutable = stats.isFile() && (stats.mode & 0o111) !== 0;
57-
} catch (err: any) {
58-
if (err.code !== 'ENOENT') {
59-
throw err; // Other errors
52+
let pathExistsAndIsExecutable: boolean = false;
53+
54+
try {
55+
const stats = await fs.promises.stat(path);
56+
pathExistsAndIsExecutable = stats.isFile() && (stats.mode & 0o111) !== 0;
57+
} catch (err: any) {
58+
if (err.code !== 'ENOENT') {
59+
throw err; // Other errors
60+
}
6061
}
61-
}
6262

63-
return pathExistsAndIsExecutable;
63+
return pathExistsAndIsExecutable;
6464
}
6565

66-
async function getLFortranPath(): Promise<string | null | undefined> {
67-
const compilerSettings =
68-
vscode.workspace.getConfiguration("LFortranLanguageServer.compiler");
69-
let lfortranPath = compilerSettings.get<string>("lfortranPath");
70-
if (lfortranPath === "lfortran"
71-
|| !(await checkPathExistsAndIsExecutable(lfortranPath))) {
72-
lfortranPath = await which("lfortran", { nothrow: true });
73-
}
74-
logger.info(`lfortranPath = ${lfortranPath}`);
75-
return lfortranPath;
66+
async function getConfig(): Promise<vscode.WorkspaceConfiguration> {
67+
return vscode.workspace.getConfiguration("LFortranLanguageServer");
68+
}
69+
70+
async function getLFortranPath(config: vscode.WorkspaceConfiguration): Promise<string | null | undefined> {
71+
let lfortranPath = config.get<string>("compiler.lfortranPath");
72+
if (lfortranPath === "lfortran"
73+
|| !(await checkPathExistsAndIsExecutable(lfortranPath))) {
74+
lfortranPath = await which("lfortran", { nothrow: true });
75+
}
76+
logger.info(`lfortranPath = ${lfortranPath}`);
77+
return lfortranPath;
7678
}
7779

7880
/**
@@ -84,81 +86,110 @@ async function getLFortranPath(): Promise<string | null | undefined> {
8486
*/
8587
async function startLangServer() {
8688

87-
// Don't interfere if we are already in the process of launching the server.
88-
if (clientStarting) {
89-
logger.info("clientStarting, returning ...");
90-
return;
91-
}
92-
93-
clientStarting = true;
94-
if (client) {
95-
await stopLangServer();
96-
}
97-
98-
const lfortranPath = await getLFortranPath();
99-
if (!lfortranPath) {
100-
logger.warn("lfortran command not found.");
101-
clientStarting = false;
102-
return;
103-
}
104-
105-
const serverOptions: ServerOptions = {
106-
command: lfortranPath,
107-
args: [
108-
"server",
109-
],
110-
options: {
111-
env: process.env,
112-
},
113-
};
114-
115-
const clientOptions: LanguageClientOptions = {
116-
documentSelector: [
117-
{
118-
scheme: "file",
119-
language: "fortran"
120-
},
121-
],
122-
outputChannel: logger,
123-
connectionOptions: {
124-
maxRestartCount: 0 // don't restart on server failure.
125-
},
126-
};
127-
128-
client = new LanguageClient(
129-
"LFortranLanguageServer",
130-
"LFortran Language Server",
131-
serverOptions,
132-
clientOptions);
133-
134-
const promises = [client.start()]
135-
136-
const results = await Promise.allSettled(promises)
137-
clientStarting = false
138-
139-
for (const result of results) {
140-
if (result.status === "rejected") {
141-
logger.error(`There was a error starting the server: ${result.reason}`)
89+
// Don't interfere if we are already in the process of launching the server.
90+
if (clientStarting) {
91+
logger.info("clientStarting, returning ...");
92+
return;
93+
}
94+
95+
clientStarting = true;
96+
if (client) {
97+
await stopLangServer();
98+
}
99+
100+
const config = await getConfig();
101+
const lfortranPath = await getLFortranPath(config);
102+
if (!lfortranPath) {
103+
logger.warn("lfortran command not found.");
104+
clientStarting = false;
105+
return;
106+
}
107+
108+
const prettyPrint: boolean = config.get<boolean>("log.prettyPrint");
109+
const indentSize: number = config.get<number>("log.indentSize");
110+
111+
const serverArgs: string[] = [
112+
"server",
113+
"--open-issue-reporter-on-error", config.get<boolean>("openIssueReporterOnError").toString(),
114+
"--max-number-of-problems", config.get<number>("maxNumberOfProblems").toString(10),
115+
"--trace-server", config.get<string>("trace.server"),
116+
// "--compiler-path", config.get<string>("compiler.path"),
117+
"--compiler-path", lfortranPath,
118+
"--log-path", config.get<string>("log.path"),
119+
"--log-level", config.get<string>("log.level"),
120+
"--log-pretty-print", prettyPrint.toString(),
121+
"--log-indent-size", indentSize.toString(10),
122+
];
123+
124+
const compilerFlags = config.get<string[]>("compiler.flags");
125+
if (compilerFlags.length > 0) {
126+
serverArgs.push("--")
127+
for (const compilerFlag of compilerFlags) {
128+
serverArgs.push(compilerFlag)
129+
}
130+
}
131+
132+
const serverOptions: ServerOptions = {
133+
command: lfortranPath,
134+
args: serverArgs,
135+
options: {
136+
env: process.env,
137+
},
138+
};
139+
140+
if (prettyPrint) {
141+
logger.debug(`Executing lfortran: ${JSON.stringify(serverOptions, undefined, indentSize)}`)
142+
} else {
143+
logger.debug(`Executing lfortran: ${JSON.stringify(serverOptions)}`)
144+
}
145+
146+
const clientOptions: LanguageClientOptions = {
147+
documentSelector: [
148+
{
149+
scheme: "file",
150+
language: "fortran"
151+
},
152+
],
153+
outputChannel: logger,
154+
connectionOptions: {
155+
maxRestartCount: Number.MAX_SAFE_INTEGER
156+
},
157+
};
158+
159+
client = new LanguageClient(
160+
"LFortranLanguageServer",
161+
"LFortran Language Server",
162+
serverOptions,
163+
clientOptions);
164+
165+
const promises = [client.start()]
166+
167+
const results = await Promise.allSettled(promises)
168+
clientStarting = false
169+
170+
for (const result of results) {
171+
if (result.status === "rejected") {
172+
logger.error(`There was a error starting the server: ${result.reason}`)
173+
}
142174
}
143-
}
144175
}
145176

146177
export function deactivate(): Thenable<void> {
147-
return stopLangServer();
178+
return stopLangServer();
148179
}
149180

150181
async function stopLangServer(): Promise<void> {
151-
logger.info("Stopping lang server ...");
152-
if (!client) {
153-
logger.info("No client to stop, returning...");
154-
return
155-
}
156-
157-
if (client.state === State.Running) {
158-
await client.stop();
159-
logger.info("Client stopped ...");
160-
}
161-
162-
client.dispose()
163-
client = undefined
182+
logger.info("Stopping lang server ...");
183+
if (!client) {
184+
logger.info("No client to stop, returning...");
185+
return
186+
}
187+
188+
if (client.state === State.Running) {
189+
await client.stop();
190+
logger.info("Client stopped ...");
191+
}
192+
193+
client.dispose()
194+
client = undefined
164195
}

esbuild.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import * as esbuild from 'esbuild';
33
const watch = process.argv.includes('--watch');
44

55
let production = process.argv.includes('--production');
6-
if (process.env.FORTLS_LFORTRAN_MODE === "debug") {
6+
if (process.env.LFORTRAN_LSP_MODE === "debug") {
77
production = false;
88
}
99

0 commit comments

Comments
 (0)