Skip to content

Commit 016a28a

Browse files
SirR4TBethGriggs
authored andcommitted
tools: non-Ascii linter for /lib only
Non-ASCII characters in /lib get compiled into the node binary, and may bloat the binary size unnecessarily. A linter rule may help prevent this. PR-URL: #18043 Backport-PR-URL: #19499 Fixes: #11209 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Teddy Katz <teddy.katz@gmail.com>
1 parent 745600a commit 016a28a

File tree

8 files changed

+71
-5
lines changed

8 files changed

+71
-5
lines changed

lib/.eslintrc.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ rules:
66
buffer-constructor: error
77
no-let-in-for-declaration: error
88
lowercase-name-for-primitive: error
9+
non-ascii-character: error

lib/console.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ function createWriteErrorHandler(stream) {
8181
// If there was an error, it will be emitted on `stream` as
8282
// an `error` event. Adding a `once` listener will keep that error
8383
// from becoming an uncaught exception, but since the handler is
84-
// removed after the event, non-console.* writes wont be affected.
84+
// removed after the event, non-console.* writes won't be affected.
8585
// we are only adding noop if there is no one else listening for 'error'
8686
if (stream.listenerCount('error') === 0) {
8787
stream.on('error', noop);
@@ -114,7 +114,7 @@ function write(ignoreErrors, stream, string, errorhandler, groupIndent) {
114114
// even in edge cases such as low stack space.
115115
if (e.message === 'Maximum call stack size exceeded')
116116
throw e;
117-
// Sorry, theres no proper way to pass along the error here.
117+
// Sorry, there's no proper way to pass along the error here.
118118
} finally {
119119
stream.removeListener('error', noop);
120120
}

lib/internal/http2/core.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1537,7 +1537,7 @@ function processRespondWithFD(fd, headers, offset = 0, length = -1,
15371537
return;
15381538
}
15391539
// exact length of the file doesn't matter here, since the
1540-
// stream is closing anyway just use 1 to signify that
1540+
// stream is closing anyway - just use 1 to signify that
15411541
// a write does exist
15421542
trackWriteState(this, 1);
15431543
}

lib/internal/test/unicode.js

+2
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@
33
// This module exists entirely for regression testing purposes.
44
// See `test/parallel/test-internal-unicode.js`.
55

6+
/* eslint-disable non-ascii-character */
67
module.exports = '✓';
8+
/* eslint-enable non-ascii-character */

lib/stream.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ try {
4545
try {
4646
Stream._isUint8Array = process.binding('util').isUint8Array;
4747
} catch (e) {
48-
// This throws for Node < 4.2.0 because theres no util binding and
48+
// This throws for Node < 4.2.0 because there's no util binding and
4949
// returns undefined for Node < 7.4.0.
5050
}
5151
}

lib/timers.js

+2
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ const TIMEOUT_MAX = 2147483647; // 2^31-1
8989
// TimerWrap C++ handle, which makes the call after the duration to process the
9090
// list it is attached to.
9191
//
92+
/* eslint-disable non-ascii-character */
9293
//
9394
// ╔════ > Object Map
9495
// ║
@@ -110,6 +111,7 @@ const TIMEOUT_MAX = 2147483647; // 2^31-1
110111
// ║
111112
// ╚════ > Linked List
112113
//
114+
/* eslint-enable non-ascii-character */
113115
//
114116
// With this, virtually constant-time insertion (append), removal, and timeout
115117
// is possible in the JavaScript layer. Any one list of timers is able to be

lib/zlib.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ Zlib.prototype.flush = function flush(kind, callback) {
339339
this._scheduledFlushFlag = maxFlush(kind, this._scheduledFlushFlag);
340340

341341
// If a callback was passed, always register a new `drain` + flush handler,
342-
// mostly because thats simpler and flush callbacks piling up is a rare
342+
// mostly because that's simpler and flush callbacks piling up is a rare
343343
// thing anyway.
344344
if (!alreadyHadFlushScheduled || callback) {
345345
const drainHandler = () => this.flush(this._scheduledFlushFlag, callback);
+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
* @fileOverview Any non-ASCII characters in lib/ will increase the size
3+
* of the compiled node binary. This linter rule ensures that
4+
* any such character is reported.
5+
* @author Sarat Addepalli <sarat.addepalli@gmail.com>
6+
*/
7+
8+
'use strict';
9+
10+
//------------------------------------------------------------------------------
11+
// Rule Definition
12+
//------------------------------------------------------------------------------
13+
14+
const nonAsciiRegexPattern = /[^\r\n\x20-\x7e]/;
15+
const suggestions = {
16+
'’': '\'',
17+
'‛': '\'',
18+
'‘': '\'',
19+
'“': '"',
20+
'‟': '"',
21+
'”': '"',
22+
'«': '"',
23+
'»': '"',
24+
'—': '-'
25+
};
26+
27+
module.exports = (context) => {
28+
29+
const reportIfError = (node, sourceCode) => {
30+
31+
const matches = sourceCode.text.match(nonAsciiRegexPattern);
32+
33+
if (!matches) return;
34+
35+
const offendingCharacter = matches[0];
36+
const offendingCharacterPosition = matches.index;
37+
const suggestion = suggestions[offendingCharacter];
38+
39+
let message = `Non-ASCII character '${offendingCharacter}' detected.`;
40+
41+
message = suggestion ?
42+
`${message} Consider replacing with: ${suggestion}` :
43+
message;
44+
45+
context.report({
46+
node,
47+
message,
48+
loc: sourceCode.getLocFromIndex(offendingCharacterPosition),
49+
fix: (fixer) => {
50+
return fixer.replaceText(
51+
node,
52+
suggestion ? `${suggestion}` : ''
53+
);
54+
}
55+
});
56+
};
57+
58+
return {
59+
Program: (node) => reportIfError(node, context.getSourceCode())
60+
};
61+
};

0 commit comments

Comments
 (0)