Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: start the LS with the board specific settings #1812

Merged
merged 1 commit into from
Jan 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions arduino-ide-extension/src/browser/boards/boards-data-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ export class BoardsDataStore implements FrontendApplicationContribution {
@inject(LocalStorageService)
protected readonly storageService: LocalStorageService;

protected readonly onChangedEmitter = new Emitter<void>();
protected readonly onChangedEmitter = new Emitter<string[]>();

onStart(): void {
this.notificationCenter.onPlatformDidInstall(async ({ item }) => {
let shouldFireChanged = false;
const dataDidChangePerFqbn: string[] = [];
for (const fqbn of item.boards
.map(({ fqbn }) => fqbn)
.filter(notEmpty)
Expand All @@ -49,18 +49,18 @@ export class BoardsDataStore implements FrontendApplicationContribution {
data = details.configOptions;
if (data.length) {
await this.storageService.setData(key, data);
shouldFireChanged = true;
dataDidChangePerFqbn.push(fqbn);
}
}
}
}
if (shouldFireChanged) {
this.fireChanged();
if (dataDidChangePerFqbn.length) {
this.fireChanged(...dataDidChangePerFqbn);
}
});
}

get onChanged(): Event<void> {
get onChanged(): Event<string[]> {
return this.onChangedEmitter.event;
}

Expand Down Expand Up @@ -116,7 +116,7 @@ export class BoardsDataStore implements FrontendApplicationContribution {
fqbn,
data: { ...data, selectedProgrammer },
});
this.fireChanged();
this.fireChanged(fqbn);
return true;
}

Expand Down Expand Up @@ -146,7 +146,7 @@ export class BoardsDataStore implements FrontendApplicationContribution {
return false;
}
await this.setData({ fqbn, data });
this.fireChanged();
this.fireChanged(fqbn);
return true;
}

Expand Down Expand Up @@ -190,8 +190,8 @@ export class BoardsDataStore implements FrontendApplicationContribution {
}
}

protected fireChanged(): void {
this.onChangedEmitter.fire();
protected fireChanged(...fqbn: string[]): void {
this.onChangedEmitter.fire(fqbn);
}
}

Expand Down
41 changes: 37 additions & 4 deletions arduino-ide-extension/src/browser/contributions/ino-language.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@ import { inject, injectable } from '@theia/core/shared/inversify';
import { Mutex } from 'async-mutex';
import {
ArduinoDaemon,
assertSanitizedFqbn,
BoardsService,
ExecutableService,
sanitizeFqbn,
} from '../../common/protocol';
import { CurrentSketch } from '../../common/protocol/sketches-service-client-impl';
import { BoardsConfig } from '../boards/boards-config';
import { BoardsServiceProvider } from '../boards/boards-service-provider';
import { HostedPluginEvents } from '../hosted-plugin-events';
import { NotificationCenter } from '../notification-center';
import { SketchContribution, URI } from './contribution';
import { BoardsDataStore } from '../boards/boards-data-store';

@injectable()
export class InoLanguage extends SketchContribution {
Expand All @@ -33,6 +36,9 @@ export class InoLanguage extends SketchContribution {
@inject(NotificationCenter)
private readonly notificationCenter: NotificationCenter;

@inject(BoardsDataStore)
private readonly boardDataStore: BoardsDataStore;

private readonly toDispose = new DisposableCollection();
private readonly languageServerStartMutex = new Mutex();
private languageServerFqbn?: string;
Expand Down Expand Up @@ -76,6 +82,26 @@ export class InoLanguage extends SketchContribution {
this.notificationCenter.onPlatformDidInstall(() => forceRestart()),
this.notificationCenter.onPlatformDidUninstall(() => forceRestart()),
this.notificationCenter.onDidReinitialize(() => forceRestart()),
this.boardDataStore.onChanged((dataChangePerFqbn) => {
if (this.languageServerFqbn) {
const sanitizedFqbn = sanitizeFqbn(this.languageServerFqbn);
if (!sanitizeFqbn) {
throw new Error(
`Failed to sanitize the FQBN of the running language server. FQBN with the board settings was: ${this.languageServerFqbn}`
);
}
const matchingFqbn = dataChangePerFqbn.find(
(fqbn) => sanitizedFqbn === fqbn
);
const { boardsConfig } = this.boardsServiceProvider;
if (
matchingFqbn &&
boardsConfig.selectedBoard?.fqbn === matchingFqbn
) {
start(boardsConfig);
}
}
}),
]);
start(this.boardsServiceProvider.boardsConfig);
}
Expand Down Expand Up @@ -121,11 +147,18 @@ export class InoLanguage extends SketchContribution {
}
return;
}
if (!forceStart && fqbn === this.languageServerFqbn) {
assertSanitizedFqbn(fqbn);
const fqbnWithConfig = await this.boardDataStore.appendConfigToFqbn(fqbn);
if (!fqbnWithConfig) {
throw new Error(
`Failed to append boards config to the FQBN. Original FQBN was: ${fqbn}`
);
}
if (!forceStart && fqbnWithConfig === this.languageServerFqbn) {
// NOOP
return;
}
this.logger.info(`Starting language server: ${fqbn}`);
this.logger.info(`Starting language server: ${fqbnWithConfig}`);
const log = this.preferences.get('arduino.language.log');
const realTimeDiagnostics = this.preferences.get(
'arduino.language.realTimeDiagnostics'
Expand Down Expand Up @@ -161,7 +194,7 @@ export class InoLanguage extends SketchContribution {
log: currentSketchPath ? currentSketchPath : log,
cliDaemonInstance: '1',
board: {
fqbn,
fqbn: fqbnWithConfig,
name: name ? `"${name}"` : undefined,
},
realTimeDiagnostics,
Expand All @@ -170,7 +203,7 @@ export class InoLanguage extends SketchContribution {
),
]);
} catch (e) {
console.log(`Failed to start language server for ${fqbn}`, e);
console.log(`Failed to start language server. Original FQBN: ${fqbn}`, e);
this.languageServerFqbn = undefined;
} finally {
release();
Expand Down
17 changes: 2 additions & 15 deletions arduino-ide-extension/src/browser/contributions/upload-sketch.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { inject, injectable } from '@theia/core/shared/inversify';
import { Emitter } from '@theia/core/lib/common/event';
import { CoreService, Port } from '../../common/protocol';
import { CoreService, Port, sanitizeFqbn } from '../../common/protocol';
import { ArduinoMenus } from '../menu/arduino-menus';
import { ArduinoToolbar } from '../toolbar/arduino-toolbar';
import {
Expand Down Expand Up @@ -170,7 +170,7 @@ export class UploadSketch extends CoreServiceContribution {
const [fqbn, { selectedProgrammer: programmer }, verify, verbose] =
await Promise.all([
verifyOptions.fqbn, // already decorated FQBN
this.boardsDataStore.getData(this.sanitizeFqbn(verifyOptions.fqbn)),
this.boardsDataStore.getData(sanitizeFqbn(verifyOptions.fqbn)),
this.preferences.get('arduino.upload.verify'),
this.preferences.get('arduino.upload.verbose'),
]);
Expand Down Expand Up @@ -207,19 +207,6 @@ export class UploadSketch extends CoreServiceContribution {
}
return port;
}

/**
* Converts the `VENDOR:ARCHITECTURE:BOARD_ID[:MENU_ID=OPTION_ID[,MENU2_ID=OPTION_ID ...]]` FQBN to
* `VENDOR:ARCHITECTURE:BOARD_ID` format.
* See the details of the `{build.fqbn}` entry in the [specs](https://arduino.github.io/arduino-cli/latest/platform-specification/#global-predefined-properties).
*/
private sanitizeFqbn(fqbn: string | undefined): string | undefined {
if (!fqbn) {
return undefined;
}
const [vendor, arch, id] = fqbn.split(':');
return `${vendor}:${arch}:${id}`;
}
}

export namespace UploadSketch {
Expand Down
24 changes: 24 additions & 0 deletions arduino-ide-extension/src/common/protocol/boards-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -623,3 +623,27 @@ export namespace Board {
}));
}
}

/**
* Throws an error if the `fqbn` argument is not sanitized. A sanitized FQBN has the `VENDOR:ARCHITECTURE:BOARD_ID` construct.
*/
export function assertSanitizedFqbn(fqbn: string): void {
if (fqbn.split(':').length !== 3) {
throw new Error(
`Expected a sanitized FQBN with three segments in the following format: 'VENDOR:ARCHITECTURE:BOARD_ID'. Got ${fqbn} instead.`
);
}
}

/**
* Converts the `VENDOR:ARCHITECTURE:BOARD_ID[:MENU_ID=OPTION_ID[,MENU2_ID=OPTION_ID ...]]` FQBN to
* `VENDOR:ARCHITECTURE:BOARD_ID` format.
* See the details of the `{build.fqbn}` entry in the [specs](https://arduino.github.io/arduino-cli/latest/platform-specification/#global-predefined-properties).
*/
export function sanitizeFqbn(fqbn: string | undefined): string | undefined {
if (!fqbn) {
return undefined;
}
const [vendor, arch, id] = fqbn.split(':');
return `${vendor}:${arch}:${id}`;
}