Skip to content
This repository was archived by the owner on Oct 1, 2024. It is now read-only.

Commit fef2db0

Browse files
hlovdaladiazulay
authored andcommitted
Use cocopa and add Analyze build mode
1 parent 0b2b77a commit fef2db0

File tree

2 files changed

+88
-54
lines changed

2 files changed

+88
-54
lines changed

src/arduino/arduino.ts

+27-9
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,19 @@ import { DeviceContext } from "../deviceContext";
1515
import { IArduinoSettings } from "./arduinoSettings";
1616
import { BoardManager } from "./boardManager";
1717
import { ExampleManager } from "./exampleManager";
18+
import { ICoCoPaContext, isCompilerParserEnabled, makeCompilerParserContext } from "./intellisense";
1819
import { LibraryManager } from "./libraryManager";
1920
import { VscodeSettings } from "./vscodeSettings";
2021

2122
import { arduinoChannel } from "../common/outputChannel";
2223
import { ArduinoWorkspace } from "../common/workspace";
2324
import { SerialMonitor } from "../serialmonitor/serialMonitor";
2425
import { UsbDetector } from "../serialmonitor/usbDetector";
25-
import { makeCompilerParserContext } from "./intellisense";
2626
import { ProgrammerManager } from "./programmerManager";
2727

2828
export enum BuildMode {
2929
Verify = "Verifying",
30+
Analyze = "Analyzing",
3031
Upload = "Uploading",
3132
UploadProgrammer = "Uploading (programmer)",
3233
};
@@ -283,6 +284,8 @@ export class ArduinoApp {
283284
public async verify(buildMode: BuildMode, buildDir: string = "") {
284285
const dc = DeviceContext.getInstance();
285286
const args: string[] = [];
287+
let cocopa: ICoCoPaContext;
288+
286289
const boardDescriptor = this.getBoardBuildString();
287290
if (!boardDescriptor) {
288291
return false;
@@ -300,7 +303,17 @@ export class ArduinoApp {
300303
await this.getMainSketch(dc);
301304
}
302305

303-
if (buildMode === BuildMode.Verify) {
306+
if (buildMode === BuildMode.Analyze) {
307+
if (!isCompilerParserEnabled()) {
308+
return false;
309+
}
310+
cocopa = makeCompilerParserContext(dc);
311+
if (!this.useArduinoCli()) {
312+
args.push("--verify", "--verbose");
313+
} else {
314+
args.push("compile", "--verbose", "-b", boardDescriptor);
315+
}
316+
} else {
304317
if (!this.useArduinoCli()) {
305318
args.push("--verify");
306319
} else {
@@ -309,7 +322,7 @@ export class ArduinoApp {
309322
}
310323

311324
const verbose = VscodeSettings.getInstance().logLevel === "verbose";
312-
if (verbose) {
325+
if (buildMode !== BuildMode.Analyze && verbose) {
313326
args.push("--verbose");
314327
}
315328

@@ -344,19 +357,28 @@ export class ArduinoApp {
344357
}
345358

346359
let success = false;
347-
const compilerParserContext = makeCompilerParserContext(dc);
348360

349361
// Push sketch as last argument
350362
args.push(path.join(ArduinoWorkspace.rootPath, dc.sketch));
351363

352364
const cleanup = async () => {
365+
if (cocopa) {
366+
cocopa.conclude();
367+
}
353368
await Promise.resolve();
354369
}
355370

356371
// TODO: Get rid of spawn's channel parameter and just support
357372
// stdout and stderr callbacks
358373
const stdoutCallback = (line: string) => {
359-
arduinoChannel.channel.append(line);
374+
if (cocopa) {
375+
cocopa.callback(line);
376+
if (verbose) {
377+
arduinoChannel.channel.append(line);
378+
}
379+
} else {
380+
arduinoChannel.channel.append(line);
381+
}
360382
}
361383

362384
await util.spawn(
@@ -379,10 +401,6 @@ export class ArduinoApp {
379401
arduinoChannel.error(`${buildMode} sketch '${dc.sketch}': ${msg}${os.EOL}`);
380402
});
381403

382-
if (compilerParserContext.conclude) {
383-
compilerParserContext.conclude();
384-
}
385-
386404
return success;
387405
}
388406

src/arduino/intellisense.ts

+61-45
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,33 @@
11
import * as ccp from "cocopa";
22
import * as path from "path";
3+
34
import * as constants from "../common/constants";
45
import { arduinoChannel } from "../common/outputChannel";
56
import { ArduinoWorkspace } from "../common/workspace";
67
import { DeviceContext } from "../deviceContext";
8+
79
import { VscodeSettings } from "./vscodeSettings";
810

11+
export interface ICoCoPaContext {
12+
callback: (s: string) => void;
13+
conclude: () => void;
14+
};
15+
16+
/**
17+
* Returns true if the combination of global enable/disable and project
18+
* specific override enable the auto-generation of the IntelliSense
19+
* configuration.
20+
*/
21+
export function isCompilerParserEnabled(dc?: DeviceContext) {
22+
if (!dc) {
23+
dc = DeviceContext.getInstance();
24+
}
25+
const globalDisable = VscodeSettings.getInstance().disableIntelliSenseAutoGen;
26+
const projectSetting = dc.disableIntelliSenseAutoGen;
27+
return projectSetting !== "disable" && !globalDisable ||
28+
projectSetting === "enable";
29+
}
30+
931
/**
1032
* Creates a context which is used for compiler command parsing
1133
* during building (verify, upload, ...).
@@ -16,61 +38,55 @@ import { VscodeSettings } from "./vscodeSettings";
1638
*
1739
* @param dc The device context of the caller.
1840
*/
19-
export function makeCompilerParserContext(dc: DeviceContext)
20-
: { callback: (s: string) => void; conclude: () => void; } {
21-
22-
const globalDisable = VscodeSettings.getInstance().disableIntelliSenseAutoGen;
23-
const project = dc.disableIntelliSenseAutoGen;
24-
25-
if (project !== "disable" && !globalDisable ||
26-
project === "enable") {
41+
export function makeCompilerParserContext(dc: DeviceContext): ICoCoPaContext {
2742

28-
const engines = makeCompilerParserEngines(dc);
29-
const runner = new ccp.Runner(engines);
43+
const engines = makeCompilerParserEngines(dc);
44+
const runner = new ccp.Runner(engines);
3045

31-
// set up the function to be called after parsing
32-
const _conclude = () => {
33-
if (!runner.result) {
34-
arduinoChannel.warning("Failed to generate IntelliSense configuration.");
35-
return;
36-
}
37-
const pPath = path.join(ArduinoWorkspace.rootPath, constants.CPP_CONFIG_FILE);
38-
// TODO: check what kind of result we've got: gcc or other architecture:
39-
// and instantiate content accordingly (to be implemented within cocopa)
40-
const content = new ccp.CCppPropertiesContentResult(runner.result,
41-
"Arduino",
42-
ccp.CCppPropertiesISMode.Gcc_X64,
43-
ccp.CCppPropertiesCStandard.C11,
44-
// as of 1.8.11 arduino is on C++11
45-
ccp.CCppPropertiesCppStandard.Cpp11);
46-
try {
47-
const prop = new ccp.CCppProperties();
48-
prop.read(pPath);
49-
prop.merge(content, ccp.CCppPropertiesMergeMode.ReplaceSameNames);
50-
if (prop.write(pPath)) {
51-
arduinoChannel.info("IntelliSense configuration updated.");
52-
} else {
53-
arduinoChannel.info("IntelliSense configuration already up to date.");
54-
}
55-
} catch (e) {
56-
// tslint:disable-next-line: no-console
57-
console.log(e);
46+
// Set up the callback to be called after parsing
47+
const _conclude = () => {
48+
if (!runner.result) {
49+
arduinoChannel.warning("Failed to generate IntelliSense configuration.");
50+
return;
51+
}
52+
const pPath = path.join(ArduinoWorkspace.rootPath, constants.CPP_CONFIG_FILE);
53+
// TODO: check what kind of result we've got: gcc or other architecture:
54+
// and instantiate content accordingly (to be implemented within cocopa)
55+
const content = new ccp.CCppPropertiesContentResult(runner.result,
56+
"Arduino",
57+
ccp.CCppPropertiesISMode.Gcc_X64,
58+
ccp.CCppPropertiesCStandard.C11,
59+
// as of 1.8.11 arduino is on C++11
60+
ccp.CCppPropertiesCppStandard.Cpp11);
61+
try {
62+
const prop = new ccp.CCppProperties();
63+
prop.read(pPath);
64+
prop.merge(content, ccp.CCppPropertiesMergeMode.ReplaceSameNames);
65+
if (prop.write(pPath)) {
66+
arduinoChannel.info("IntelliSense configuration updated.");
67+
} else {
68+
arduinoChannel.info("IntelliSense configuration already up to date.");
5869
}
59-
};
60-
return {
61-
callback: runner.callback(),
62-
conclude: _conclude,
70+
} catch (e) {
71+
const estr = JSON.stringify(e);
72+
arduinoChannel.error(`Failed to read or write IntelliSense configuration: ${estr}`);
6373
}
64-
}
74+
};
6575
return {
66-
callback: undefined,
67-
conclude: undefined,
76+
callback: runner.callback(),
77+
conclude: _conclude,
6878
}
6979
};
7080

7181
/**
82+
* Assembles compiler parser engines which then will be used to find the main
83+
* sketch's compile command and parse the infomation from it required for
84+
* assembling an IntelliSense configuration from it.
85+
*
86+
* It could return multiple engines for different compilers or - if necessary -
87+
* return specialized engines based on the current board architecture.
7288
*
73-
* @param dc
89+
* @param dc Current device context used to generate the engines.
7490
*/
7591
function makeCompilerParserEngines(dc: DeviceContext) {
7692

0 commit comments

Comments
 (0)