Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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