From 6b4f2deabf0a00f20f166c793194462492972d3e Mon Sep 17 00:00:00 2001 From: Adnan Chowdhury Date: Fri, 10 Nov 2017 22:33:33 -0800 Subject: [PATCH 1/4] Implement fallback hashing algorithm when crypto module is not available --- src/compiler/sys.ts | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index 529ece36fa62f..0e2c129b5e432 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -129,7 +129,11 @@ namespace ts { const _fs = require("fs"); const _path = require("path"); const _os = require("os"); - const _crypto = require("crypto"); + // crypto can be absent on reduced node installations + let _crypto: any; + try { + _crypto = require("crypto"); + } catch { } const useNonPollingWatchers = process.env.TSC_NONPOLLING_WATCHER; @@ -494,9 +498,17 @@ namespace ts { } }, createHash(data) { - const hash = _crypto.createHash("md5"); - hash.update(data); - return hash.digest("hex"); + let hash: any; + if (_crypto) { + hash = _crypto.createHash("md5"); + hash.update(data); + hash.digest("hex"); + } else { + // djb2 hashing algorithm: http://www.cse.yorku.ca/~oz/hash.html + const chars = data.split('').map(str => str.charCodeAt(0)); + hash = `${chars.reduce((prev, curr) => ((prev << 5) + prev) + curr, 5381)}`; + } + return hash; }, getMemoryUsage() { if (global.gc) { From fc9bc292985c1efd578a31a60575cca119a6753b Mon Sep 17 00:00:00 2001 From: Adnan Chowdhury Date: Sat, 11 Nov 2017 08:34:05 -0800 Subject: [PATCH 2/4] Fix lint errors --- src/compiler/sys.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index 0e2c129b5e432..be8056def6504 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -133,7 +133,10 @@ namespace ts { let _crypto: any; try { _crypto = require("crypto"); - } catch { } + } + catch { + _crypto = undefined; + } const useNonPollingWatchers = process.env.TSC_NONPOLLING_WATCHER; @@ -503,9 +506,10 @@ namespace ts { hash = _crypto.createHash("md5"); hash.update(data); hash.digest("hex"); - } else { + } + else { // djb2 hashing algorithm: http://www.cse.yorku.ca/~oz/hash.html - const chars = data.split('').map(str => str.charCodeAt(0)); + const chars = data.split("").map(str => str.charCodeAt(0)); hash = `${chars.reduce((prev, curr) => ((prev << 5) + prev) + curr, 5381)}`; } return hash; From f36c39a6c2649f61a5095c358f2470ecdf85a4ac Mon Sep 17 00:00:00 2001 From: Adnan Chowdhury Date: Mon, 13 Nov 2017 13:41:00 -0800 Subject: [PATCH 3/4] Expose method internally and use in watch.ts --- src/compiler/sys.ts | 14 +++++++++++--- src/compiler/watch.ts | 2 +- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index be8056def6504..9d5c05dc4fe9d 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -16,6 +16,16 @@ namespace ts { } } + /** + * djb2 hashing algorithm + * http://www.cse.yorku.ca/~oz/hash.html + */ + /* @internal */ + export function generateDjb2Hash(data: string): string { + const chars = data.split("").map(str => str.charCodeAt(0)); + return `${chars.reduce((prev, curr) => ((prev << 5) + prev) + curr, 5381)}`; + } + export enum FileWatcherEventKind { Created, Changed, @@ -508,9 +518,7 @@ namespace ts { hash.digest("hex"); } else { - // djb2 hashing algorithm: http://www.cse.yorku.ca/~oz/hash.html - const chars = data.split("").map(str => str.charCodeAt(0)); - hash = `${chars.reduce((prev, curr) => ((prev << 5) + prev) + curr, 5381)}`; + hash = generateDjb2Hash(data); } return hash; }, diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index 8e49bb71a1592..c6106d9728899 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -642,7 +642,7 @@ namespace ts { } function computeHash(data: string) { - return system.createHash ? system.createHash(data) : data; + return system.createHash ? system.createHash(data) : generateDjb2Hash(data); } } } From f83a64734afbabe47399324b55ce6c4fd8717525 Mon Sep 17 00:00:00 2001 From: Adnan Chowdhury Date: Wed, 10 Jan 2018 21:04:27 -0800 Subject: [PATCH 4/4] Simplify syntax; Remove fallback from watch.ts --- src/compiler/sys.ts | 38 ++++++++++++++++---------------------- src/compiler/watch.ts | 2 +- 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index 9d5c05dc4fe9d..01cb909e825da 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -16,16 +16,6 @@ namespace ts { } } - /** - * djb2 hashing algorithm - * http://www.cse.yorku.ca/~oz/hash.html - */ - /* @internal */ - export function generateDjb2Hash(data: string): string { - const chars = data.split("").map(str => str.charCodeAt(0)); - return `${chars.reduce((prev, curr) => ((prev << 5) + prev) + curr, 5381)}`; - } - export enum FileWatcherEventKind { Created, Changed, @@ -150,6 +140,21 @@ namespace ts { const useNonPollingWatchers = process.env.TSC_NONPOLLING_WATCHER; + /** + * djb2 hashing algorithm + * http://www.cse.yorku.ca/~oz/hash.html + */ + function generateDjb2Hash(data: string): string { + const chars = data.split("").map(str => str.charCodeAt(0)); + return `${chars.reduce((prev, curr) => ((prev << 5) + prev) + curr, 5381)}`; + } + + function createMD5HashUsingNativeCrypto(data: string) { + const hash = _crypto.createHash("md5"); + hash.update(data); + return hash.digest("hex"); + } + function createWatchedFileSet() { const dirWatchers = createMap(); // One file can have multiple watchers @@ -510,18 +515,7 @@ namespace ts { return undefined; } }, - createHash(data) { - let hash: any; - if (_crypto) { - hash = _crypto.createHash("md5"); - hash.update(data); - hash.digest("hex"); - } - else { - hash = generateDjb2Hash(data); - } - return hash; - }, + createHash: _crypto ? createMD5HashUsingNativeCrypto : generateDjb2Hash, getMemoryUsage() { if (global.gc) { global.gc(); diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index c6106d9728899..8e49bb71a1592 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -642,7 +642,7 @@ namespace ts { } function computeHash(data: string) { - return system.createHash ? system.createHash(data) : generateDjb2Hash(data); + return system.createHash ? system.createHash(data) : data; } } }