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

Commit f2a5307

Browse files
elektronikworkshopadiazulay
authored andcommitted
Forceinclude Arduino.h
* Added message to end of each build to inform user how to update the IntelliSense configuration * The magic now searches all identified include paths for the Arduino core include file (aka Arduino.h) and adds it as forced include - most users expect Arduino core functionality to work without having to include this header. Added typed-promisify to dependencies since I made use of it in the new code for better readability. * Conclude is now asynchronous * Updated branch status and added new future task * Bumped cocopa version to 0.0.10
1 parent b7effbc commit f2a5307

File tree

5 files changed

+89
-18
lines changed

5 files changed

+89
-18
lines changed

BRANCHNOTES.md

+7-5
Original file line numberDiff line numberDiff line change
@@ -108,20 +108,19 @@ During merging I found some bugs within those functions - mainly due to the abov
108108
| | :heavy_check_mark: Merging of parsing result and existing file content |
109109
| | :heavy_check_mark: Handling inexistent files and folders |
110110
| | :heavy_check_mark: Write configuration on change only |
111-
| | :white_check_mark: Option to backup old configurations? |
112111
| **Configuration flags** | :heavy_check_mark: Provide global disable flag for IntelliSense auto-config |
113112
| | :heavy_check_mark: Provide project specific override for the global flag - most users will likely use the default setup and disable auto-generation for very specific projects |
114113
| **Unit tests** | :heavy_check_mark: Basic parser (known boards, match/no match)|
115114
| | :white_check_mark: All unit tests in cocopa |
116115
| | :white_check_mark: Test with cpp sketches |
117116
| **General** | :heavy_check_mark: Review and remove previous attempts messing with `c_cpp_properties.json` or IntelliSense (documented in the [General Tasks](#General-Tasks) section) `*` |
118-
| | :white_check_mark: *Auto-run verify when* |
117+
| | :heavy_check_mark: *Auto-run verify when* |
119118
| |     :heavy_check_mark: a) setting a board `*` |
120119
| |     :heavy_check_mark: b) changing the board's configuration `*` |
121120
| |     :heavy_check_mark: c) selecting another sketch `*` |
122-
| |     :white_check_mark: d) workbench initialized and no `c_cpp_properties.json` found |
123-
| |     :white_check_mark: e) Identify other occasions where this applies (usually when adding new libraries) |
124-
| | :white_check_mark: Hint the user to run *Arduino: Rebuild IntelliSense Configuration*? -> Good moment would be after the workbench initialization -> message in arduino channel |
121+
| |     :heavy_check_mark: d) ~~workbench initialized and no `c_cpp_properties.json` found~~ obsolete: when board and board configuration is loaded on start up the analysis is triggered anyways |
122+
| |     :white_check_mark: e) Identify other occasions where this applies (usually when adding new libraries) -- any suggestions? |
123+
| | :heavy_check_mark: Hint the user to run *Arduino: Rebuild IntelliSense Configuration* -> printing message after each build (verify, upload, ...) |
125124
| | :heavy_check_mark: Better build management such that regular builds and analyze builds do not interfere (done, 2020-02-19) `*` |
126125
| | :heavy_check_mark: Analyze task queue which fits in the latter (done, 2020-02-19) `*` |
127126
| | :heavy_check_mark: Document configuration settings in [README.md](README.md) |
@@ -214,6 +213,9 @@ I will list every supporter here, thanks!
214213
* When having adding a library folder to the workspace IntelliSense should use the same configuration for it to enable library navigation and code completion.
215214
* Optimization: Abort analysis build as soon as compiler statement has been found
216215
* Non-IDE unit testing - to eliminate dependency injection use ts-mock-imports for instance
216+
* Hardcoded and scattered constants:
217+
* Load package.json and use values from therein instead of hard coding redundant values like shortcuts (like I did for the IntelliSense message in `arduino.ts`)
218+
* Scan code for other hard coded stuff and take appropriate countermeasures
217219

218220
## Non-categorized Notes
219221
### Integrate upstream changes into fork

package-lock.json

+8-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@
604604
},
605605
"dependencies": {
606606
"body-parser": "^1.16.1",
607-
"cocopa": "^0.0.9",
607+
"cocopa": "^0.0.10",
608608
"compare-versions": "^3.4.0",
609609
"eventemitter2": "^4.1.0",
610610
"express": "^4.14.1",
@@ -613,6 +613,7 @@
613613
"impor": "^0.1.1",
614614
"node-usb-native": "^0.0.18",
615615
"properties": "^1.2.1",
616+
"typed-promisify": "^0.4.0",
616617
"uuid": "^3.0.1",
617618
"vscode-extension-telemetry": "0.1.6",
618619
"winreg": "^1.2.3",

src/arduino/arduino.ts

+12-6
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ export class ArduinoApp {
368368

369369
const cleanup = async () => {
370370
if (cocopa) {
371-
cocopa.conclude();
371+
await cocopa.conclude();
372372
}
373373
if (buildMode === BuildMode.Upload || buildMode === BuildMode.UploadProgrammer) {
374374
UsbDetector.getInstance().resumeListening();
@@ -399,15 +399,21 @@ export class ArduinoApp {
399399
stdoutCallback,
400400
).then(async () => {
401401
await cleanup();
402+
if (buildMode !== BuildMode.Analyze) {
403+
const cmd = os.platform() === "darwin"
404+
? "Cmd + Alt + I"
405+
: "Ctrl + Alt + I";
406+
arduinoChannel.info(`To rebuild your IntelliSense configuration run "${cmd}"`);
407+
}
402408
arduinoChannel.end(`${buildMode} sketch '${dc.sketch}'${os.EOL}`);
403409
success = true;
404410
}, async (reason) => {
405411
await cleanup();
406-
const msg = reason.code ?
407-
`Exit with code=${reason.code}` :
408-
reason.message ?
409-
reason.message :
410-
JSON.stringify(reason);
412+
const msg = reason.code
413+
? `Exit with code=${reason.code}`
414+
: reason.message
415+
? reason.message
416+
: JSON.stringify(reason);
411417
arduinoChannel.error(`${buildMode} sketch '${dc.sketch}': ${msg}${os.EOL}`);
412418
});
413419

src/arduino/intellisense.ts

+60-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
// Licensed under the MIT license.
33

44
import * as ccp from "cocopa";
5+
import * as fs from "fs";
56
import * as path from "path";
7+
import * as tp from "typed-promisify";
68

79
import * as constants from "../common/constants";
810
import { arduinoChannel } from "../common/outputChannel";
@@ -13,7 +15,7 @@ import { VscodeSettings } from "./vscodeSettings";
1315

1416
export interface ICoCoPaContext {
1517
callback: (s: string) => void;
16-
conclude: () => void;
18+
conclude: () => Promise<void>;
1719
};
1820

1921
/**
@@ -58,7 +60,7 @@ export function makeCompilerParserContext(dc: DeviceContext): ICoCoPaContext {
5860
const runner = new ccp.Runner(engines);
5961

6062
// Set up the callback to be called after parsing
61-
const _conclude = () => {
63+
const _conclude = async () => {
6264
if (!runner.result) {
6365
arduinoChannel.warning("Failed to generate IntelliSense configuration.");
6466
return;
@@ -67,14 +69,26 @@ export function makeCompilerParserContext(dc: DeviceContext): ICoCoPaContext {
6769
// Normalize compiler and include paths (resolve ".." and ".")
6870
runner.result.normalize();
6971

72+
// Search for Arduino.h in the include paths - we need it for a
73+
// forced include - users expect Arduino symbols to be available
74+
// in main sketch without having to include the header explicitly
75+
const ardHeader = await locateArduinoHeader(runner.result.includes);
76+
const forcedIncludes = ardHeader
77+
? [ ardHeader ]
78+
: undefined;
79+
if (!ardHeader) {
80+
arduinoChannel.warning("Unable to locate \"Arduino.h\" within IntelliSense include paths.");
81+
}
82+
7083
// TODO: check what kind of result we've got: gcc or other architecture:
7184
// and instantiate content accordingly (to be implemented within cocopa)
7285
const content = new ccp.CCppPropertiesContentResult(runner.result,
7386
"Arduino",
7487
ccp.CCppPropertiesISMode.Gcc_X64,
7588
ccp.CCppPropertiesCStandard.C11,
7689
// as of 1.8.11 arduino is on C++11
77-
ccp.CCppPropertiesCppStandard.Cpp11);
90+
ccp.CCppPropertiesCppStandard.Cpp11,
91+
forcedIncludes);
7892
try {
7993
const pPath = path.join(ArduinoWorkspace.rootPath, constants.CPP_CONFIG_FILE);
8094
const prop = new ccp.CCppProperties();
@@ -113,6 +127,49 @@ function makeCompilerParserEngines(dc: DeviceContext) {
113127
return [gccParserEngine];
114128
}
115129

130+
/**
131+
* Search directories recursively for a file.
132+
* @param dir Directory where the search should begin.
133+
* @param what The file we're looking for.
134+
* @returns The path of the directory which contains the file else undefined.
135+
*/
136+
async function findDirContaining(dir: string, what: string): Promise<string | undefined> {
137+
const readdir = tp.promisify(fs.readdir);
138+
const fsstat = tp.promisify(fs.stat);
139+
140+
for (const entry of await readdir(dir)) {
141+
const p = path.join(dir, entry);
142+
const s = await fsstat(p);
143+
if (s.isDirectory()) {
144+
const result = await findDirContaining(p, what);
145+
if (result) {
146+
return result;
147+
}
148+
} else if (entry === what) {
149+
return dir;
150+
}
151+
}
152+
return undefined;
153+
};
154+
155+
/**
156+
* Tries to find the main Arduino header (i.e. Arduino.h) in the given include
157+
* paths.
158+
* @param includes Array containing all include paths in which we should look
159+
* for Arduino.h
160+
* @returns The full path of the main Arduino header.
161+
*/
162+
async function locateArduinoHeader(includes: string[]) {
163+
const header = "Arduino.h";
164+
for (const i of includes) {
165+
const result = await findDirContaining(i, header);
166+
if (result) {
167+
return path.join(result, header);
168+
}
169+
}
170+
return undefined;
171+
}
172+
116173
/**
117174
* Possible states of AnalysisManager's state machine.
118175
*/

0 commit comments

Comments
 (0)