Skip to content

Commit 341855a

Browse files
author
Akos Kitta
committed
fix: start the LS with the board specific settings
restart the LS when board settings of the running LS has changed Closes #1029 Signed-off-by: Akos Kitta <[email protected]>
1 parent 197cea2 commit 341855a

File tree

4 files changed

+70
-29
lines changed

4 files changed

+70
-29
lines changed

Diff for: arduino-ide-extension/src/browser/boards/boards-data-store.ts

+10-10
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ export class BoardsDataStore implements FrontendApplicationContribution {
3030
@inject(LocalStorageService)
3131
protected readonly storageService: LocalStorageService;
3232

33-
protected readonly onChangedEmitter = new Emitter<void>();
33+
protected readonly onChangedEmitter = new Emitter<string[]>();
3434

3535
onStart(): void {
3636
this.notificationCenter.onPlatformDidInstall(async ({ item }) => {
37-
let shouldFireChanged = false;
37+
const dataDidChangePerFqbn: string[] = [];
3838
for (const fqbn of item.boards
3939
.map(({ fqbn }) => fqbn)
4040
.filter(notEmpty)
@@ -49,18 +49,18 @@ export class BoardsDataStore implements FrontendApplicationContribution {
4949
data = details.configOptions;
5050
if (data.length) {
5151
await this.storageService.setData(key, data);
52-
shouldFireChanged = true;
52+
dataDidChangePerFqbn.push(fqbn);
5353
}
5454
}
5555
}
5656
}
57-
if (shouldFireChanged) {
58-
this.fireChanged();
57+
if (dataDidChangePerFqbn.length) {
58+
this.fireChanged(...dataDidChangePerFqbn);
5959
}
6060
});
6161
}
6262

63-
get onChanged(): Event<void> {
63+
get onChanged(): Event<string[]> {
6464
return this.onChangedEmitter.event;
6565
}
6666

@@ -116,7 +116,7 @@ export class BoardsDataStore implements FrontendApplicationContribution {
116116
fqbn,
117117
data: { ...data, selectedProgrammer },
118118
});
119-
this.fireChanged();
119+
this.fireChanged(fqbn);
120120
return true;
121121
}
122122

@@ -146,7 +146,7 @@ export class BoardsDataStore implements FrontendApplicationContribution {
146146
return false;
147147
}
148148
await this.setData({ fqbn, data });
149-
this.fireChanged();
149+
this.fireChanged(fqbn);
150150
return true;
151151
}
152152

@@ -190,8 +190,8 @@ export class BoardsDataStore implements FrontendApplicationContribution {
190190
}
191191
}
192192

193-
protected fireChanged(): void {
194-
this.onChangedEmitter.fire();
193+
protected fireChanged(...fqbn: string[]): void {
194+
this.onChangedEmitter.fire(fqbn);
195195
}
196196
}
197197

Diff for: arduino-ide-extension/src/browser/contributions/ino-language.ts

+34-4
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@ import { Mutex } from 'async-mutex';
22
import { inject, injectable } from '@theia/core/shared/inversify';
33
import {
44
ArduinoDaemon,
5+
assertSanitizedFqbn,
56
BoardsService,
67
ExecutableService,
8+
sanitizeFqbn,
79
} from '../../common/protocol';
810
import { HostedPluginEvents } from '../hosted-plugin-events';
911
import { SketchContribution, URI } from './contribution';
1012
import { CurrentSketch } from '../../common/protocol/sketches-service-client-impl';
1113
import { BoardsConfig } from '../boards/boards-config';
1214
import { BoardsServiceProvider } from '../boards/boards-service-provider';
15+
import { BoardsDataStore } from '../boards/boards-data-store';
1316

1417
@injectable()
1518
export class InoLanguage extends SketchContribution {
@@ -28,6 +31,9 @@ export class InoLanguage extends SketchContribution {
2831
@inject(BoardsServiceProvider)
2932
private readonly boardsServiceProvider: BoardsServiceProvider;
3033

34+
@inject(BoardsDataStore)
35+
private readonly boardDataStore: BoardsDataStore;
36+
3137
private languageServerFqbn?: string;
3238
private languageServerStartMutex = new Mutex();
3339

@@ -61,6 +67,23 @@ export class InoLanguage extends SketchContribution {
6167
}
6268
}
6369
);
70+
this.boardDataStore.onChanged((dataChangePerFqbn) => {
71+
if (this.languageServerFqbn) {
72+
const sanitizedFqbn = sanitizeFqbn(this.languageServerFqbn);
73+
if (!sanitizeFqbn) {
74+
throw new Error(
75+
`Failed to sanitize the FQBN of the running language server. FQBN with the board settings was: ${this.languageServerFqbn}`
76+
);
77+
}
78+
const matchingFqbn = dataChangePerFqbn.find(
79+
(fqbn) => sanitizedFqbn === fqbn
80+
);
81+
const { boardsConfig } = this.boardsServiceProvider;
82+
if (matchingFqbn && boardsConfig.selectedBoard?.fqbn === matchingFqbn) {
83+
start(boardsConfig);
84+
}
85+
}
86+
});
6487
start(this.boardsServiceProvider.boardsConfig);
6588
}
6689

@@ -101,11 +124,18 @@ export class InoLanguage extends SketchContribution {
101124
}
102125
return;
103126
}
104-
if (!forceStart && fqbn === this.languageServerFqbn) {
127+
assertSanitizedFqbn(fqbn);
128+
const fqbnWithConfig = await this.boardDataStore.appendConfigToFqbn(fqbn);
129+
if (!fqbnWithConfig) {
130+
throw new Error(
131+
`Failed to append boards config to the FQBN. Original FQBN was: ${fqbn}`
132+
);
133+
}
134+
if (!forceStart && fqbnWithConfig === this.languageServerFqbn) {
105135
// NOOP
106136
return;
107137
}
108-
this.logger.info(`Starting language server: ${fqbn}`);
138+
this.logger.info(`Starting language server: ${fqbnWithConfig}`);
109139
const log = this.preferences.get('arduino.language.log');
110140
const realTimeDiagnostics = this.preferences.get(
111141
'arduino.language.realTimeDiagnostics'
@@ -141,7 +171,7 @@ export class InoLanguage extends SketchContribution {
141171
log: currentSketchPath ? currentSketchPath : log,
142172
cliDaemonInstance: '1',
143173
board: {
144-
fqbn,
174+
fqbn: fqbnWithConfig,
145175
name: name ? `"${name}"` : undefined,
146176
},
147177
realTimeDiagnostics,
@@ -150,7 +180,7 @@ export class InoLanguage extends SketchContribution {
150180
),
151181
]);
152182
} catch (e) {
153-
console.log(`Failed to start language server for ${fqbn}`, e);
183+
console.log(`Failed to start language server. Original FQBN: ${fqbn}`, e);
154184
this.languageServerFqbn = undefined;
155185
} finally {
156186
release();

Diff for: arduino-ide-extension/src/browser/contributions/upload-sketch.ts

+2-15
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { inject, injectable } from '@theia/core/shared/inversify';
22
import { Emitter } from '@theia/core/lib/common/event';
3-
import { CoreService, Port } from '../../common/protocol';
3+
import { CoreService, Port, sanitizeFqbn } from '../../common/protocol';
44
import { ArduinoMenus } from '../menu/arduino-menus';
55
import { ArduinoToolbar } from '../toolbar/arduino-toolbar';
66
import {
@@ -170,7 +170,7 @@ export class UploadSketch extends CoreServiceContribution {
170170
const [fqbn, { selectedProgrammer: programmer }, verify, verbose] =
171171
await Promise.all([
172172
verifyOptions.fqbn, // already decorated FQBN
173-
this.boardsDataStore.getData(this.sanitizeFqbn(verifyOptions.fqbn)),
173+
this.boardsDataStore.getData(sanitizeFqbn(verifyOptions.fqbn)),
174174
this.preferences.get('arduino.upload.verify'),
175175
this.preferences.get('arduino.upload.verbose'),
176176
]);
@@ -207,19 +207,6 @@ export class UploadSketch extends CoreServiceContribution {
207207
}
208208
return port;
209209
}
210-
211-
/**
212-
* Converts the `VENDOR:ARCHITECTURE:BOARD_ID[:MENU_ID=OPTION_ID[,MENU2_ID=OPTION_ID ...]]` FQBN to
213-
* `VENDOR:ARCHITECTURE:BOARD_ID` format.
214-
* See the details of the `{build.fqbn}` entry in the [specs](https://arduino.github.io/arduino-cli/latest/platform-specification/#global-predefined-properties).
215-
*/
216-
private sanitizeFqbn(fqbn: string | undefined): string | undefined {
217-
if (!fqbn) {
218-
return undefined;
219-
}
220-
const [vendor, arch, id] = fqbn.split(':');
221-
return `${vendor}:${arch}:${id}`;
222-
}
223210
}
224211

225212
export namespace UploadSketch {

Diff for: arduino-ide-extension/src/common/protocol/boards-service.ts

+24
Original file line numberDiff line numberDiff line change
@@ -623,3 +623,27 @@ export namespace Board {
623623
}));
624624
}
625625
}
626+
627+
/**
628+
* Throws an error if the `fqbn` argument is not sanitized. A sanitized FQBN has the `VENDOR:ARCHITECTURE:BOARD_ID` construct.
629+
*/
630+
export function assertSanitizedFqbn(fqbn: string): void {
631+
if (fqbn.split(':').length !== 3) {
632+
throw new Error(
633+
`Expected a sanitized FQBN with three segments in the following format: 'VENDOR:ARCHITECTURE:BOARD_ID'. Got ${fqbn} instead.`
634+
);
635+
}
636+
}
637+
638+
/**
639+
* Converts the `VENDOR:ARCHITECTURE:BOARD_ID[:MENU_ID=OPTION_ID[,MENU2_ID=OPTION_ID ...]]` FQBN to
640+
* `VENDOR:ARCHITECTURE:BOARD_ID` format.
641+
* See the details of the `{build.fqbn}` entry in the [specs](https://arduino.github.io/arduino-cli/latest/platform-specification/#global-predefined-properties).
642+
*/
643+
export function sanitizeFqbn(fqbn: string | undefined): string | undefined {
644+
if (!fqbn) {
645+
return undefined;
646+
}
647+
const [vendor, arch, id] = fqbn.split(':');
648+
return `${vendor}:${arch}:${id}`;
649+
}

0 commit comments

Comments
 (0)