Skip to content
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
2 changes: 1 addition & 1 deletion src/desktop/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,6 @@ export const activate = async (context: ExtensionContext): Promise<CsolutionExte
const compileCommandsGenerator = new CompileCommandsGeneratorImpl(buildTaskProvider, buildTaskDefinitionBuilder);

const solutionConverterImpl = new SolutionConverterImpl(
solutionManager,
eventHub,
configurationProvider,
outputChannelProvider,
Expand Down Expand Up @@ -207,6 +206,7 @@ export const activate = async (context: ExtensionContext): Promise<CsolutionExte
commandsProvider,
messageProvider,
solutionManager,
eventHub,
);

const debugProvider = new DebugLaunchProvider(commandsProvider, solutionManager, configurationProvider);
Expand Down
14 changes: 0 additions & 14 deletions src/solutions/csolution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import { ContextDescriptor, contextDescriptorFromString } from './descriptors/de
import { CmsisSettingsJsonFile } from '../global/cmsis-settings-json-file';
import { CSolutionYamlFile } from './files/csolution-yaml-file';
import { CProjectYamlFile } from './files/cproject-yaml-file';
import { VariablesConfiguration } from '../json-rpc/csolution-rpc-client';
import { CbuildPackFile } from './files/cbuild-pack-file';

export const targetTypeSchema = new Schema({
Expand Down Expand Up @@ -75,12 +74,6 @@ export class CSolution {
cbuildSetYmlFileName = '';
cmsisJsonFile = new CmsisSettingsJsonFile();

// select-compiler
selectCompiler?: string[] = undefined;

// layer configurations
variablesConfigurations?: VariablesConfiguration[] = undefined;

public get projects() {
return this.csolutionYml.projects;
}
Expand Down Expand Up @@ -478,13 +471,6 @@ export class CSolution {
return this.csolutionYml.compilers;
}

public setSelectCompiler(compilers: string[] | undefined) {
this.selectCompiler = compilers;
}

public setVariablesConfigurations(variablesConfigurations: VariablesConfiguration[] | undefined) {
this.variablesConfigurations = variablesConfigurations;
}
};

export function expandPath(path: string, csolution?: CSolution, targetType?: string,): string {
Expand Down
26 changes: 25 additions & 1 deletion src/solutions/solution-converter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ describe('SolutionConverter', () => {
eventHub = new SolutionEventHub();
completedListener = jest.fn();
eventHub.onDidConvertCompleted(completedListener);
jest.spyOn(eventHub, 'fireConfigureSolutionDataReady');

// Initialize convertRequestData with default test values
convertRequestData = {
Expand Down Expand Up @@ -137,7 +138,6 @@ describe('SolutionConverter', () => {
solutionManager.getCsolution.mockReturnValue(mockCSolution);

converter = new SolutionConverterImpl(
solutionManager,
eventHub,
mockConfigurationProvider,
outputChannelProvider,
Expand Down Expand Up @@ -281,6 +281,7 @@ describe('SolutionConverter', () => {

it('run solution convert and discover layers', async () => {
mockCsolutionService.convertSolution.mockResolvedValue({ success: false, undefinedLayers: ['$Board-Layer'] });
mockCsolutionService.discoverLayers.mockResolvedValue({ success: true, configurations: [{ variables: [] }] });
await fireAndWaitForConversion();

expect(mockCsolutionService.discoverLayers).toHaveBeenCalledTimes(1);
Expand All @@ -291,6 +292,29 @@ describe('SolutionConverter', () => {
detection: true
})
);
expect(eventHub.fireConfigureSolutionDataReady).toHaveBeenCalledTimes(1);
expect(eventHub.fireConfigureSolutionDataReady).toHaveBeenCalledWith(
expect.objectContaining({
availableCompilers: [],
availableConfigurations: [{ variables: [] }],
})
);
});

it('emits configure event with compilers when selectCompiler is returned', async () => {
mockCsolutionService.convertSolution.mockResolvedValue({ success: true, selectCompiler: ['GCC', 'AC6'] });
await fireAndWaitForConversion();

expect(completedListener).toHaveBeenCalledWith(
expect.objectContaining({ detection: true })
);
expect(eventHub.fireConfigureSolutionDataReady).toHaveBeenCalledTimes(1);
expect(eventHub.fireConfigureSolutionDataReady).toHaveBeenCalledWith(
expect.objectContaining({
availableCompilers: ['GCC', 'AC6'],
availableConfigurations: undefined,
})
);
});

it('reports discoverLayers failure through toolsOutputMessages', async () => {
Expand Down
28 changes: 15 additions & 13 deletions src/solutions/solution-converter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import * as manifest from '../manifest';
import { ConfigurationProvider } from '../vscode-api/configuration-provider';
import { OutputChannelProvider } from '../vscode-api/output-channel-provider';
import { CmsisToolboxManager } from './cmsis-toolbox';
import { SolutionManager } from './solution-manager';
import { CompileCommandsGenerator } from './intellisense/compile-commands-generator';
import { Mutex } from 'async-mutex';
import * as rpc from '../json-rpc/csolution-rpc-client';
Expand All @@ -39,7 +38,6 @@ export class SolutionConverterImpl implements SolutionConverter {
private data: ConvertRequestData = { solutionPath: '', targetSet: '', updateRte: false, restartRpc: false };

constructor(
private readonly solutionManager: SolutionManager,
private readonly eventHub: SolutionEventHub,
private readonly configProvider: ConfigurationProvider,
private readonly outputChannelProvider: OutputChannelProvider,
Expand Down Expand Up @@ -143,7 +141,8 @@ export class SolutionConverterImpl implements SolutionConverter {

let detection = false;
let convertResult: rpc.ConvertSolutionResult = { success: false };
const csolution = this.solutionManager.getCsolution();
let availableCompilers: string[] = [];
let availableConfigurations: rpc.VariablesConfiguration[] | undefined;
if (!missingPacksResult || missingPacksResult.success) {
// rpc method: ConvertSolution
outputChannel.append('Convert solution... ');
Expand All @@ -160,14 +159,16 @@ export class SolutionConverterImpl implements SolutionConverter {
return;
}

// compilers and variables detection handling: apply select-compiler and discover layer configurations if any
csolution?.setSelectCompiler(convertResult.selectCompiler);
// compilers and variables detection: gather locally and emit configure event
availableCompilers = convertResult.selectCompiler ?? [];
detection = availableCompilers.length > 0;
if (convertResult.undefinedLayers) {
const [discoverLayersDetected, discoverLayersOutput] = await this.checkDiscoverLayers();
detection = discoverLayersDetected;
const result = await this.checkDiscoverLayers();
const discoverLayersOutput = !result.success && result.message ? [`error csolution: ${result.message.trim()}`] : [];
toolsOutputMessages = toolsOutputMessages.concat(discoverLayersOutput);
availableConfigurations = result.configurations;
detection = detection || result.success;
}
detection = detection || !!convertResult.selectCompiler;
}

let logResult = undefined;
Expand Down Expand Up @@ -212,6 +213,10 @@ export class SolutionConverterImpl implements SolutionConverter {
logMessages: logResult,
toolsOutputMessages,
});
// compilers and variables detection handling:
// apply select-compiler and discover layer configurations, reset state otherwise
this.eventHub.fireConfigureSolutionDataReady({ availableCompilers, availableConfigurations });

}

private async printErrorsWarnings(messages?: rpc.LogMessages): Promise<void> {
Expand Down Expand Up @@ -249,9 +254,8 @@ export class SolutionConverterImpl implements SolutionConverter {
return formattedOutput;
}

private async checkDiscoverLayers(): Promise<[boolean, string[]]> {
private async checkDiscoverLayers() {
const outputChannel = this.outputChannelProvider.getOrCreate(manifest.CMSIS_SOLUTION_OUTPUT_CHANNEL);
this.solutionManager.getCsolution()?.setVariablesConfigurations(undefined);
// rpc method: DiscoverLayers
outputChannel.append('Discover Layers... ');
const result = await this.cmsisToolboxManager.runCsolutionRpc(
Expand All @@ -261,9 +265,7 @@ export class SolutionConverterImpl implements SolutionConverter {
activeTarget: this.data?.targetSet ?? '',
}
) as rpc.DiscoverLayersInfo;
this.solutionManager.getCsolution()?.setVariablesConfigurations(result.configurations);
const formattedOutput = !result.success && result.message ? [`error csolution: ${result.message.trim()}`] : [];
return [result.success, formattedOutput];
return result;
}

private getSeverity(messages: rpc.LogMessages, lines?: string[]): Severity {
Expand Down
28 changes: 27 additions & 1 deletion src/solutions/solution-event-hub.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ describe('EventHub', () => {
it('should register emitters with context subscriptions', async () => {
await eventHub.activate(mockContext);

expect(mockContext.subscriptions).toHaveLength(2);
expect(mockContext.subscriptions).toHaveLength(3);
});
});

Expand Down Expand Up @@ -178,4 +178,30 @@ describe('EventHub', () => {
expect(listener).toHaveBeenCalledTimes(2);
});
});

describe('fireConfigureSolutionDataReady', () => {
it('should fire event with compilers and configurations', async () => {
const listener = jest.fn();
eventHub.onDidConfigureSolutionDataReady(listener);

const data = { availableCompilers: ['GCC', 'AC6'], availableConfigurations: undefined };
await eventHub.fireConfigureSolutionDataReady(data);

expect(listener).toHaveBeenCalledTimes(1);
expect(listener).toHaveBeenCalledWith(data);
});

it('should notify multiple listeners', async () => {
const listener1 = jest.fn();
const listener2 = jest.fn();
eventHub.onDidConfigureSolutionDataReady(listener1);
eventHub.onDidConfigureSolutionDataReady(listener2);

const data = { availableCompilers: [], availableConfigurations: [{ variables: [] }] };
await eventHub.fireConfigureSolutionDataReady(data);

expect(listener1).toHaveBeenCalledWith(data);
expect(listener2).toHaveBeenCalledWith(data);
});
});
});
26 changes: 25 additions & 1 deletion src/solutions/solution-event-hub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
import * as vscode from 'vscode';
import { constructor } from '../generic/constructor';
import { LogMessages } from '../json-rpc/csolution-rpc-client';
import { LogMessages, VariablesConfiguration } from '../json-rpc/csolution-rpc-client';
import { Severity } from './constants';

/**
Expand All @@ -29,6 +29,14 @@ export interface ConvertRequestData {
lockAbort?: boolean;
}

/**
* Event data for configure solution readiness
*/
export interface ConfigureSolutionData {
availableCompilers: string[];
availableConfigurations: VariablesConfiguration[] | undefined;
}

/**
* Event data for solution conversion result
*/
Expand Down Expand Up @@ -69,6 +77,14 @@ export interface SolutionEventHub {
* Event fired when solution conversion is completed
*/
readonly onDidConvertCompleted: vscode.Event<ConvertResultData>;
/**
* Fire configure solution data ready event
*/
fireConfigureSolutionDataReady(data: ConfigureSolutionData): Promise<void>;
/**
* Event fired when configure solution data is ready (compilers / layer configurations detected)
*/
readonly onDidConfigureSolutionDataReady: vscode.Event<ConfigureSolutionData>;
}

class SolutionEventHubImpl {
Expand All @@ -79,9 +95,13 @@ class SolutionEventHubImpl {
private readonly convertCompleteEmitter = new vscode.EventEmitter<ConvertResultData>();
public readonly onDidConvertCompleted: vscode.Event<ConvertResultData> = this.convertCompleteEmitter.event;

private readonly configureSolutionDataEmitter = new vscode.EventEmitter<ConfigureSolutionData>();
public readonly onDidConfigureSolutionDataReady: vscode.Event<ConfigureSolutionData> = this.configureSolutionDataEmitter.event;

public async activate(context: vscode.ExtensionContext): Promise<void> {
context.subscriptions.push(this.convertRequestEmitter);
context.subscriptions.push(this.convertCompleteEmitter);
context.subscriptions.push(this.configureSolutionDataEmitter);
}

public async fireConvertRequest(data: ConvertRequestData): Promise<void> {
Expand All @@ -91,6 +111,10 @@ class SolutionEventHubImpl {
public async fireConvertCompleted(data: ConvertResultData): Promise<void> {
this.convertCompleteEmitter.fire(data);
}

public async fireConfigureSolutionDataReady(data: ConfigureSolutionData): Promise<void> {
this.configureSolutionDataEmitter.fire(data);
}
}

export const SolutionEventHub = constructor<typeof SolutionEventHubImpl, SolutionEventHub>(SolutionEventHubImpl);
Expand Down
Loading
Loading