Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | 6454x 6454x 6454x 6454x 6780x 341x 15x 326x 326x 326x 326x 165x 326x 6454x 6454x | /**
* TransitiveEnumCollector
* Issue #588: extracted from Transpiler; pass 1.4 Resolve's since #1472.
*
* Collects symbol information from transitively included .cnx files.
* This enables proper enum prefixing when enums are defined in deeply
* nested includes (A includes B, B includes C with enum).
*/
import ICodeGenSymbols from "../../types/ICodeGenSymbols";
import type ITransitiveIncludes from "./types/ITransitiveIncludes";
/**
* Collects symbol information by traversing the include graph.
*
* When generating code, we need to know about enums defined in included files
* so we can properly prefix enum member references. This collector walks the
* include graph starting from a root file and gathers symbol info from all
* transitively included .cnx files.
*/
class TransitiveEnumCollector {
/**
* Collect symbol info from every file `filePath` transitively includes.
*
* #1435: the closure is taken over the include graph discovery resolved, and
* over nothing else. There were two entry points here, and neither read that
* graph: one re-read each file from disk and rebuilt a search path without
* the PlatformIO and Arduino tiers or the injected filesystem, so an include
* discovery had compiled was invisible to its includer (E0426); the other
* started its walk without the root, so a cycle handed the root its own
* symbols as an "external" source. One entry point over one graph cannot
* disagree with discovery, or with itself.
*
* Depth-first, each file before its includes, each file once. The root is
* visited first and is never a source of its own view.
*
* @param filePath - The root file to start collecting from
* @param includesByFile - Each file's direct includes, as discovery resolved
* them. A file with no entry includes nothing.
* @param symbolInfoByFile - Map of file paths to their symbol info
* @returns the closure's `ICodeGenSymbols`, and every file it visited
*/
static collect(
filePath: string,
includesByFile: ReadonlyMap<string, ReadonlyArray<{ path: string }>>,
symbolInfoByFile: ReadonlyMap<string, ICodeGenSymbols>,
): ITransitiveIncludes {
const sources: ICodeGenSymbols[] = [];
const paths: string[] = [];
const visited = new Set<string>([filePath]);
const visit = (from: string): void => {
for (const include of includesByFile.get(from) ?? []) {
if (visited.has(include.path)) {
continue;
}
visited.add(include.path);
paths.push(include.path);
const externalInfo = symbolInfoByFile.get(include.path);
if (externalInfo) {
sources.push(externalInfo);
}
visit(include.path);
}
};
visit(filePath);
return { sources, paths };
}
}
export default TransitiveEnumCollector;
|