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 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | 58x 58x 58x 996x 996x 996x 996x 996x 795351x 279x 279x 279x 279x 795351x 7571x 7571x 7571x 7571x 7571x 24x 7547x 295x 295x 795327x 972x | import jsTokens from "js-tokens";
export interface IgnoreHint {
type: "if" | "else" | "next" | "file";
loc: { start: number; end: number };
}
const IGNORE_PATTERN =
/^\s*(?:istanbul|[cv]8|node:coverage)\s+ignore\s+(if|else|next|file)(?=\W|$)/;
const IGNORE_LINES_PATTERN = /\s*(?:istanbul|[cv]8|node:coverage)\s+ignore\s+(start|stop)(?=\W|$)/;
const EOL_PATTERN = /\r?\n/g;
/**
* Parse ignore hints from **Javascript** code based on AST
* - Most AST parsers don't emit comments in AST like Acorn does, so parse comments manually instead.
*/
export function getIgnoreHints(code: string): IgnoreHint[] {
const ignoreHints: IgnoreHint[] = [];
const tokens = jsTokens(code);
let current = 0;
let previousTokenWasIgnoreHint = false;
for (const token of tokens) {
if (
previousTokenWasIgnoreHint &&
token.type !== "WhiteSpace" &&
token.type !== "LineTerminatorSequence"
) {
// Make the comment end reach all the way to the next node so that
// it's easier to check for ignore hints when inspecting node, kind of like
// leadingComments AST attribute.
const previous = ignoreHints.at(-1);
Eif (previous) {
previous.loc.end = current;
}
previousTokenWasIgnoreHint = false;
}
if (token.type === "SingleLineComment" || token.type === "MultiLineComment") {
const loc = { start: current, end: current + token.value.length };
const comment = token.value
// Start of multiline comment
.replace(/^\/\*\*/, "")
.replace(/^\/\*/, "")
// End of multiline comment
.replace(/\*\*\/$/, "")
.replace(/\*\/$/, "")
// Inline comment
.replace(/^\/\//, "");
const groups = comment.match(IGNORE_PATTERN);
const type = groups?.[1];
if (type === "file") {
return [{ type: "file", loc: { start: 0, end: 0 } }];
}
if (type === "if" || type === "else" || type === "next") {
ignoreHints.push({ type, loc });
previousTokenWasIgnoreHint = true;
}
}
current += token.value.length;
}
return ignoreHints;
}
/**
* Parse ignore start/stop hints from **text file** based on regular expressions
* - Does not understand what a comment is in Javascript (or JSX, Vue, Svelte)
* - Parses source code (JS, TS, Vue, Svelte, anything) based on text search by
* matching for `/* <name> ignore start *\/` pattern - not by looking for real comments
*
* ```js
* /* v8 ignore start *\/
* <!-- /* v8 ignore start *\/ -->
* <SomeFrameworkComment content="/* v8 ignore start *\/">
* ```
*/
export function getIgnoredLines(text?: string): Set<number> {
if (!text) {
return new Set();
}
const ranges: { start: number; stop: number }[] = [];
let lineNumber = 0;
for (const line of text.split(EOL_PATTERN)) {
lineNumber++;
const match = line.match(IGNORE_LINES_PATTERN);
if (match) {
const type = match[1];
if (type === "stop") {
const previous = ranges.at(-1);
// Ignore whole "ignore stop" if no previous start was found
if (previous && previous.stop === Infinity) {
previous.stop = lineNumber;
}
continue;
}
ranges.push({ start: lineNumber, stop: Infinity });
}
}
const ignoredLines = new Set<number>();
for (const range of ranges) {
for (let line = range.start; line <= range.stop; line++) {
ignoredLines.add(line);
if (line >= lineNumber) {
break;
}
}
}
return ignoredLines;
}
|