Skip to content

Commit 40e7979

Browse files
Akos Kittakittaakos
Akos Kitta
authored andcommitted
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 a15a94a commit 40e7979

File tree

4 files changed

+73
-29
lines changed

4 files changed

+73
-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

+37-4
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,18 @@ import { inject, injectable } from '@theia/core/shared/inversify';
33
import { Mutex } from 'async-mutex';
44
import {
55
ArduinoDaemon,
6+
assertSanitizedFqbn,
67
BoardsService,
78
ExecutableService,
9+
sanitizeFqbn,
810
} from '../../common/protocol';
911
import { CurrentSketch } from '../../common/protocol/sketches-service-client-impl';
1012
import { BoardsConfig } from '../boards/boards-config';
1113
import { BoardsServiceProvider } from '../boards/boards-service-provider';
1214
import { HostedPluginEvents } from '../hosted-plugin-events';
1315
import { NotificationCenter } from '../notification-center';
1416
import { SketchContribution, URI } from './contribution';
17+
import { BoardsDataStore } from '../boards/boards-data-store';
1518

1619
@injectable()
1720
export class InoLanguage extends SketchContribution {
@@ -33,6 +36,9 @@ export class InoLanguage extends SketchContribution {
3336
@inject(NotificationCenter)
3437
private readonly notificationCenter: NotificationCenter;
3538

39+
@inject(BoardsDataStore)
40+
private readonly boardDataStore: BoardsDataStore;
41+
3642
private readonly toDispose = new DisposableCollection();
3743
private readonly languageServerStartMutex = new Mutex();
3844
private languageServerFqbn?: string;
@@ -76,6 +82,26 @@ export class InoLanguage extends SketchContribution {
7682
this.notificationCenter.onPlatformDidInstall(() => forceRestart()),
7783
this.notificationCenter.onPlatformDidUninstall(() => forceRestart()),
7884
this.notificationCenter.onDidReinitialize(() => forceRestart()),
85+
this.boardDataStore.onChanged((dataChangePerFqbn) => {
86+
if (this.languageServerFqbn) {
87+
const sanitizedFqbn = sanitizeFqbn(this.languageServerFqbn);
88+
if (!sanitizeFqbn) {
89+
throw new Error(
90+
`Failed to sanitize the FQBN of the running language server. FQBN with the board settings was: ${this.languageServerFqbn}`
91+
);
92+
}
93+
const matchingFqbn = dataChangePerFqbn.find(
94+
(fqbn) => sanitizedFqbn === fqbn
95+
);
96+
const { boardsConfig } = this.boardsServiceProvider;
97+
if (
98+
matchingFqbn &&
99+
boardsConfig.selectedBoard?.fqbn === matchingFqbn
100+
) {
101+
start(boardsConfig);
102+
}
103+
}
104+
}),
79105
]);
80106
start(this.boardsServiceProvider.boardsConfig);
81107
}
@@ -121,11 +147,18 @@ export class InoLanguage extends SketchContribution {
121147
}
122148
return;
123149
}
124-
if (!forceStart && fqbn === this.languageServerFqbn) {
150+
assertSanitizedFqbn(fqbn);
151+
const fqbnWithConfig = await this.boardDataStore.appendConfigToFqbn(fqbn);
152+
if (!fqbnWithConfig) {
153+
throw new Error(
154+
`Failed to append boards config to the FQBN. Original FQBN was: ${fqbn}`
155+
);
156+
}
157+
if (!forceStart && fqbnWithConfig === this.languageServerFqbn) {
125158
// NOOP
126159
return;
127160
}
128-
this.logger.info(`Starting language server: ${fqbn}`);
161+
this.logger.info(`Starting language server: ${fqbnWithConfig}`);
129162
const log = this.preferences.get('arduino.language.log');
130163
const realTimeDiagnostics = this.preferences.get(
131164
'arduino.language.realTimeDiagnostics'
@@ -161,7 +194,7 @@ export class InoLanguage extends SketchContribution {
161194
log: currentSketchPath ? currentSketchPath : log,
162195
cliDaemonInstance: '1',
163196
board: {
164-
fqbn,
197+
fqbn: fqbnWithConfig,
165198
name: name ? `"${name}"` : undefined,
166199
},
167200
realTimeDiagnostics,
@@ -170,7 +203,7 @@ export class InoLanguage extends SketchContribution {
170203
),
171204
]);
172205
} catch (e) {
173-
console.log(`Failed to start language server for ${fqbn}`, e);
206+
console.log(`Failed to start language server. Original FQBN: ${fqbn}`, e);
174207
this.languageServerFqbn = undefined;
175208
} finally {
176209
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)