export function makeCompilerParserContext()

in src/arduino/intellisense.ts [50:129]


export function makeCompilerParserContext(dc: DeviceContext): ICoCoPaContext {

    // TODO: callback for local setting: when IG gen is re-enabled file
    //   analysis trigger. Perhaps for global possible as well?
    if (!isCompilerParserEnabled(dc)) {
        return {
            callback: undefined,
            conclude: async () => {
                arduinoChannel.info("IntelliSense auto-configuration disabled.");
            },
        };
    }

    const engines = makeCompilerParserEngines(dc);
    const runner = new ccp.Runner(engines);

    // Set up the callback to be called after parsing
    const _conclude = async () => {
        if (!runner.result) {
            arduinoChannel.warning("Failed to generate IntelliSense configuration.");
            return;
        }

        // Normalize compiler and include paths (resolve ".." and ".")
        runner.result.normalize();
        // Remove invalid paths
        await runner.result.cleanup();

        // Search for Arduino.h in the include paths - we need it for a
        // forced include - users expect Arduino symbols to be available
        // in main sketch without having to include the header explicitly
        const ardHeader = await runner.result.findFile("Arduino.h");
        const forcedIncludes = ardHeader.length > 0
            ? ardHeader
            : undefined;
        if (!forcedIncludes) {
            arduinoChannel.warning("Unable to locate \"Arduino.h\" within IntelliSense include paths.");
        }

        // The C++ standard is set to the following default value if no compiler flag has been found.
        const content = new ccp.CCppPropertiesContentResult(runner.result,
                                                            constants.C_CPP_PROPERTIES_CONFIG_NAME,
                                                            ccp.CCppPropertiesISMode.Gcc_X64,
                                                            ccp.CCppPropertiesCStandard.C11,
                                                            ccp.CCppPropertiesCppStandard.Cpp11,
                                                            forcedIncludes);

        // The following 4 lines are added to prevent null.d from being created in the workspace
        // directory on MacOS and Linux. This is may be a bug in intelliSense
        const mmdIndex = runner.result.options.findIndex((element) => element === "-MMD");
        if (mmdIndex) {
            runner.result.options.splice(mmdIndex);
        }

        // Add USB Connected marco to defines
        runner.result.defines.push("USBCON")

        try {

            const cmd = os.platform() === "darwin" ? "Cmd" : "Ctrl";
            const help = `To manually rebuild your IntelliSense configuration run "${cmd}+Alt+I"`;
            const pPath = path.join(ArduinoWorkspace.rootPath, constants.CPP_CONFIG_FILE);
            const prop = new ccp.CCppProperties();
            prop.read(pPath);
            prop.merge(content, ccp.CCppPropertiesMergeMode.ReplaceSameNames);
            if (prop.write(pPath)) {
                arduinoChannel.info(`IntelliSense configuration updated. ${help}`);
            } else {
                arduinoChannel.info(`IntelliSense configuration already up to date. ${help}`);
            }
        } catch (e) {
            const estr = JSON.stringify(e);
            arduinoChannel.error(`Failed to read or write IntelliSense configuration: ${estr}`);
        }
    };
    return {
        callback: runner.callback(),
        conclude: _conclude,
    }
}