forked from avajs/ava
-
Notifications
You must be signed in to change notification settings - Fork 0
/
eslint-plugin-helper.js
96 lines (76 loc) · 2.78 KB
/
eslint-plugin-helper.js
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
'use strict';
const v8 = require('v8');
const {Worker} = require('worker_threads');
const {classify, hasExtension, isHelperish, matches, normalizeFileForMatching, normalizePatterns} = require('./lib/globs');
const MAX_DATA_LENGTH_EXCLUSIVE = 100 * 1024; // Allocate 100 KiB to exchange globs.
let data;
let sync;
let worker;
const resolveGlobsSync = (projectDir, overrideExtensions, overrideFiles) => {
if (worker === undefined) {
const dataBuffer = new SharedArrayBuffer(MAX_DATA_LENGTH_EXCLUSIVE);
data = new Uint8Array(dataBuffer);
const syncBuffer = new SharedArrayBuffer(4);
sync = new Int32Array(syncBuffer);
worker = new Worker('./lib/eslint-plugin-helper-worker.js', {
workerData: {
dataBuffer,
syncBuffer,
firstMessage: {projectDir, overrideExtensions, overrideFiles}
}
});
worker.unref();
} else {
worker.postMessage({projectDir, overrideExtensions, overrideFiles});
}
Atomics.wait(sync, 0, 0);
const byteLength = Atomics.exchange(sync, 0, 0);
if (byteLength === MAX_DATA_LENGTH_EXCLUSIVE) {
throw new Error('Globs are over 100 KiB and cannot be resolved');
}
const globsOrError = v8.deserialize(data.slice(0, byteLength));
if (globsOrError instanceof Error) {
throw globsOrError;
}
return globsOrError;
};
const helperCache = new Map();
function load(projectDir, overrides) {
const cacheKey = `${JSON.stringify(overrides)}\n${projectDir}`;
if (helperCache.has(cacheKey)) {
return helperCache.get(cacheKey);
}
let helperPatterns = [];
if (overrides && overrides.helpers !== undefined) {
if (!Array.isArray(overrides.helpers) || overrides.helpers.length === 0) {
throw new Error('The ’helpers’ override must be an array containing glob patterns.');
}
helperPatterns = normalizePatterns(overrides.helpers);
}
const globs = resolveGlobsSync(projectDir, overrides && overrides.extensions, overrides && overrides.files);
const classifyForESLint = file => {
const {isTest} = classify(file, globs);
let isHelper = false;
if (!isTest && hasExtension(globs.extensions, file)) {
file = normalizeFileForMatching(projectDir, file);
isHelper = isHelperish(file) || (helperPatterns.length > 0 && matches(file, helperPatterns));
}
return {isHelper, isTest};
};
const helper = Object.freeze({
classifyFile: classifyForESLint,
classifyImport: importPath => {
if (hasExtension(globs.extensions, importPath)) {
// The importPath has one of the test file extensions: we can classify
// it directly.
return classifyForESLint(importPath);
}
// Add the first extension. If multiple extensions are available, assume
// patterns are not biased to any particular extension.
return classifyForESLint(`${importPath}.${globs.extensions[0]}`);
}
});
helperCache.set(cacheKey, helper);
return helper;
}
exports.load = load;