Skip to content

Commit 6fee06d

Browse files
committed
Introduce and adopt const enum CharCode for performance & readability
1 parent b3e9288 commit 6fee06d

9 files changed

Lines changed: 114 additions & 64 deletions

File tree

src/vs/base/browser/dom.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {isObject} from 'vs/base/common/types';
1313
import {isChrome, isWebKit} from 'vs/base/browser/browser';
1414
import {IKeyboardEvent, StandardKeyboardEvent} from 'vs/base/browser/keyboardEvent';
1515
import {IMouseEvent, StandardMouseEvent} from 'vs/base/browser/mouseEvent';
16+
import {CharCode} from 'vs/base/common/charCode';
1617

1718
export function clearNode(node: HTMLElement) {
1819
while (node.firstChild) {
@@ -55,7 +56,6 @@ export function isInDOM(node: Node): boolean {
5556
return false;
5657
}
5758

58-
const _blank = ' '.charCodeAt(0);
5959
let lastStart: number, lastEnd: number;
6060

6161
function _findClassName(node: HTMLElement, className: string): void {
@@ -95,14 +95,14 @@ function _findClassName(node: HTMLElement, className: string): void {
9595
idxEnd = idx + classLen;
9696

9797
// a class that is followed by another class
98-
if ((idx === 0 || classes.charCodeAt(idx - 1) === _blank) && classes.charCodeAt(idxEnd) === _blank) {
98+
if ((idx === 0 || classes.charCodeAt(idx - 1) === CharCode.Space) && classes.charCodeAt(idxEnd) === CharCode.Space) {
9999
lastStart = idx;
100100
lastEnd = idxEnd + 1;
101101
return;
102102
}
103103

104104
// last class
105-
if (idx > 0 && classes.charCodeAt(idx - 1) === _blank && idxEnd === classesLen) {
105+
if (idx > 0 && classes.charCodeAt(idx - 1) === CharCode.Space && idxEnd === classesLen) {
106106
lastStart = idx - 1;
107107
lastEnd = idxEnd;
108108
return;

src/vs/base/common/charCode.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
'use strict';
6+
7+
/**
8+
* An inlined enum containing useful character codes (to be used with String.charCodeAt).
9+
* Please leave the const keyword such that it gets inlined when compiled to JavaScript!
10+
*/
11+
export const enum CharCode {
12+
13+
Tab = 9,
14+
LineFeed = 10,
15+
CarriageReturn = 13,
16+
Space = 32,
17+
18+
/**
19+
* The `$` character.
20+
*/
21+
Dollar = 36,
22+
23+
/**
24+
* The `/` character.
25+
*/
26+
Slash = 47,
27+
28+
Digit0 = 48,
29+
Digit1 = 49,
30+
Digit9 = 57,
31+
32+
/**
33+
* The `:` character.
34+
*/
35+
Colon = 58,
36+
37+
A = 65,
38+
Z = 90,
39+
40+
/**
41+
* The `\` character.
42+
*/
43+
Backslash = 92,
44+
45+
/**
46+
* The ``(`)`` character.
47+
*/
48+
BackTick = 96,
49+
50+
a = 97,
51+
n = 110,
52+
t = 116,
53+
z = 122,
54+
55+
56+
}

src/vs/base/common/filters.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import strings = require('vs/base/common/strings');
88
import {BoundedLinkedMap} from 'vs/base/common/map';
9+
import {CharCode} from 'vs/base/common/charCode';
910

1011
export interface IFilter {
1112
// Returns null if word doesn't match.
@@ -114,19 +115,24 @@ function _matchesSubString(word: string, wordToMatchAgainst: string, i: number,
114115
// CamelCase
115116

116117
function isLower(code: number): boolean {
117-
return 97 <= code && code <= 122;
118+
return CharCode.a <= code && code <= CharCode.z;
118119
}
119120

120121
function isUpper(code: number): boolean {
121-
return 65 <= code && code <= 90;
122+
return CharCode.A <= code && code <= CharCode.Z;
122123
}
123124

124125
function isNumber(code: number): boolean {
125-
return 48 <= code && code <= 57;
126+
return CharCode.Digit0 <= code && code <= CharCode.Digit9;
126127
}
127128

128129
function isWhitespace(code: number): boolean {
129-
return [32, 9, 10, 13].indexOf(code) > -1;
130+
return (
131+
code === CharCode.Space
132+
|| code === CharCode.Tab
133+
|| code === CharCode.LineFeed
134+
|| code === CharCode.CarriageReturn
135+
);
130136
}
131137

132138
function isAlphanumeric(code: number): boolean {

src/vs/base/common/glob.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import strings = require('vs/base/common/strings');
88
import paths = require('vs/base/common/paths');
99
import {BoundedLinkedMap} from 'vs/base/common/map';
10+
import {CharCode} from 'vs/base/common/charCode';
1011

1112
export interface IExpression {
1213
[pattern: string]: boolean | SiblingClause | any;
@@ -467,9 +468,6 @@ function parseExpressionPattern(pattern: string, value: any): (ParsedStringPatte
467468
return parsedPattern;
468469
}
469470

470-
const SLASH = '/'.charCodeAt(0);
471-
const BACKSLASH = '\\'.charCodeAt(0);
472-
473471
function aggregateBasenameMatches(parsedPatterns: (ParsedStringPattern | ParsedExpressionPattern)[], result?: string): (ParsedStringPattern | ParsedExpressionPattern)[] {
474472
const basenamePatterns = parsedPatterns.filter(parsedPattern => !!(<ParsedStringPattern>parsedPattern).basenames);
475473
if (basenamePatterns.length < 2) {
@@ -494,7 +492,7 @@ function aggregateBasenameMatches(parsedPatterns: (ParsedStringPattern | ParsedE
494492
let i: number;
495493
for (i = path.length; i > 0; i--) {
496494
const ch = path.charCodeAt(i - 1);
497-
if (ch === SLASH || ch === BACKSLASH) {
495+
if (ch === CharCode.Slash || ch === CharCode.Backslash) {
498496
break;
499497
}
500498
}

src/vs/base/common/json.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ function isDigit(ch: number): boolean {
443443
return ch >= CharacterCodes._0 && ch <= CharacterCodes._9;
444444
}
445445

446-
enum CharacterCodes {
446+
const enum CharacterCodes {
447447
nullCharacter = 0,
448448
maxAsciiCharacter = 0x7F,
449449

src/vs/base/common/paths.ts

Lines changed: 20 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
'use strict';
66

77
import {isLinux, isWindows} from 'vs/base/common/platform';
8+
import {CharCode} from 'vs/base/common/charCode';
89

910
/**
1011
* The forward slash path separator.
@@ -113,7 +114,7 @@ export function normalize(path: string, toOSPath?: boolean): string {
113114
for (let end = root.length; end <= len; end++) {
114115

115116
// either at the end or at a path-separator character
116-
if (end === len || path.charCodeAt(end) === _slash || path.charCodeAt(end) === _backslash) {
117+
if (end === len || path.charCodeAt(end) === CharCode.Slash || path.charCodeAt(end) === CharCode.Backslash) {
117118

118119
if (streql(path, start, end, '..')) {
119120
// skip current and remove parent (if there is already something)
@@ -160,28 +161,28 @@ export function getRoot(path: string, sep: string = '/'): string {
160161

161162
let len = path.length;
162163
let code = path.charCodeAt(0);
163-
if (code === _slash || code === _backslash) {
164+
if (code === CharCode.Slash || code === CharCode.Backslash) {
164165

165166
code = path.charCodeAt(1);
166-
if (code === _slash || code === _backslash) {
167+
if (code === CharCode.Slash || code === CharCode.Backslash) {
167168
// UNC candidate \\localhost\shares\ddd
168169
// ^^^^^^^^^^^^^^^^^^^
169170
code = path.charCodeAt(2);
170-
if (code !== _slash && code !== _backslash) {
171+
if (code !== CharCode.Slash && code !== CharCode.Backslash) {
171172
let pos = 3;
172173
let start = pos;
173174
for (; pos < len; pos++) {
174175
code = path.charCodeAt(pos);
175-
if (code === _slash || code === _backslash) {
176+
if (code === CharCode.Slash || code === CharCode.Backslash) {
176177
break;
177178
}
178179
}
179180
code = path.charCodeAt(pos + 1);
180-
if (start !== pos && code !== _slash && code !== _backslash) {
181+
if (start !== pos && code !== CharCode.Slash && code !== CharCode.Backslash) {
181182
pos += 1;
182183
for (; pos < len; pos++) {
183184
code = path.charCodeAt(pos);
184-
if (code === _slash || code === _backslash) {
185+
if (code === CharCode.Slash || code === CharCode.Backslash) {
185186
return path.slice(0, pos + 1) // consume this separator
186187
.replace(/[\\/]/g, sep);
187188
}
@@ -194,12 +195,12 @@ export function getRoot(path: string, sep: string = '/'): string {
194195
// ^
195196
return sep;
196197

197-
} else if ((code >= _A && code <= _Z) || (code >= _a && code <= _z)) {
198+
} else if ((code >= CharCode.A && code <= CharCode.Z) || (code >= CharCode.a && code <= CharCode.z)) {
198199
// check for windows drive letter c:\ or c:
199200

200-
if (path.charCodeAt(1) === _colon) {
201+
if (path.charCodeAt(1) === CharCode.Colon) {
201202
code = path.charCodeAt(2);
202-
if (code === _slash || code === _backslash) {
203+
if (code === CharCode.Slash || code === CharCode.Backslash) {
203204
// C:\fff
204205
// ^^^
205206
return path.slice(0, 2) + sep;
@@ -219,7 +220,7 @@ export function getRoot(path: string, sep: string = '/'): string {
219220
pos += 3; // 3 -> "://".length
220221
for (; pos < len; pos++) {
221222
code = path.charCodeAt(pos);
222-
if (code === _slash || code === _backslash) {
223+
if (code === CharCode.Slash || code === CharCode.Backslash) {
223224
return path.slice(0, pos + 1); // consume this separator
224225
}
225226
}
@@ -240,9 +241,9 @@ export const join: (...parts: string[]) => string = function () {
240241
// add the separater between two parts unless
241242
// there already is one
242243
let last = value.charCodeAt(value.length - 1);
243-
if (last !== _slash && last !== _backslash) {
244+
if (last !== CharCode.Slash && last !== CharCode.Backslash) {
244245
let next = part.charCodeAt(0);
245-
if (next !== _slash && next !== _backslash) {
246+
if (next !== CharCode.Slash && next !== CharCode.Backslash) {
246247

247248
value += sep;
248249
}
@@ -274,26 +275,26 @@ export function isUNC(path: string): boolean {
274275
}
275276

276277
let code = path.charCodeAt(0);
277-
if (code !== _backslash) {
278+
if (code !== CharCode.Backslash) {
278279
return false;
279280
}
280281
code = path.charCodeAt(1);
281-
if (code !== _backslash) {
282+
if (code !== CharCode.Backslash) {
282283
return false;
283284
}
284285
let pos = 2;
285286
let start = pos;
286287
for (; pos < path.length; pos++) {
287288
code = path.charCodeAt(pos);
288-
if (code === _backslash) {
289+
if (code === CharCode.Backslash) {
289290
break;
290291
}
291292
}
292293
if (start === pos) {
293294
return false;
294295
}
295296
code = path.charCodeAt(pos + 1);
296-
if (isNaN(code) || code === _backslash) {
297+
if (isNaN(code) || code === CharCode.Backslash) {
297298
return false;
298299
}
299300
return true;
@@ -307,15 +308,6 @@ export function makePosixAbsolute(path: string): string {
307308
return isPosixAbsolute(normalize(path)) ? path : sep + path;
308309
}
309310

310-
311-
const _slash = '/'.charCodeAt(0);
312-
const _backslash = '\\'.charCodeAt(0);
313-
const _colon = ':'.charCodeAt(0);
314-
const _a = 'a'.charCodeAt(0);
315-
const _A = 'A'.charCodeAt(0);
316-
const _z = 'z'.charCodeAt(0);
317-
const _Z = 'Z'.charCodeAt(0);
318-
319311
export function isEqualOrParent(path: string, candidate: string): boolean {
320312

321313
if (path === candidate) {
@@ -327,7 +319,7 @@ export function isEqualOrParent(path: string, candidate: string): boolean {
327319

328320
let candidateLen = candidate.length;
329321
let lastCandidateChar = candidate.charCodeAt(candidateLen - 1);
330-
if (lastCandidateChar === _slash) {
322+
if (lastCandidateChar === CharCode.Slash) {
331323
candidate = candidate.substring(0, candidateLen - 1);
332324
candidateLen -= 1;
333325
}
@@ -351,7 +343,7 @@ export function isEqualOrParent(path: string, candidate: string): boolean {
351343
}
352344

353345
let char = path.charCodeAt(candidateLen);
354-
return char === _slash;
346+
return char === CharCode.Slash;
355347
}
356348

357349
// Reference: https://en.wikipedia.org/wiki/Filename

src/vs/base/common/strings.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
'use strict';
66

77
import {BoundedLinkedMap} from 'vs/base/common/map';
8+
import {CharCode} from 'vs/base/common/charCode';
89

910
/**
1011
* The empty string.
@@ -261,7 +262,8 @@ export function normalizeNFC(str: string): string {
261262
*/
262263
export function firstNonWhitespaceIndex(str: string): number {
263264
for (let i = 0, len = str.length; i < len; i++) {
264-
if (str.charAt(i) !== ' ' && str.charAt(i) !== '\t') {
265+
let chCode = str.charCodeAt(i);
266+
if (chCode !== CharCode.Space && chCode !== CharCode.Tab) {
265267
return i;
266268
}
267269
}
@@ -274,7 +276,8 @@ export function firstNonWhitespaceIndex(str: string): number {
274276
*/
275277
export function getLeadingWhitespace(str: string): string {
276278
for (let i = 0, len = str.length; i < len; i++) {
277-
if (str.charAt(i) !== ' ' && str.charAt(i) !== '\t') {
279+
let chCode = str.charCodeAt(i);
280+
if (chCode !== CharCode.Space && chCode !== CharCode.Tab) {
278281
return str.substring(0, i);
279282
}
280283
}
@@ -287,7 +290,8 @@ export function getLeadingWhitespace(str: string): string {
287290
*/
288291
export function lastNonWhitespaceIndex(str: string, startIndex: number = str.length - 1): number {
289292
for (let i = startIndex; i >= 0; i--) {
290-
if (str.charAt(i) !== ' ' && str.charAt(i) !== '\t') {
293+
let chCode = str.charCodeAt(i);
294+
if (chCode !== CharCode.Space && chCode !== CharCode.Tab) {
291295
return i;
292296
}
293297
}
@@ -305,7 +309,7 @@ export function compare(a: string, b: string): number {
305309
}
306310

307311
function isAsciiChar(code: number): boolean {
308-
return (code >= 97 && code <= 122) || (code >= 65 && code <= 90);
312+
return (code >= CharCode.a && code <= CharCode.z) || (code >= CharCode.A && code <= CharCode.Z);
309313
}
310314

311315
export function equalsIgnoreCase(a: string, b: string): boolean {

src/vs/base/node/decoder.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
'use strict';
77

88
import sd = require('string_decoder');
9+
import {CharCode} from 'vs/base/common/charCode';
910

1011
/**
1112
* Convenient way to iterate over output line by line. This helper accommodates for the fact that
@@ -35,16 +36,16 @@ export class LineDecoder {
3536
}
3637
let start = 0;
3738
let ch: number;
38-
while (start < value.length && ((ch = value.charCodeAt(start)) === 13 || ch === 10)) {
39+
while (start < value.length && ((ch = value.charCodeAt(start)) === CharCode.CarriageReturn || ch === CharCode.LineFeed)) {
3940
start++;
4041
}
4142
let idx = start;
4243
while (idx < value.length) {
4344
ch = value.charCodeAt(idx);
44-
if (ch === 13 || ch === 10) {
45+
if (ch === CharCode.CarriageReturn || ch === CharCode.LineFeed) {
4546
result.push(value.substring(start, idx));
4647
idx++;
47-
while (idx < value.length && ((ch = value.charCodeAt(idx)) === 13 || ch === 10)) {
48+
while (idx < value.length && ((ch = value.charCodeAt(idx)) === CharCode.CarriageReturn || ch === CharCode.LineFeed)) {
4849
idx++;
4950
}
5051
start = idx;

0 commit comments

Comments
 (0)