Skip to content

Commit d0cc569

Browse files
authored
Merge pull request #12 from jabraham17/fix-bugs
This PR bundles a number of fixes and improves to the extension Features - The extension is no longer reliant on a `CHPL_HOME` value - Can detect and use prefix-based installs - Added better error detection and handling - When CLS/chplcheck has crashed, the status bar now also has a notification to show that these are not working correctly. - Removed the ability to build the tools automatically, this was error prone and only rarely the "correct" course of action - Syntax highlighting for format string specifiers List of fixes - Resolve issues with searching PATH - Fix syntax highlighting for numbers and the count operator Tested locally with two versions of a chapel, a CHPL_HOME build from source and with a prefix install from homebrew [Reviewed by @ShreyasKhandekar]
2 parents 3523c4d + 78cf1c1 commit d0cc569

9 files changed

+273
-136
lines changed

Diff for: DEVELOPER.md

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Documentation for Extension Developers
2+
3+
This document is intended for developers who want to contribute to the Chapel extension for Visual Studio Code.
4+
5+
## Building locally
6+
7+
To build and test the extension locally in debug mode, you can use the Run/Debug tab to launch the extension in a new VSCode window (or press `F5`).
8+
9+
For some debugging purposes, it may be useful to build a local binary of the extension using `vsce`. To do this, run `vsce package -o bin/chapel.vsix` from the root of the repository. This can then be installed in VSCode by selecting "Install from VSIX" in the Extensions view, or by running `code --install-extension bin/chapel.vsix`.

Diff for: README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
- Generic Instantiations: inspect generic code with helpful annotations
2222
- Dead Code: highlight dead code that will never execute
2323

24-
> **_:warning: CAUTION:_**
24+
> **_CAUTION:_**
2525
> These features use a work-in-progress resolver for Chapel called Dyno to further
2626
> inspect your code. To enable these features, use Dyno by setting
2727
> `chapel.chpl-language-server.resolver` to `true`. Enabling the Dyno resolver

Diff for: package-lock.json

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: package.json

+13-8
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,8 @@
8282
],
8383
"commands": [
8484
{
85-
"command": "chapel.findChpl",
86-
"title": "Find Chapel",
87-
"category": "chapel"
88-
},
89-
{
90-
"command": "chapel.buildTools",
91-
"title": "Build chpl-language-server and chplcheck",
85+
"command": "chapel.findChplHome",
86+
"title": "Find CHPL_HOME",
9287
"category": "chapel"
9388
},
9489
{
@@ -114,7 +109,7 @@
114109
"chapel.CHPL_HOME": {
115110
"scope": "window",
116111
"type": "string",
117-
"description": "CHPL_HOME"
112+
"description": "The path to CHPL_HOME. If not provided, the extension may be able to find it automatically if `chpl`, `chplcheck`, and `chpl-language-server` are in PATH."
118113
},
119114
"chapel.CHPL_DEVELOPER": {
120115
"scope": "window",
@@ -128,6 +123,11 @@
128123
"default": true,
129124
"description": "Enable chplcheck"
130125
},
126+
"chapel.chplcheck.path": {
127+
"scope": "window",
128+
"type": "string",
129+
"description": "An explicit path to the chplcheck executable. If not provided, the extension will look for chplcheck in PATH and in CHPL_HOME"
130+
},
131131
"chapel.chplcheck.args": {
132132
"scope": "window",
133133
"type": "array",
@@ -143,6 +143,11 @@
143143
"default": true,
144144
"description": "Enable chpl-language-server"
145145
},
146+
"chapel.chpl-language-server.path": {
147+
"scope": "window",
148+
"type": "string",
149+
"description": "An explicit path to the chpl-language-server executable. If not provided, the extension will look for chpl-language-server in PATH and in CHPL_HOME"
150+
},
146151
"chapel.chpl-language-server.resolver": {
147152
"scope": "window",
148153
"type": "boolean",

Diff for: src/ChapelLanguageClient.ts

+65-29
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,19 @@
1717
* limitations under the License.
1818
*/
1919

20-
import { ToolConfig, getChplDeveloper } from "./configuration";
20+
import { ToolConfig, getChplDeveloper, getChplHome } from "./configuration";
2121
import * as fs from "fs";
2222
import * as vscode from "vscode";
2323
import * as vlc from "vscode-languageclient/node";
24-
import { checkToolPath, checkChplHome, cloneEnv } from "./ChplPaths";
24+
import {
25+
checkToolPath,
26+
checkChplHome,
27+
cloneEnv,
28+
findToolPath,
29+
findPossibleChplHomes,
30+
getWorkspaceFolder,
31+
} from "./ChplPaths";
32+
import { showChplHomeMissingError } from "./extension";
2533
import * as path from "path";
2634

2735
export enum LanguageClientState {
@@ -62,21 +70,19 @@ class ErrorHandlingClient extends vlc.LanguageClient {
6270
}
6371

6472
export abstract class ChapelLanguageClient {
65-
chplhome: string;
6673
protected config_: ToolConfig;
6774
name: string;
6875
state: LanguageClientState;
6976
tool_path: string;
7077
client: ErrorHandlingClient | undefined;
7178
logger: vscode.LogOutputChannel;
79+
statusBarItem: vscode.StatusBarItem;
7280

7381
constructor(
74-
chplhome: string,
7582
config: ToolConfig,
7683
name: string,
7784
logger: vscode.LogOutputChannel
7885
) {
79-
this.chplhome = chplhome;
8086
this.config_ = config;
8187
this.name = name;
8288
this.state = this.config_.enable
@@ -85,16 +91,30 @@ export abstract class ChapelLanguageClient {
8591
this.tool_path = this.getToolPath();
8692
this.client = undefined;
8793
this.logger = logger;
94+
this.statusBarItem = vscode.window.createStatusBarItem(
95+
vscode.StatusBarAlignment.Right,
96+
1000
97+
);
98+
// render the text using vscode codicons
99+
this.statusBarItem.text = `$(error) ${this.name}`;
100+
this.statusBarItem.tooltip = `${this.name} is stopped. Click to restart.`;
101+
this.statusBarItem.color = new vscode.ThemeColor(
102+
"statusBarItem.errorForeground"
103+
);
104+
this.statusBarItem.backgroundColor = new vscode.ThemeColor(
105+
"statusBarItem.errorBackground"
106+
);
107+
this.statusBarItem.command = `${this.name}.restart`;
108+
this.statusBarItem.hide();
88109
}
89110

90111
protected abstract getToolPath(): string;
91112

92113
get config(): ToolConfig {
93114
return this.config_;
94115
}
95-
async resetConfig(chplhome: string, config: ToolConfig) {
116+
async resetConfig(config: ToolConfig) {
96117
await this.stop();
97-
this.chplhome = chplhome;
98118
this.config_ = config;
99119
this.state = this.config_.enable
100120
? LanguageClientState.STOPPED
@@ -105,36 +125,41 @@ export abstract class ChapelLanguageClient {
105125

106126
setErrorState() {
107127
this.state = LanguageClientState.ERRORED;
128+
this.statusBarItem.show();
108129
}
109130

110131
clearError(): void {
111132
this.state = LanguageClientState.STOPPED;
112133
}
113134

114135
private errorFindTools() {
136+
this.setErrorState();
115137
// if invalid chplhome, prompt user to set it
116138
// if missing tool path, warn user that we can't find it, tell them to not override the path or upgrade their chapel version
117139
// otherwise, its likely the tools arent built, so prompt the user to build them
118140

119-
if (checkChplHome(this.chplhome) !== undefined) {
141+
if (this.tool_path === "") {
120142
vscode.window
121143
.showErrorMessage(
122-
"CHPL_HOME is either missing or incorrect, make sure the path is correct",
123-
"Find CHPL_HOME",
144+
`Could not determine the path for ${this.name}. Make sure it is installed. If it is, you may need to set the path manually.`,
145+
`Set ${this.name} Path`,
146+
"Set CHPL_HOME",
124147
"Show Log",
125148
"Ok"
126149
)
127150
.then((value) => {
128-
if (value === "Find CHPL_HOME") {
129-
vscode.commands.executeCommand("chapel.findChpl");
151+
if (value === `Set ${this.name} Path`) {
152+
// TODO
153+
} else if (value === "Set CHPL_HOME") {
154+
vscode.commands.executeCommand("chapel.findChplHome");
130155
} else if (value === "Show Log") {
131156
this.logger.show();
132157
}
133158
});
134159
} else if (checkToolPath(this.tool_path) !== undefined) {
135160
vscode.window
136161
.showErrorMessage(
137-
`${this.name} does not exist in the CHPL_HOME directory, make sure you are using the correct version of Chapel`,
162+
`${this.name} is missing at the path '${this.tool_path}'. If you set the path manually, make sure it is correct. If it is, you may need to upgrade your Chapel version.`,
138163
"Show Log",
139164
"Ok"
140165
)
@@ -146,15 +171,12 @@ export abstract class ChapelLanguageClient {
146171
} else {
147172
vscode.window
148173
.showErrorMessage(
149-
`${this.name} encountered an error, this is likely because ${this.name} is not installed. Double check that ${this.name} is built.`,
150-
"Build Tools",
174+
`${this.name} encountered an error. You may need to rebuild ${this.name}.`,
151175
"Show Log",
152176
"Ok"
153177
)
154178
.then((value) => {
155-
if (value === "Build Tools") {
156-
vscode.commands.executeCommand(`chapel.buildTools`, this.chplhome);
157-
} else if (value === "Show Log") {
179+
if (value === "Show Log") {
158180
this.logger.show();
159181
}
160182
});
@@ -168,16 +190,25 @@ export abstract class ChapelLanguageClient {
168190
return Promise.resolve();
169191
}
170192
this.state = LanguageClientState.STARTING;
193+
this.statusBarItem.hide();
171194
let toolPathError = checkToolPath(this.tool_path);
172195
if (toolPathError !== undefined) {
173196
this.logger.error(toolPathError);
174197
this.errorFindTools();
175-
this.state = LanguageClientState.STOPPED;
176198
return Promise.reject();
177199
}
178200

179201
let env = cloneEnv();
180-
env.CHPL_HOME = this.chplhome;
202+
const chplhome = getChplHome();
203+
if (chplhome !== undefined && chplhome !== "") {
204+
this.logger.info(`Using CHPL_HOME: ${chplhome}`);
205+
const chplHomeError = checkChplHome(chplhome);
206+
if (chplHomeError !== undefined) {
207+
showChplHomeMissingError(chplHomeError);
208+
} else {
209+
env.CHPL_HOME = chplhome;
210+
}
211+
}
181212
env.CHPL_DEVELOPER = getChplDeveloper() ? "1" : "0";
182213

183214
let args = this.alwaysArguments();
@@ -190,7 +221,7 @@ export abstract class ChapelLanguageClient {
190221
command: this.tool_path,
191222
args: args,
192223
options: {
193-
cwd: this.chplhome,
224+
cwd: getWorkspaceFolder()?.uri.fsPath,
194225
env: env,
195226
},
196227
};
@@ -238,7 +269,7 @@ export abstract class ChapelLanguageClient {
238269
}
239270

240271
this.stop().finally(() => {
241-
this.state = LanguageClientState.ERRORED;
272+
this.setErrorState();
242273

243274
vscode.window
244275
.showErrorMessage(
@@ -337,20 +368,25 @@ export abstract class ChapelLanguageClient {
337368

338369
export class ChplCheckClient extends ChapelLanguageClient {
339370
getToolPath(): string {
340-
return path.join(this.chplhome, "tools", "chplcheck", "chplcheck");
371+
const path = findToolPath("chplcheck", getChplHome());
372+
if (path === undefined) {
373+
this.setErrorState();
374+
return "";
375+
}
376+
return path;
341377
}
342378
alwaysArguments(): Array<string> {
343379
return ["--lsp"];
344380
}
345381
}
346382
export class CLSClient extends ChapelLanguageClient {
347383
getToolPath(): string {
348-
return path.join(
349-
this.chplhome,
350-
"tools",
351-
"chpl-language-server",
352-
"chpl-language-server"
353-
);
384+
const path = findToolPath("chpl-language-server", getChplHome());
385+
if (path === undefined) {
386+
this.setErrorState();
387+
return "";
388+
}
389+
return path;
354390
}
355391
alwaysArguments(): Array<string> {
356392
let args = [];

0 commit comments

Comments
 (0)